Compare commits

...

3 Commits

Author SHA1 Message Date
a52dc89f9f diagdummy srpr2 wait for device lock 2025-11-24 22:29:59 +01:00
cc2b96f37a qemu_pci_serial device locking/sync 2025-11-24 22:29:32 +01:00
80a29d8ff6 Handle continous jobs via new subsystem - CJob 2025-11-24 21:53:51 +01:00
11 changed files with 219 additions and 64 deletions

View File

@ -71,6 +71,7 @@ SRCFILES += $(call GRABSRC, \
pci \ pci \
pci/ata \ pci/ata \
pci/qemu_pci_serial \ pci/qemu_pci_serial \
cjob \
) )
CFILES := $(call GET_CFILES, $(SRCFILES)) CFILES := $(call GET_CFILES, $(SRCFILES))

36
kernel/cjob/cjob.c Normal file
View File

@ -0,0 +1,36 @@
#include <stdint.h>
#include <stddef.h>
#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);
}

29
kernel/cjob/cjob.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef CJOB_CJOB_H_
#define CJOB_CJOB_H_
#include <stdint.h>
#include <stddef.h>
#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_

View File

@ -7,15 +7,47 @@
#include "std/string.h" #include "std/string.h"
#include "dlmalloc/malloc.h" #include "dlmalloc/malloc.h"
#include "util/util.h" #include "util/util.h"
#include "cjob/cjob.h"
#include "hshtb.h" #include "hshtb.h"
#include "errors.h" #include "errors.h"
#include "kprintf.h" #include "kprintf.h"
IpcMBuses IPC_MBUSES; 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) { void ipc_mbusinit(void) {
memset(&IPC_MBUSES, 0, sizeof(IPC_MBUSES)); memset(&IPC_MBUSES, 0, sizeof(IPC_MBUSES));
spinlock_init(&IPC_MBUSES.spinlock); spinlock_init(&IPC_MBUSES.spinlock);
cjob_register(&ipc_mbus_gc_cjob, NULL);
} }
IpcMBus *ipc_mbusmake(const char *name, size_t objsize, size_t objmax) { 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; 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);
}
}

View File

@ -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_mbusconsume(const char *name, uint8_t *const buffer, uint64_t pid);
int32_t ipc_mbusattch(const char *name, uint64_t pid); int32_t ipc_mbusattch(const char *name, uint64_t pid);
int32_t ipc_mbusdttch(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_ #endif // IPC_MBUS_MBUS_H_

View File

@ -19,6 +19,7 @@
#include "cpu/gdt.h" #include "cpu/gdt.h"
#include "ipc/mbus/mbus.h" #include "ipc/mbus/mbus.h"
#include "pci/pci.h" #include "pci/pci.h"
#include "cjob/cjob.h"
void log_bootinfo(void) { void log_bootinfo(void) {
char buf[100]; char buf[100];
@ -50,6 +51,7 @@ void kmain(void) {
vmm_init(); vmm_init();
intr_init(); intr_init();
randcrypto_init(); randcrypto_init();
cjob_init();
ipc_mbusinit(); ipc_mbusinit();
dev_init(); dev_init();
storedev_init(); storedev_init();

View File

@ -6,6 +6,8 @@
#include "sysdefs/dev.h" #include "sysdefs/dev.h"
#include "util/util.h" #include "util/util.h"
#include "dev/dev.h" #include "dev/dev.h"
#include "cjob/cjob.h"
#include "proc/proc.h"
#include "errors.h" #include "errors.h"
#include "hshtb.h" #include "hshtb.h"
#include "kprintf.h" #include "kprintf.h"
@ -53,6 +55,11 @@ int32_t qemu_pci_serial_dev_sendb(struct Dev *dev, uint8_t *buffer, size_t len,
(void)len; (void)pid; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra; QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
_serial_sendb(qpsd->iobase, buffer[0]); _serial_sendb(qpsd->iobase, buffer[0]);
return E_OK; return E_OK;
@ -63,6 +70,10 @@ int32_t qemu_pci_serial_dev_sendready(struct Dev *dev, uint8_t *buffer, size_t l
QemuPciSerialDev *qpsd = dev->extra; QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
return _serial_sendready(qpsd->iobase); return _serial_sendready(qpsd->iobase);
} }
@ -71,17 +82,76 @@ int32_t qemu_pci_serial_dev_recvb(struct Dev *dev, uint8_t *buffer, size_t len,
QemuPciSerialDev *qpsd = dev->extra; QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
return _serial_recvb(qpsd->iobase); return _serial_recvb(qpsd->iobase);
} }
int32_t qemu_pci_serial_dev_recvready(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { int32_t qemu_pci_serial_dev_recvready(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) {
(void)dev; (void)buffer; (void)len; (void)pid; (void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra; QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate != -1 && qpsd->lockstate != (int)pid) {
return E_DEVLOCKED;
}
return _serial_recvready(qpsd->iobase); return _serial_recvready(qpsd->iobase);
} }
int32_t qemu_pci_serial_dev_lock(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) {
(void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate == (int)pid) {
return E_OK;
}
if (qpsd->lockstate == -1) {
qpsd->lockstate = (int)pid;
return E_OK;
}
return E_DEVLOCKED;
}
int32_t qemu_pci_serial_dev_unlock(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) {
(void)buffer; (void)len; (void)pid;
QemuPciSerialDev *qpsd = dev->extra;
if (qpsd->lockstate == (int)pid) {
qpsd->lockstate = -1;
return E_OK;
}
return E_DEVNOTYOURLOCK;
}
void pci_qemu_pci_serial_gc_cjob(void *arg) {
Dev *dev = arg;
QemuPciSerialDev *qpsd;
spinlock_acquire(&dev->spinlock);
qpsd = dev->extra;
uint64_t pid = qpsd->lockstate;
spinlock_release(&dev->spinlock);
Proc *proc = NULL;
spinlock_acquire(&PROCS.spinlock);
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
spinlock_acquire(&dev->spinlock);
qpsd = dev->extra;
qpsd->lockstate = -1;
spinlock_release(&dev->spinlock);
}
}
void pci_qemu_pci_serial_init(void) { void pci_qemu_pci_serial_init(void) {
PciDev dev = pci_getdev(0x1B36, 0x0002, -1); PciDev dev = pci_getdev(0x1B36, 0x0002, -1);
if (!dev.bits) { if (!dev.bits) {
@ -97,6 +167,7 @@ void pci_qemu_pci_serial_init(void) {
QEMU_PCI_SERIAL_DEV._magic = QEMU_PCI_SERIAL_MAGIC; QEMU_PCI_SERIAL_DEV._magic = QEMU_PCI_SERIAL_MAGIC;
QEMU_PCI_SERIAL_DEV.iobase = iobase; QEMU_PCI_SERIAL_DEV.iobase = iobase;
QEMU_PCI_SERIAL_DEV.lockstate = -1;
Dev *serialdev = NULL; Dev *serialdev = NULL;
HSHTB_ALLOC(DEVTABLE.devs, ident, "serialdev", serialdev); HSHTB_ALLOC(DEVTABLE.devs, ident, "serialdev", serialdev);
@ -104,8 +175,13 @@ void pci_qemu_pci_serial_init(void) {
serialdev->fns[1] = &qemu_pci_serial_dev_sendready; serialdev->fns[1] = &qemu_pci_serial_dev_sendready;
serialdev->fns[2] = &qemu_pci_serial_dev_recvb; serialdev->fns[2] = &qemu_pci_serial_dev_recvb;
serialdev->fns[3] = &qemu_pci_serial_dev_recvready; serialdev->fns[3] = &qemu_pci_serial_dev_recvready;
serialdev->fns[4] = &qemu_pci_serial_dev_lock;
serialdev->fns[5] = &qemu_pci_serial_dev_unlock;
spinlock_init(&serialdev->spinlock); spinlock_init(&serialdev->spinlock);
serialdev->extra = &QEMU_PCI_SERIAL_DEV; serialdev->extra = &QEMU_PCI_SERIAL_DEV;
cjob_register(&pci_qemu_pci_serial_gc_cjob, serialdev);
_serial_init(QEMU_PCI_SERIAL_DEV.iobase); _serial_init(QEMU_PCI_SERIAL_DEV.iobase);
} }

View File

@ -9,6 +9,7 @@
typedef struct { typedef struct {
uint32_t _magic; uint32_t _magic;
uint16_t iobase; uint16_t iobase;
int lockstate;
} QemuPciSerialDev; } QemuPciSerialDev;
void pci_qemu_pci_serial_init(void); void pci_qemu_pci_serial_init(void);

View File

@ -19,6 +19,7 @@
#include "intr/pic.h" #include "intr/pic.h"
#include "vmm/vmm.h" #include "vmm/vmm.h"
#include "proc/switch.h" #include "proc/switch.h"
#include "cjob/cjob.h"
#include "elf.h" #include "elf.h"
#include "errors.h" #include "errors.h"
#include "kprintf.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); spinlock_acquire(&PROCS.spinlock);
Proc *head, *tmp; Proc *head, *tmp;
LL_FOREACH_SAFE(PROCS.procs, head, tmp) { LL_FOREACH_SAFE(PROCS.procs, head, tmp) {
@ -222,41 +249,12 @@ void proc_reaper(void) {
spinlock_release(&PROCS.spinlock); 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) { void proc_init(void) {
spinlock_init(&PROCS.spinlock); spinlock_init(&PROCS.spinlock);
PROCS.procs = NULL; PROCS.procs = NULL;
cjob_register(&proc_gc_cjob, NULL);
Proc *init = proc_spawnuser("base", "/bin/init"); Proc *init = proc_spawnuser("base", "/bin/init");
PROCS.current = init; PROCS.current = init;
proc_register(init); proc_register(init);

View File

@ -17,6 +17,8 @@
#define E_SPAWNERROR -13 #define E_SPAWNERROR -13
#define E_NOTYET -14 #define E_NOTYET -14
#define E_MOUNTERR -15 #define E_MOUNTERR -15
#define E_DEVLOCKED -16
#define E_DEVNOTYOURLOCK -17
#if !defined(__ASSEMBLER__) #if !defined(__ASSEMBLER__)
@ -38,6 +40,8 @@ static const char *_ERROR_STRINGS[] = {
"Process spawn error", "Process spawn error",
"Data isn't ready yet", "Data isn't ready yet",
"File system mount error", "File system mount error",
"This device is locked",
"Device is hasn't been locked by this process",
}; };
#define ERRSTRING_INDEX(ioh) ((size_t)((ioh) < 0 ? (ioh) * (-1) : (ioh))) #define ERRSTRING_INDEX(ioh) ((size_t)((ioh) < 0 ? (ioh) * (-1) : (ioh)))

View File

@ -6,6 +6,8 @@
#define SENDREADY 1 #define SENDREADY 1
#define RECVB 2 #define RECVB 2
#define RECVREADY 3 #define RECVREADY 3
#define LOCK 4
#define UNLOCK 5
void diagdummy_srpr(void) { void diagdummy_srpr(void) {
char *str = "Hello world\n"; char *str = "Hello world\n";
@ -35,9 +37,13 @@ void diagdummy_srpr2(void) {
Dev_t serialdev; Dev_t serialdev;
dev_gethandle(&serialdev, "serialdev"); dev_gethandle(&serialdev, "serialdev");
while(dev_cmd(&serialdev, LOCK, NULL, 0) != E_OK);
for (;;) { for (;;) {
while (!dev_cmd(&serialdev, SENDREADY, NULL, 0)); while (!dev_cmd(&serialdev, SENDREADY, NULL, 0));
dev_cmd(&serialdev, SENDB, str, 1); dev_cmd(&serialdev, SENDB, str, 1);
schedsleep(500); schedsleep(500);
} }
dev_cmd(&serialdev, UNLOCK, NULL, 0);
} }