1
0
mirror of https://github.com/CPunch/Laika.git synced 2025-10-04 23:30:06 +00:00

TaskService refactoring

This commit is contained in:
2022-02-17 17:24:46 -06:00
parent 4e8febe916
commit 4e928464bd
5 changed files with 50 additions and 20 deletions

View File

@@ -1,6 +1,8 @@
#ifndef LAIKA_PACKET_H
#define LAIKA_PACKET_H
#include <inttypes.h>
#define LAIKA_MAGIC "LAI\x12"
#define LAIKA_MAGICLEN 4

View File

@@ -12,6 +12,7 @@ struct sLaika_task {
taskCallback callback;
void *uData;
long scheduled;
int delta;
};
struct sLaika_taskService {

50
lib/include/lvm.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef LAIKA_VM_H
#define LAIKA_VM_H
/* Laika VM:
This is an obfuscation technique where vital code can be executed in a
stack-based VM, inlined into the function. The VM instruction-set is fairly
simple, see the OP_* for avaliable opcodes and their expected arguments.
*/
#define LAIKA_VM_CODESIZE 512
#define LAIKA_VM_STACKSIZE 64
#define LAIKA_VM_CONSTSIZE 32
struct sLaika_vm_val {
union {
int i;
void *ptr;
};
};
struct sLaika_vm {
struct sLaika_vm_val stack[LAIKA_VM_STACKSIZE];
struct sLaika_vm_val constList[LAIKA_VM_CONSTSIZE];
uint8_t code[LAIKA_VM_CODESIZE];
int pc;
};
#define LAIKA_MAKE_VM_INT(i) (struct sLaika_vm_val)({.i = i})
#define LAIKA_MAKE_VM_PTR(ptr) (struct sLaika_vm_val)({.ptr = ptr})
#define LAIKA_MAKE_VM(consts, code) (struct sLaika_vm)({.constList = consts, .code = code, .pc = 0})
enum {
OP_EXIT,
OP_LOADCONST, /* stk_indx[uint8_t] = const_indx[uint8_t] */
OP_LOAD,
/* arithmetic */
OP_ADD, /* stk_indx[uint8_t] = stk_indx[uint8_t] + stk_indx[uint8_t] */
OP_SUB, /* stk_indx[uint8_t] = stk_indx[uint8_t] - stk_indx[uint8_t] */
OP_MUL, /* stk_indx[uint8_t] = stk_indx[uint8_t] * stk_indx[uint8_t] */
OP_DIV, /* stk_indx[uint8_t] = stk_indx[uint8_t] / stk_indx[uint8_t] */
OP_AND, /* stk_indx[uint8_t] = stk_indx[uint8_t] & stk_indx[uint8_t] */
OP_OR, /* stk_indx[uint8_t] = stk_indx[uint8_t] | stk_indx[uint8_t] */
OP_XOR, /* stk_indx[uint8_t] = stk_indx[uint8_t] ^ stk_indx[uint8_t] */
/* control-flow */
OP_TESTJMP, /* if stk_indx[uint8_t] != 0, pc = [uint8_t] */
};
#endif

View File

@@ -24,14 +24,12 @@ void laikaT_cleanTaskService(struct sLaika_taskService *service) {
}
}
struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta, taskCallback callback, void *uData) {
struct sLaika_task *curr = service->headTask, *last = NULL, *task = laikaM_malloc(sizeof(struct sLaika_task));
void scheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) {
struct sLaika_task *curr = service->headTask, *last = NULL;
task->callback = callback;
task->uData = uData;
task->scheduled = getTime() + delta;
task->scheduled = getTime() + task->delta;
/* search list for event for which we're scheduled before */
/* search list for task for which we're scheduled before */
while (curr != NULL && curr->scheduled < task->scheduled) {
last = curr;
curr = curr->next;
@@ -49,10 +47,10 @@ struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta
}
}
void laikaT_delTask(struct sLaika_taskService *service, struct sLaika_task *task) {
void unscheduleTask(struct sLaika_taskService *service, struct sLaika_task *task) {
struct sLaika_task *curr = service->headTask, *last = NULL;
if (task == service->headTask) {
if (task == service->headTask) { /* if task is root, set root to next */
service->headTask = task->next;
} else {
/* find in list */
@@ -63,8 +61,23 @@ void laikaT_delTask(struct sLaika_taskService *service, struct sLaika_task *task
/* unlink */
last->next = task->next;
task->next = NULL;
}
}
struct sLaika_task *laikaT_newTask(struct sLaika_taskService *service, int delta, taskCallback callback, void *uData) {
struct sLaika_task *task = laikaM_malloc(sizeof(struct sLaika_task));
task->callback = callback;
task->uData = uData;
task->delta = delta;
task->next = NULL;
scheduleTask(service, task);
}
void laikaT_delTask(struct sLaika_taskService *service, struct sLaika_task *task) {
unscheduleTask(service, task);
laikaM_free(task);
}
@@ -73,21 +86,25 @@ void laikaT_pollTasks(struct sLaika_taskService *service) {
clock_t currTick = getTime();
/* run each task, list is already sorted from closest scheduled task to furthest */
while (curr != NULL && curr->scheduled < currTick) { /* if scheduled time is greater than currTime, all events that follow are also not scheduled yet */
/* dispatch task callback */
curr->callback(service, curr, currTick, curr->uData);
/* walk to next task and free */
while (curr != NULL && curr->scheduled <= currTick) { /* if scheduled time is greater than currTime, all events that follow are also not scheduled yet */
/* walk to next task */
last = curr;
curr = curr->next;
laikaT_delTask(service, last);
/* reset task timer */
unscheduleTask(service, last);
scheduleTask(service, last);
/* dispatch task callback */
last->callback(service, last, currTick, last->uData);
}
}
/* will return the delta time in ms till the next event. -1 for no tasks scheduled */
int laikaT_timeTillTask(struct sLaika_taskService *service) {
if (service->headTask)
return service->headTask->scheduled - getTime();
else
if (service->headTask) {
int pause = service->headTask->scheduled - getTime();
return (pause > 0) ? pause : 0;
} else
return -1; /* no tasks scheduled */
}