mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
FEAT: SYSTEM_CMD_PARALLEL_RUN
This commit is contained in:
parent
beb2c724ff
commit
3169ec51cb
4 changed files with 72 additions and 1 deletions
|
|
@ -36,9 +36,44 @@ static inline void wrmsr(uint32_t msr, uint64_t value) {
|
|||
}
|
||||
|
||||
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) {
|
||||
// SMP-Safe System Calls using int 0x80 (configured in idt.c)
|
||||
}
|
||||
|
||||
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);
|
||||
get_os_info(info);
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ typedef struct {
|
|||
#define SYSTEM_CMD_SLEEP 46
|
||||
#define SYSTEM_CMD_SET_RESOLUTION 47
|
||||
#define SYSTEM_CMD_GET_OS_INFO 49
|
||||
#define SYSTEM_CMD_PARALLEL_RUN 50
|
||||
|
||||
void syscall_init(void);
|
||||
uint64_t syscall_handler_c(registers_t *regs);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
#define SYSTEM_CMD_TCP_RECV_NB 42
|
||||
#define SYSTEM_CMD_YIELD 43
|
||||
#define SYSTEM_CMD_GET_OS_INFO 49
|
||||
#define SYSTEM_CMD_PARALLEL_RUN 50
|
||||
|
||||
// Internal assembly entry into Ring 0
|
||||
extern uint64_t syscall0(uint64_t sys_num);
|
||||
|
|
|
|||
Loading…
Reference in a new issue