FEAT: SYSTEM_CMD_PARALLEL_RUN

This commit is contained in:
boreddevnl 2026-04-02 20:21:06 +02:00
parent beb2c724ff
commit 3169ec51cb
4 changed files with 72 additions and 1 deletions

View file

@ -36,9 +36,44 @@ static inline void wrmsr(uint32_t msr, uint64_t value) {
} }
extern void isr128_wrapper(void); extern void isr128_wrapper(void);
extern void* kmalloc(size_t size);
extern void kfree(void* ptr);
typedef struct {
void (*fn)(void *);
void *arg;
uint64_t pml4_phys;
volatile int *completion_counter;
} smp_user_task_t;
static void smp_user_wrapper(void *arg) {
smp_user_task_t *task = (smp_user_task_t *)arg;
if (!task) return;
uint64_t old_cr3;
asm volatile("mov %%cr3, %0" : "=r"(old_cr3));
// Switch to user address space if necessary
bool switch_cr3 = (task->pml4_phys != 0 && task->pml4_phys != old_cr3);
if (switch_cr3) {
asm volatile("mov %0, %%cr3" :: "r"(task->pml4_phys) : "memory");
}
if (task->fn) {
task->fn(task->arg);
}
if (switch_cr3) {
asm volatile("mov %0, %%cr3" :: "r"(old_cr3) : "memory");
}
if (task->completion_counter) {
__sync_fetch_and_add(task->completion_counter, -1);
}
}
void syscall_init(void) { void syscall_init(void) {
// SMP-Safe System Calls using int 0x80 (configured in idt.c)
} }
static void user_window_close(Window *win) { static void user_window_close(Window *win) {
@ -1280,6 +1315,36 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
extern void get_os_info(os_info_t *info); extern void get_os_info(os_info_t *info);
get_os_info(info); get_os_info(info);
return 0; return 0;
} else if (cmd == SYSTEM_CMD_PARALLEL_RUN) {
void (*user_fn)(void*) = (void (*)(void*))arg2;
void **args = (void **)arg3;
int count = (int)arg4;
if (count <= 0) return 0;
if (count > 64) count = 64;
volatile int completion_counter = count;
uint64_t current_pml4 = proc->pml4_phys;
smp_user_task_t tasks[64];
for (int i = 0; i < count; i++) {
tasks[i].fn = user_fn;
tasks[i].arg = args[i];
tasks[i].pml4_phys = current_pml4;
tasks[i].completion_counter = &completion_counter;
extern void work_queue_submit(void (*fn)(void*), void *arg);
work_queue_submit(smp_user_wrapper, &tasks[i]);
}
extern bool work_queue_drain_one(void);
while (completion_counter > 0) {
if (!work_queue_drain_one()) {
asm volatile("pause");
}
}
return 0;
} }
return -1; return -1;
} }

View file

@ -58,6 +58,7 @@ typedef struct {
#define SYSTEM_CMD_SLEEP 46 #define SYSTEM_CMD_SLEEP 46
#define SYSTEM_CMD_SET_RESOLUTION 47 #define SYSTEM_CMD_SET_RESOLUTION 47
#define SYSTEM_CMD_GET_OS_INFO 49 #define SYSTEM_CMD_GET_OS_INFO 49
#define SYSTEM_CMD_PARALLEL_RUN 50
void syscall_init(void); void syscall_init(void);
uint64_t syscall_handler_c(registers_t *regs); uint64_t syscall_handler_c(registers_t *regs);

View file

@ -255,3 +255,7 @@ int sys_get_os_info(os_info_t *info) {
return (int)syscall5(SYS_SYSTEM, SYSTEM_CMD_GET_OS_INFO, (uint64_t)info, 0, 0, 0); return (int)syscall5(SYS_SYSTEM, SYSTEM_CMD_GET_OS_INFO, (uint64_t)info, 0, 0, 0);
} }
void sys_parallel_run(void (*fn)(void*), void **args, int count) {
syscall5(SYS_SYSTEM, SYSTEM_CMD_PARALLEL_RUN, (uint64_t)fn, (uint64_t)args, (uint64_t)count, 0);
}

View file

@ -76,6 +76,7 @@
#define SYSTEM_CMD_TCP_RECV_NB 42 #define SYSTEM_CMD_TCP_RECV_NB 42
#define SYSTEM_CMD_YIELD 43 #define SYSTEM_CMD_YIELD 43
#define SYSTEM_CMD_GET_OS_INFO 49 #define SYSTEM_CMD_GET_OS_INFO 49
#define SYSTEM_CMD_PARALLEL_RUN 50
// Internal assembly entry into Ring 0 // Internal assembly entry into Ring 0
extern uint64_t syscall0(uint64_t sys_num); extern uint64_t syscall0(uint64_t sys_num);