diff --git a/kernel/Makefile b/kernel/Makefile index a01c8de..743522f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -71,6 +71,7 @@ SRCFILES += $(call GRABSRC, \ pci \ pci/ata \ pci/qemu_pci_serial \ + cjob \ ) CFILES := $(call GET_CFILES, $(SRCFILES)) diff --git a/kernel/cjob/cjob.c b/kernel/cjob/cjob.c new file mode 100644 index 0000000..a846835 --- /dev/null +++ b/kernel/cjob/cjob.c @@ -0,0 +1,36 @@ +#include +#include +#include "spinlock/spinlock.h" +#include "cjob/cjob.h" +#include "dlmalloc/malloc.h" +#include "util/util.h" + +CJobs CJOBS; +static uint64_t cjobids = 0; + +void cjob_init(void) { + spinlock_init(&CJOBS.spinlock); + CJOBS.cjobs = NULL; +} + +int32_t cjob_register(CJobFn fn, void *arg) { + CJob *cjob = dlmalloc(sizeof(*cjob)); + cjob->fn = fn; + cjob->arg = arg; + int32_t id = cjob->id = cjobids++; + + spinlock_acquire(&CJOBS.spinlock); + LL_APPEND(CJOBS.cjobs, cjob); + spinlock_release(&CJOBS.spinlock); + + return id; +} + +void cjob_runjobs(void) { + CJob *cjob, *cjobtmp; + spinlock_acquire(&CJOBS.spinlock); + LL_FOREACH_SAFE(CJOBS.cjobs, cjob, cjobtmp) { + cjob->fn(cjob->arg); + } + spinlock_release(&CJOBS.spinlock); +} diff --git a/kernel/cjob/cjob.h b/kernel/cjob/cjob.h new file mode 100644 index 0000000..ddab20c --- /dev/null +++ b/kernel/cjob/cjob.h @@ -0,0 +1,29 @@ +#ifndef CJOB_CJOB_H_ +#define CJOB_CJOB_H_ + +#include +#include +#include "spinlock/spinlock.h" + +typedef void (*CJobFn)(void *arg); + +typedef struct CJob { + struct CJob *next; + CJobFn fn; + void *arg; + int32_t id; +} CJob; + +typedef struct { + SpinLock spinlock; + CJob *cjobs; +} CJobs; + +extern CJobs CJOBS; + +void cjob_init(void); + +int32_t cjob_register(CJobFn fn, void *arg); +void cjob_runjobs(void); + +#endif // CJOB_CJOB_H_ diff --git a/kernel/ipc/mbus/mbus.c b/kernel/ipc/mbus/mbus.c index 434366e..7b4311e 100644 --- a/kernel/ipc/mbus/mbus.c +++ b/kernel/ipc/mbus/mbus.c @@ -7,15 +7,47 @@ #include "std/string.h" #include "dlmalloc/malloc.h" #include "util/util.h" +#include "cjob/cjob.h" #include "hshtb.h" #include "errors.h" #include "kprintf.h" IpcMBuses IPC_MBUSES; +void ipc_mbus_gc_cjob(void *arg) { + for (size_t i = 0; i < LEN(IPC_MBUSES.mbuses); i++) { + spinlock_acquire(&IPC_MBUSES.spinlock); + IpcMBus *mbus = &IPC_MBUSES.mbuses[i]; + spinlock_release(&IPC_MBUSES.spinlock); + + spinlock_acquire(&mbus->spinlock); + if (mbus->_hshtbstate != HSHTB_TAKEN) { + spinlock_release(&mbus->spinlock); + continue; + } + + IpcMBusCons *cons, *constmp; + LL_FOREACH_SAFE(mbus->consumers, cons, constmp) { + spinlock_acquire(&PROCS.spinlock); + Proc *proc = NULL; + LL_FINDPROP(PROCS.procs, proc, pid, cons->pid); + spinlock_release(&PROCS.spinlock); + + if (proc == NULL) { + LL_REMOVE(mbus->consumers, cons); + dlfree(cons->rbuf.buffer); + dlfree(cons); + } + } + spinlock_release(&mbus->spinlock); + } +} + void ipc_mbusinit(void) { memset(&IPC_MBUSES, 0, sizeof(IPC_MBUSES)); spinlock_init(&IPC_MBUSES.spinlock); + + cjob_register(&ipc_mbus_gc_cjob, NULL); } IpcMBus *ipc_mbusmake(const char *name, size_t objsize, size_t objmax) { @@ -174,32 +206,3 @@ int32_t ipc_mbusdttch(const char *name, uint64_t pid) { return E_OK; } - -void ipc_mbustick(void) { - for (size_t i = 0; i < LEN(IPC_MBUSES.mbuses); i++) { - spinlock_acquire(&IPC_MBUSES.spinlock); - IpcMBus *mbus = &IPC_MBUSES.mbuses[i]; - spinlock_release(&IPC_MBUSES.spinlock); - - spinlock_acquire(&mbus->spinlock); - if (mbus->_hshtbstate != HSHTB_TAKEN) { - spinlock_release(&mbus->spinlock); - continue; - } - - IpcMBusCons *cons, *constmp; - LL_FOREACH_SAFE(mbus->consumers, cons, constmp) { - spinlock_acquire(&PROCS.spinlock); - Proc *proc = NULL; - LL_FINDPROP(PROCS.procs, proc, pid, cons->pid); - spinlock_release(&PROCS.spinlock); - - if (proc == NULL) { - LL_REMOVE(mbus->consumers, cons); - dlfree(cons->rbuf.buffer); - dlfree(cons); - } - } - spinlock_release(&mbus->spinlock); - } -} diff --git a/kernel/ipc/mbus/mbus.h b/kernel/ipc/mbus/mbus.h index bd517c1..91ecb41 100644 --- a/kernel/ipc/mbus/mbus.h +++ b/kernel/ipc/mbus/mbus.h @@ -34,6 +34,5 @@ int32_t ipc_mbuspublish(const char *name, const uint8_t *const buffer); int32_t ipc_mbusconsume(const char *name, uint8_t *const buffer, uint64_t pid); int32_t ipc_mbusattch(const char *name, uint64_t pid); int32_t ipc_mbusdttch(const char *name, uint64_t pid); -void ipc_mbustick(void); #endif // IPC_MBUS_MBUS_H_ diff --git a/kernel/kmain.c b/kernel/kmain.c index df7bac3..d7f82f0 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -19,6 +19,7 @@ #include "cpu/gdt.h" #include "ipc/mbus/mbus.h" #include "pci/pci.h" +#include "cjob/cjob.h" void log_bootinfo(void) { char buf[100]; @@ -50,6 +51,7 @@ void kmain(void) { vmm_init(); intr_init(); randcrypto_init(); + cjob_init(); ipc_mbusinit(); dev_init(); storedev_init(); diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 69d8b6b..1271722 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -19,6 +19,7 @@ #include "intr/pic.h" #include "vmm/vmm.h" #include "proc/switch.h" +#include "cjob/cjob.h" #include "elf.h" #include "errors.h" #include "kprintf.h" @@ -174,7 +175,33 @@ Proc *proc_nextready(void) { } } -void proc_reaper(void) { +void proc_sched(void *cpustate) { + intr_disable(); + + memcpy(&PROCS.current->platformdata.trapframe, cpustate, sizeof(IntrStackFrame)); + + PROCS.current = proc_nextready(); + + cjob_runjobs(); + + tss.rsp0 = (uint64_t)VIRT(PROCS.current->platformdata.kstack); + proc_switch(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3); +} + +void proc_kill(Proc *proc) { + spinlock_acquire(&PROCS.spinlock); + proc->state = PROC_ZOMBIE; + spinlock_release(&PROCS.spinlock); +} + +void proc_killself(void) { + spinlock_acquire(&PROCS.spinlock); + Proc *proc = PROCS.current; + spinlock_release(&PROCS.spinlock); + proc_kill(proc); +} + +void proc_gc_cjob(void *arg) { spinlock_acquire(&PROCS.spinlock); Proc *head, *tmp; LL_FOREACH_SAFE(PROCS.procs, head, tmp) { @@ -222,41 +249,12 @@ void proc_reaper(void) { spinlock_release(&PROCS.spinlock); } -void proc_tick(void) { - proc_reaper(); - ipc_mbustick(); -} - -void proc_sched(void *cpustate) { - intr_disable(); - - memcpy(&PROCS.current->platformdata.trapframe, cpustate, sizeof(IntrStackFrame)); - - PROCS.current = proc_nextready(); - - proc_tick(); - - tss.rsp0 = (uint64_t)VIRT(PROCS.current->platformdata.kstack); - proc_switch(&PROCS.current->platformdata.trapframe, (void *)PROCS.current->platformdata.cr3); -} - -void proc_kill(Proc *proc) { - spinlock_acquire(&PROCS.spinlock); - proc->state = PROC_ZOMBIE; - spinlock_release(&PROCS.spinlock); -} - -void proc_killself(void) { - spinlock_acquire(&PROCS.spinlock); - Proc *proc = PROCS.current; - spinlock_release(&PROCS.spinlock); - proc_kill(proc); -} - void proc_init(void) { spinlock_init(&PROCS.spinlock); PROCS.procs = NULL; + cjob_register(&proc_gc_cjob, NULL); + Proc *init = proc_spawnuser("base", "/bin/init"); PROCS.current = init; proc_register(init);