Redesign reschedule points, allow one operation to reschedule many cpus at once
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m12s

This commit is contained in:
2026-02-18 23:16:03 +01:00
parent ae0a6024da
commit f103bdd739
39 changed files with 376 additions and 223 deletions

View File

@@ -9,6 +9,7 @@ void app_main (void) {
char ch;
mail_receive (&ch, 1);
mail_send (e_pgid, &ch, 1);
test (ch);
/* mail_send (e_pgid, &ch, 1); */
}
}

View File

@@ -18,8 +18,8 @@ void app_main (void) {
mail_send (ce_pgid, (uint8_t*)&ch, 1);
char rcv;
mail_receive (&rcv, 1);
terminal_print (&rcv, 1);
/* char rcv; */
/* mail_receive (&rcv, 1); */
/* terminal_print (&rcv, 1); */
}
}

View File

@@ -16,10 +16,12 @@
#include <mm/liballoc.h>
#include <mm/pmm.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
#include <sys/debug.h>
#include <sys/mm.h>
#include <sys/smp.h>
#include <sys/spin.h>
#include <sys/spin_lock.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <uacpi/uacpi.h>
@@ -51,14 +53,9 @@ void bootmain (void) {
devices_init ();
vfs_init ();
bool reschedule = false;
struct device* ramdisk_device = device_find (RAMDISK_DEVICE);
struct device_op_ctx op_ctx = {
.proc = NULL,
.reschedule_cpu = NULL,
.reschedule = &reschedule,
};
int ret = vfs_create_mountpoint ("ramdisk", VFS_TARFS, ramdisk_device, &op_ctx);
struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT};
int ret = vfs_create_mountpoint ("ramdisk", VFS_TARFS, ramdisk_device, NULL, &rctx);
if (ret < 0) {
DEBUG ("could not mount ramdisk! (%d)\n", ret);

View File

@@ -26,9 +26,13 @@ static bool amd64_debug_serial_tx_empty (void) {
/* Write a single character to serial */
static void amd64_debug_serial_write (char x) {
spin_lock (&serial_lock);
while (!amd64_debug_serial_tx_empty ())
;
amd64_io_outb (PORT_COM1, (uint8_t)x);
spin_unlock (&serial_lock);
}
/*
@@ -50,14 +54,10 @@ void debugprintf (const char* fmt, ...) {
const char* p = buffer;
spin_lock (&serial_lock);
while (*p) {
amd64_debug_serial_write (*p);
p++;
}
spin_unlock (&serial_lock);
}
/* Initialize serial */

View File

@@ -8,6 +8,8 @@
#include <libk/std.h>
#include <libk/string.h>
#include <m/syscall_defs.h>
#include <mm/liballoc.h>
#include <proc/reschedule.h>
#include <sys/debug.h>
#include <sys/smp.h>
#include <sys/spin.h>
@@ -155,9 +157,34 @@ static void amd64_intr_exception (struct saved_regs* regs) {
regs->rbx);
if (regs->cs == (GDT_UCODE | 0x03)) {
struct cpu* reschedule_cpu;
if (proc_kill (thiscpu->proc_current, &reschedule_cpu) == PROC_NEED_RESCHEDULE)
cpu_request_sched (reschedule_cpu);
struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT};
proc_kill (thiscpu->proc_current, &rctx);
bool reschedule_thiscpu = false;
spin_lock (&rctx.lock);
struct list_node_link *node, *tmp;
list_foreach (rctx.entries, node, tmp) {
struct reschedule_entry* entry = list_entry (node, struct reschedule_entry, link);
struct cpu* cpu = entry->cpu;
if (cpu != thiscpu) {
cpu_request_sched (cpu);
} else {
reschedule_thiscpu = true;
}
list_remove (rctx.entries, &entry->link);
free (entry);
}
spin_unlock (&rctx.lock);
if (reschedule_thiscpu) {
proc_sched ();
}
} else {
spin ();
}
@@ -185,12 +212,35 @@ void amd64_intr_handler (void* stack_ptr) {
struct irq* irq = irq_find (regs->trap);
if (irq != NULL) {
struct cpu* reschedule_cpu = NULL;
bool reschedule = irq->func (&reschedule_cpu, irq->arg, stack_ptr);
if (irq == NULL)
return;
if (reschedule)
cpu_request_sched (reschedule_cpu);
struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT};
irq->func (irq->arg, stack_ptr, &rctx);
bool reschedule_thiscpu = false;
spin_lock (&rctx.lock);
struct list_node_link *node, *tmp;
list_foreach (rctx.entries, node, tmp) {
struct reschedule_entry* entry = list_entry (node, struct reschedule_entry, link);
struct cpu* cpu = entry->cpu;
if (cpu != thiscpu) {
cpu_request_sched (cpu);
} else {
reschedule_thiscpu = true;
}
list_remove (rctx.entries, &entry->link);
free (entry);
}
spin_unlock (&rctx.lock);
if (reschedule_thiscpu) {
proc_sched ();
}
}
}

View File

@@ -99,14 +99,14 @@ struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t ent
return proc;
}
void proc_cleanup (struct proc* proc) {
void proc_cleanup (struct proc* proc, struct reschedule_ctx* rctx) {
proc_sqs_cleanup (proc);
proc_mutexes_cleanup (proc);
proc_mutexes_cleanup (proc, rctx);
pmm_free (proc->pdata.kernel_stack, KSTACK_SIZE / PAGE_SIZE);
procgroup_unmap (proc->procgroup, proc->pdata.tls_vaddr, proc->procgroup->tls.tls_tmpl_pages);
procgroup_detach (proc->procgroup, proc);
procgroup_detach (proc->procgroup, proc, rctx);
/* clean the process */
free (proc);

View File

@@ -2,6 +2,7 @@
#include <amd64/msr.h>
#include <amd64/sched.h>
#include <libk/std.h>
#include <libk/string.h>
#include <proc/proc.h>
#include <sync/spin_lock.h>
#include <sys/mm.h>
@@ -14,8 +15,12 @@ void do_sched (struct proc* proc, spin_lock_t* cpu_lock) {
thiscpu->syscall_kernel_stack = proc->pdata.kernel_stack;
amd64_wrmsr (MSR_FS_BASE, proc->pdata.fs_base);
void* cr3 = (void*)proc->procgroup->pd.cr3_paddr;
struct saved_regs regs;
memcpy (&regs, &proc->pdata.regs, sizeof (regs));
spin_unlock (&proc->lock);
spin_unlock (cpu_lock);
amd64_do_sched ((void*)&proc->pdata.regs, (void*)proc->procgroup->pd.cr3_paddr);
amd64_do_sched ((void*)&regs, cr3);
}

View File

@@ -9,6 +9,7 @@
#include <limine/requests.h>
#include <mm/liballoc.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
#include <sys/sched.h>
@@ -88,8 +89,7 @@ static void amd64_smp_bootstrap (struct limine_mp_info* mp_info) {
atomic_fetch_sub (&cpu_counter, 1);
struct proc* spin_proc = proc_from_file (NULL, "ramdisk", "/spin");
struct cpu* spin_cpu = thiscpu;
proc_register (spin_proc, &spin_cpu);
proc_register (spin_proc, thiscpu, NULL);
spin_lock (&spin_proc->cpu->lock);
do_sched (spin_proc, &spin_proc->cpu->lock);

View File

@@ -3,10 +3,13 @@
#include <amd64/mm.h>
#include <amd64/msr-index.h>
#include <amd64/msr.h>
#include <libk/list.h>
#include <libk/string.h>
#include <m/status.h>
#include <m/syscall_defs.h>
#include <mm/liballoc.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
#include <sys/debug.h>
#include <sys/smp.h>
#include <syscall/syscall.h>
@@ -34,11 +37,10 @@ uintptr_t amd64_syscall_dispatch (void* stack_ptr) {
return -ST_SYSCALL_NOT_FOUND;
}
bool reschedule = false;
struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT};
struct cpu* reschedule_cpu = NULL;
uintptr_t r = func (caller, regs, &reschedule, &reschedule_cpu, regs->rdi, regs->rsi, regs->rdx,
regs->r10, regs->r8, regs->r9);
uintptr_t r =
func (caller, regs, &rctx, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9);
caller = proc_find_pid (caller_pid);
@@ -48,8 +50,30 @@ uintptr_t amd64_syscall_dispatch (void* stack_ptr) {
spin_unlock (&caller->lock);
}
if (reschedule)
cpu_request_sched (reschedule_cpu);
bool reschedule_thiscpu = false;
spin_lock (&rctx.lock);
struct list_node_link *node, *tmp;
list_foreach (rctx.entries, node, tmp) {
struct reschedule_entry* entry = list_entry (node, struct reschedule_entry, link);
struct cpu* cpu = entry->cpu;
if (cpu != thiscpu) {
cpu_request_sched (cpu);
} else {
reschedule_thiscpu = true;
}
list_remove (rctx.entries, &entry->link);
free (entry);
}
spin_unlock (&rctx.lock);
if (reschedule_thiscpu) {
proc_sched ();
}
return r;
}

View File

@@ -1,22 +1,18 @@
#ifndef _KERNEL_DEVICE_DEVICE_H
#define _KERNEL_DEVICE_DEVICE_H
#include <libk/list.h>
#include <libk/rbtree.h>
#include <libk/std.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
#include <sync/spin_lock.h>
#include <sys/smp.h>
struct device;
struct device_op_ctx {
struct proc* proc;
struct cpu** reschedule_cpu;
bool* reschedule;
};
typedef int (*device_op_func_t) (struct device* device, struct device_op_ctx* op_ctx, void* a1,
void* a2, void* a3, void* a4);
typedef int (*device_op_func_t) (struct device* device, struct proc*, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4);
typedef bool (*device_init_func_t) (struct device* device, void* arg);
typedef void (*device_fini_func_t) (struct device* device);

View File

@@ -9,6 +9,7 @@
#include <m/status.h>
#include <proc/capability.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
#include <proc/suspension_q.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
@@ -165,13 +166,13 @@ static int32_t ps2kb_keycode (void) {
return c;
}
static bool ps2kb_irq (struct cpu** reschedule_cpu, void* arg, void* regs) {
static void ps2kb_irq (void* arg, void* regs, struct reschedule_ctx* rctx) {
(void)arg, (void)regs;
int32_t keycode = ps2kb_keycode ();
if (keycode <= 0)
return PROC_NO_RESCHEDULE;
return;
spin_lock (&ps2kb_ringbuffer_lock);
spin_lock (&ps2kb_sq.lock);
@@ -187,20 +188,19 @@ static bool ps2kb_irq (struct cpu** reschedule_cpu, void* arg, void* regs) {
spin_unlock (&ps2kb_sq.lock);
spin_unlock (&ps2kb_ringbuffer_lock);
return proc_sq_resume (resumed_proc, sq_entry, reschedule_cpu);
proc_sq_resume (resumed_proc, sq_entry, rctx);
return;
}
spin_unlock (&ps2kb_sq.lock);
spin_unlock (&ps2kb_ringbuffer_lock);
return PROC_NO_RESCHEDULE;
}
int ps2kb_read_key (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4) {
int ps2kb_read_key (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4) {
(void)device, (void)a2, (void)a3, (void)a4;
if ((op_ctx->proc != NULL) && !(op_ctx->proc->procgroup->capabilities & PROC_CAP_KB))
if (!(proc->procgroup->capabilities & PROC_CAP_KB))
return -ST_PERMISSION_ERROR;
uint8_t* chbuf = (uint8_t*)a1;
@@ -224,8 +224,7 @@ int ps2kb_read_key (struct device* device, struct device_op_ctx* op_ctx, void* a
return -ST_PERMISSION_ERROR;
}
*op_ctx->reschedule =
proc_sq_suspend (op_ctx->proc, &ps2kb_sq, &ps2kb_ringbuffer_lock, op_ctx->reschedule_cpu);
proc_sq_suspend (proc, &ps2kb_sq, &ps2kb_ringbuffer_lock, rctx);
return ST_OK;
}

View File

@@ -1,14 +1,19 @@
#ifndef _KERNEL_DEVICE_PS2_KB_H
#define _KERNEL_DEVICE_PS2_KB_H
#include <libk/list.h>
#include <libk/std.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
struct device;
struct device_op_ctx;
int ps2kb_read_key (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4);
int ps2kb_read_key (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4);
bool ps2kb_init (struct device* device, void* arg);
void ps2kb_fini (struct device* device);
#endif // _KERNEL_DEVICE_PS2_KB_H

View File

@@ -43,9 +43,9 @@ void ramdrv_fini (struct device* device) {
free (ramdrv);
}
int ramdrv_get_device_type (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4) {
(void)device, (void)a2, (void)a3, (void)a4, (void)op_ctx;
int ramdrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) {
(void)device, (void)a2, (void)a3, (void)a4;
if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE;
@@ -57,9 +57,9 @@ int ramdrv_get_device_type (struct device* device, struct device_op_ctx* op_ctx,
return ST_OK;
}
int ramdrv_get_size (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4) {
(void)a2, (void)a3, (void)a4, (void)op_ctx;
int ramdrv_get_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) {
(void)a2, (void)a3, (void)a4;
if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE;
@@ -73,9 +73,9 @@ int ramdrv_get_size (struct device* device, struct device_op_ctx* op_ctx, void*
return ST_OK;
}
int ramdrv_get_sector_size (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4) {
(void)a2, (void)a3, (void)a4, (void)op_ctx;
int ramdrv_get_sector_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) {
(void)a2, (void)a3, (void)a4;
if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE;
@@ -89,9 +89,9 @@ int ramdrv_get_sector_size (struct device* device, struct device_op_ctx* op_ctx,
return ST_OK;
}
int ramdrv_read (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2, void* a3,
void* a4) {
(void)op_ctx, (void)a4;
int ramdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4) {
(void)a4;
if (a1 == NULL || a2 == NULL || a3 == NULL)
return -ST_BAD_ADDRESS_SPACE;

View File

@@ -1,7 +1,10 @@
#ifndef _KERNEL_DEVICE_RAMDRV_H
#define _KERNEL_DEVICE_RAMDRV_H
#include <libk/list.h>
#include <libk/std.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
struct device;
struct device_op_ctx;
@@ -23,16 +26,16 @@ bool ramdrv_init (struct device* device, void* arg);
void ramdrv_fini (struct device* device);
int ramdrv_read (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2, void* a3,
void* a4);
int ramdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4);
int ramdrv_get_device_type (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4);
int ramdrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4);
int ramdrv_get_sector_size (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4);
int ramdrv_get_sector_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4);
int ramdrv_get_size (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4);
int ramdrv_get_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4);
#endif // _KERNEL_DEVICE_RAMDRV_H

View File

@@ -35,11 +35,11 @@ bool terminal_init (struct device* device, void* arg) {
void terminal_fini (struct device* device) { (void)device; }
int terminal_putstr (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4) {
int terminal_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) {
(void)a2, (void)a3, (void)a4, (void)device;
if ((op_ctx->proc != NULL) && !(op_ctx->proc->procgroup->capabilities & PROC_CAP_TERMINAL))
if (!(proc->procgroup->capabilities & PROC_CAP_TERMINAL))
return -ST_PERMISSION_ERROR;
char* string = (char*)a1;

View File

@@ -1,14 +1,19 @@
#ifndef _KERNEL_DEVICE_TERMINAL_H
#define _KERNEL_DEVICE_TERMINAL_H
#include <libk/list.h>
#include <libk/std.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
struct device;
struct device_op_ctx;
bool terminal_init (struct device* device, void* arg);
void terminal_fini (struct device* device);
int terminal_putstr (struct device* device, struct device_op_ctx* op_ctx, void* a1, void* a2,
void* a3, void* a4);
int terminal_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4);
#endif // _KERNEL_DEVICE_TERMINAL_H

View File

@@ -54,7 +54,8 @@ static size_t tar_parse (struct tarfs* tarfs, uint8_t* addr) {
return i;
}
int tarfs_mount (struct vfs_mountpoint* mountpoint, struct device_op_ctx* op_ctx) {
int tarfs_mount (struct vfs_mountpoint* mountpoint, struct proc* proc,
struct reschedule_ctx* rctx) {
struct tarfs* tarfs = malloc (sizeof (*tarfs));
if (tarfs == NULL)
@@ -70,7 +71,7 @@ int tarfs_mount (struct vfs_mountpoint* mountpoint, struct device_op_ctx* op_ctx
spin_lock (&back_device->lock);
ret = back_device->ops[XDRV_GET_SIZE](back_device, op_ctx, &total_size, NULL, NULL, NULL);
ret = back_device->ops[XDRV_GET_SIZE](back_device, proc, rctx, &total_size, NULL, NULL, NULL);
if (ret < 0) {
spin_unlock (&back_device->lock);
free (mountpoint->udata);
@@ -86,7 +87,7 @@ int tarfs_mount (struct vfs_mountpoint* mountpoint, struct device_op_ctx* op_ctx
}
size_t pos = 0;
ret = back_device->ops[XDRV_READ](back_device, op_ctx, &pos, &total_size, buffer, NULL);
ret = back_device->ops[XDRV_READ](back_device, proc, rctx, &pos, &total_size, buffer, NULL);
spin_unlock (&back_device->lock);

View File

@@ -4,6 +4,8 @@
#include <device/device.h>
#include <libk/std.h>
#include <m/fs_desc_buffer.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
struct tar_header {
char filename[100];
@@ -31,7 +33,7 @@ struct tarfs {
struct vfs_mountpoint;
int tarfs_mount (struct vfs_mountpoint* mountpoint, struct device_op_ctx* op_ctx);
int tarfs_mount (struct vfs_mountpoint* mountpoint, struct proc* proc, struct reschedule_ctx* rctx);
int tarfs_describe (struct vfs_mountpoint* mountpoint, const char* path,
struct fs_desc_buffer* desc);

View File

@@ -8,6 +8,7 @@
#include <libk/string.h>
#include <m/status.h>
#include <mm/liballoc.h>
#include <proc/proc.h>
#include <proc/procgroup.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
@@ -32,7 +33,7 @@ static struct vfs_mountpoint* vfs_find_mountpoint (const char* mountpoint) {
}
int vfs_create_mountpoint (const char* key, int fs_type, struct device* back_device,
struct device_op_ctx* op_ctx) {
struct proc* proc, struct reschedule_ctx* rctx) {
if (strlen_null (key) > fieldsizeof (struct vfs_mountpoint, key))
return -ST_OOB_ERROR;
@@ -60,7 +61,7 @@ int vfs_create_mountpoint (const char* key, int fs_type, struct device* back_dev
} break;
}
int ret = mountpoint->driver_ops.mount (mountpoint, op_ctx);
int ret = mountpoint->driver_ops.mount (mountpoint, proc, rctx);
if (ret < 0) {
free (mountpoint);

View File

@@ -6,7 +6,9 @@
#include <libk/list.h>
#include <libk/std.h>
#include <m/fs_desc_buffer.h>
#include <proc/proc.h>
#include <proc/procgroup.h>
#include <proc/reschedule.h>
#include <sync/spin_lock.h>
#define VFS_TARFS 0
@@ -19,9 +21,12 @@ struct vfs_mountpoint {
bool locked;
struct procgroup* ownerpg;
struct {
int (*mount) (struct vfs_mountpoint* mountpoint, struct device_op_ctx* op_ctx);
int (*mount) (struct vfs_mountpoint* mountpoint, struct proc* proc,
struct reschedule_ctx* rctx);
int (*describe) (struct vfs_mountpoint* mountpoint, const char* path,
struct fs_desc_buffer* desc);
int (*read) (struct vfs_mountpoint* mountpoint, const char* path, uint8_t* buffer, size_t off,
size_t size);
} driver_ops;
@@ -35,7 +40,7 @@ struct vfs_mount_table {
};
int vfs_create_mountpoint (const char* key, int fs_type, struct device* back_device,
struct device_op_ctx* op_ctx);
struct proc* proc, struct reschedule_ctx* rctx);
int vfs_describe (struct procgroup* procgroup, const char* mountpoint, const char* path,
struct fs_desc_buffer* desc);

View File

@@ -1,11 +1,12 @@
#ifndef _KERNEL_IRQ_IRQ_H
#define _KERNEL_IRQ_IRQ_H
#include <libk/list.h>
#include <libk/rbtree.h>
#include <libk/std.h>
#include <sys/smp.h>
#include <proc/reschedule.h>
typedef bool (*irq_func_t) (struct cpu** reschedule_cpu, void* arg, void* regs);
typedef void (*irq_func_t) (void* arg, void* regs, struct reschedule_ctx* rctx);
struct irq {
uint32_t irq_num;

View File

@@ -1,3 +1,5 @@
#include <libk/list.h>
#include <libk/minmax.h>
#include <libk/std.h>
#include <libk/string.h>
#include <mm/liballoc.h>
@@ -8,9 +10,8 @@
#include <sys/debug.h>
#include <sys/smp.h>
bool proc_cleanup_resource_mail (struct proc_resource* resource, struct cpu** reschedule_cpu) {
void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx) {
struct proc_mail* mail = &resource->u.mail;
bool reschedule = PROC_NO_RESCHEDULE;
spin_lock (&mail->resource->lock);
@@ -29,7 +30,7 @@ bool proc_cleanup_resource_mail (struct proc_resource* resource, struct cpu** re
spin_unlock (&mail->send_sq.lock);
spin_unlock (&mail->resource->lock);
reschedule = reschedule || proc_sq_resume (suspended_proc, sq_entry, reschedule_cpu);
proc_sq_resume (suspended_proc, sq_entry, rctx);
spin_lock (&mail->resource->lock);
spin_lock (&mail->send_sq.lock);
@@ -38,13 +39,18 @@ bool proc_cleanup_resource_mail (struct proc_resource* resource, struct cpu** re
spin_unlock (&mail->send_sq.lock);
spin_unlock (&mail->resource->lock);
return reschedule;
}
bool proc_mail_send (struct proc* proc, struct proc_mail* mail, struct cpu** reschedule_cpu,
void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx,
void* data, size_t data_size) {
spin_lock (&mail->resource->lock);
/* mail full */
if (mail->pending_mesg != NULL) {
proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, rctx);
return;
}
spin_lock (&mail->recv_sq.lock);
/* if receiver available, hand off directly */
@@ -57,40 +63,33 @@ bool proc_mail_send (struct proc* proc, struct proc_mail* mail, struct cpu** res
spin_unlock (&mail->recv_sq.lock);
spin_unlock (&mail->resource->lock);
spin_lock (&proc->lock);
spin_lock (&resumed_proc->lock);
if (resumed_proc->mail_recv_buffer != NULL) {
size_t copy_size =
(data_size < resumed_proc->mail_recv_size) ? data_size : resumed_proc->mail_recv_size;
size_t copy_size = min (data_size, resumed_proc->mail_recv_size);
memcpy (resumed_proc->mail_recv_buffer, data, copy_size);
resumed_proc->mail_recv_buffer = NULL;
resumed_proc->mail_recv_size = 0;
}
spin_unlock (&proc->lock);
spin_unlock (&resumed_proc->lock);
return proc_sq_resume (resumed_proc, sq_entry, reschedule_cpu);
proc_sq_resume (resumed_proc, sq_entry, rctx);
return;
}
spin_unlock (&mail->recv_sq.lock);
/* mail full */
if (mail->pending_mesg != NULL) {
return proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, reschedule_cpu);
}
/* mail is empty and nobody is waiting */
mail->pending_mesg = malloc (data_size);
memcpy (mail->pending_mesg, data, data_size);
mail->pending_mesg_size = data_size;
spin_unlock (&mail->resource->lock);
return PROC_NO_RESCHEDULE;
}
bool proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct cpu** reschedule_cpu,
void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx,
void* recv_buffer, size_t recv_size) {
spin_lock (&proc->lock);
proc->mail_recv_buffer = recv_buffer;
@@ -118,15 +117,16 @@ bool proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct cpu**
spin_unlock (&mail->send_sq.lock);
spin_unlock (&mail->resource->lock);
return proc_sq_resume (resumed_proc, sq_entry, reschedule_cpu);
proc_sq_resume (resumed_proc, sq_entry, rctx);
return;
}
spin_unlock (&mail->send_sq.lock);
spin_unlock (&mail->resource->lock);
return PROC_NO_RESCHEDULE;
return;
}
/* nothing to receive */
return proc_sq_suspend (proc, &mail->recv_sq, &mail->resource->lock, reschedule_cpu);
proc_sq_suspend (proc, &mail->recv_sq, &mail->resource->lock, rctx);
}

View File

@@ -1,12 +1,14 @@
#ifndef _KERNEL_PROC_MAIL_H
#define _KERNEL_PROC_MAIL_H
#include <libk/list.h>
#include <libk/std.h>
#include <proc/suspension_q.h>
struct proc;
struct proc_resource;
struct cpu;
struct reschedule_ctx;
struct proc_mail {
struct proc_resource* resource;
@@ -17,10 +19,12 @@ struct proc_mail {
size_t pending_mesg_size;
};
bool proc_cleanup_resource_mail (struct proc_resource* resource, struct cpu** reschedule_cpu);
bool proc_mail_send (struct proc* proc, struct proc_mail* mail, struct cpu** reschedule_cpu,
void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx);
void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx,
void* data, size_t data_size);
bool proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct cpu** reschedule_cpu,
void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct reschedule_ctx* rctx,
void* recv_buffer, size_t recv_size);
#endif // _KERNEL_PROC_MAIL_H

View File

@@ -11,7 +11,7 @@
#include <sys/smp.h>
#include <sys/spin_lock.h>
void proc_mutexes_cleanup (struct proc* proc) {
void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx) {
spin_lock (&proc->procgroup->lock);
struct rb_node_link* rnode;
@@ -35,22 +35,19 @@ void proc_mutexes_cleanup (struct proc* proc) {
if (resource->u.mutex.owner == proc && resource->u.mutex.locked) {
spin_unlock (&resource->lock);
struct cpu* reschedule_cpu;
proc_mutex_unlock (proc, &resource->u.mutex, &reschedule_cpu);
proc_mutex_unlock (proc, &resource->u.mutex, rctx);
}
}
spin_unlock (&proc->procgroup->lock);
}
bool proc_cleanup_resource_mutex (struct proc_resource* resource, struct cpu** reschedule_cpu) {
void proc_cleanup_resource_mutex (struct proc_resource* resource, struct reschedule_ctx* rctx) {
struct proc_mutex* mutex = &resource->u.mutex;
spin_lock (&mutex->resource->lock);
spin_lock (&mutex->suspension_q.lock);
bool reschedule = PROC_NO_RESCHEDULE;
while (mutex->suspension_q.proc_list != NULL) {
struct list_node_link* node = mutex->suspension_q.proc_list;
struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link);
@@ -60,7 +57,7 @@ bool proc_cleanup_resource_mutex (struct proc_resource* resource, struct cpu** r
spin_unlock (&mutex->suspension_q.lock);
spin_unlock (&mutex->resource->lock);
reschedule = reschedule || proc_sq_resume (suspended_proc, sq_entry, reschedule_cpu);
proc_sq_resume (suspended_proc, sq_entry, rctx);
/* reacquire */
spin_lock (&mutex->resource->lock);
@@ -72,29 +69,27 @@ bool proc_cleanup_resource_mutex (struct proc_resource* resource, struct cpu** r
spin_unlock (&mutex->suspension_q.lock);
spin_unlock (&mutex->resource->lock);
return reschedule;
}
bool proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct cpu** reschedule_cpu) {
void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx) {
spin_lock (&mutex->resource->lock);
if (!mutex->locked || mutex->owner == proc) {
mutex->locked = true;
mutex->owner = proc;
spin_unlock (&mutex->resource->lock);
return PROC_NO_RESCHEDULE;
return;
}
return proc_sq_suspend (proc, &mutex->suspension_q, &mutex->resource->lock, reschedule_cpu);
proc_sq_suspend (proc, &mutex->suspension_q, &mutex->resource->lock, rctx);
}
bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct cpu** reschedule_cpu) {
void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx) {
spin_lock (&mutex->resource->lock);
if (mutex->owner != proc) {
spin_unlock (&mutex->resource->lock);
return PROC_NO_RESCHEDULE;
return;
}
spin_lock (&mutex->suspension_q.lock);
@@ -111,7 +106,8 @@ bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct cpu*
spin_unlock (&mutex->suspension_q.lock);
spin_unlock (&mutex->resource->lock);
return proc_sq_resume (resumed_proc, sq_entry, reschedule_cpu);
proc_sq_resume (resumed_proc, sq_entry, rctx);
return;
}
mutex->locked = false;
@@ -119,6 +115,4 @@ bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct cpu*
spin_unlock (&mutex->suspension_q.lock);
spin_unlock (&mutex->resource->lock);
return PROC_NO_RESCHEDULE;
}

View File

@@ -1,12 +1,14 @@
#ifndef _KERNEL_PROC_MUTEX_H
#define _KERNEL_PROC_MUTEX_H
#include <libk/list.h>
#include <libk/std.h>
#include <proc/suspension_q.h>
struct proc;
struct proc_resource;
struct cpu;
struct reschedule_ctx;
struct proc_mutex {
struct proc_resource* resource;
@@ -16,9 +18,12 @@ struct proc_mutex {
struct proc* owner;
};
bool proc_cleanup_resource_mutex (struct proc_resource* resource, struct cpu** reschedule_cpu);
bool proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct cpu** reschedule_cpu);
bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct cpu** reschedule_cpu);
void proc_mutexes_cleanup (struct proc* proc);
void proc_cleanup_resource_mutex (struct proc_resource* resource, struct reschedule_ctx* rctx);
void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx);
void proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex, struct reschedule_ctx* rctx);
void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx);
#endif // _KERNEL_PROC_MUTEX_H

View File

@@ -15,6 +15,7 @@
#include <proc/capability.h>
#include <proc/proc.h>
#include <proc/procgroup.h>
#include <proc/reschedule.h>
#include <proc/resource.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
@@ -160,8 +161,8 @@ struct proc* proc_find_pid (int pid) {
return proc;
}
bool proc_register (struct proc* proc, struct cpu** reschedule_cpu) {
struct cpu* cpu = *reschedule_cpu != NULL ? *reschedule_cpu : cpu_find_lightest ();
void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedule_ctx* rctx) {
struct cpu* cpu = register_cpu != NULL ? register_cpu : cpu_find_lightest ();
spin_lock (&proc_tree_lock);
spin_lock (&cpu->lock);
@@ -180,9 +181,8 @@ bool proc_register (struct proc* proc, struct cpu** reschedule_cpu) {
spin_unlock (&cpu->lock);
spin_unlock (&proc_tree_lock);
*reschedule_cpu = cpu;
return PROC_NEED_RESCHEDULE;
if (rctx != NULL)
reschedule_list_append (rctx, cpu);
}
/* caller holds cpu->lock */
@@ -214,7 +214,7 @@ static struct proc* proc_find_sched (struct cpu* cpu) {
return NULL;
}
static void proc_reap (void) {
static void proc_reap (struct reschedule_ctx* rctx) {
struct proc* proc = NULL;
struct list_node_link* reap_list = NULL;
@@ -246,15 +246,16 @@ static void proc_reap (void) {
list_remove (reap_list, &proc->reap_link);
DEBUG ("cleanup PID %d\n", proc->pid);
proc_cleanup (proc);
proc_cleanup (proc, rctx);
}
}
void proc_sched (void) {
int s_cycles = atomic_fetch_add (&sched_cycles, 1);
struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT};
if (s_cycles % SCHED_REAP_FREQ == 0)
proc_reap ();
proc_reap (&rctx);
struct proc* next = NULL;
struct cpu* cpu = thiscpu;
@@ -275,7 +276,7 @@ void proc_sched (void) {
}
}
bool proc_kill (struct proc* proc, struct cpu** reschedule_cpu) {
void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) {
spin_lock (&proc->lock);
struct cpu* cpu = proc->cpu;
spin_unlock (&proc->lock);
@@ -294,17 +295,14 @@ bool proc_kill (struct proc* proc, struct cpu** reschedule_cpu) {
spin_unlock (&proc->lock);
spin_unlock (&cpu->lock);
reschedule_list_append (rctx, cpu);
DEBUG ("killed PID %d\n", proc->pid);
*reschedule_cpu = cpu;
return PROC_NEED_RESCHEDULE;
}
static bool proc_irq_sched (struct cpu** reschedule_cpu, void* arg, void* regs) {
(void)arg, (void)regs, (void)reschedule_cpu;
static void proc_irq_sched (void* arg, void* regs, struct reschedule_ctx* rctx) {
(void)arg, (void)regs;
proc_sched ();
return PROC_NO_RESCHEDULE;
}
void proc_init (void) {
@@ -314,13 +312,11 @@ void proc_init (void) {
#endif
struct proc* spin_proc = proc_from_file (NULL, "ramdisk", "/spin");
struct cpu* spin_cpu = thiscpu;
proc_register (spin_proc, &spin_cpu);
proc_register (spin_proc, thiscpu, NULL);
struct proc* init = proc_from_file (NULL, "ramdisk", "/init");
init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB);
struct cpu* init_cpu = thiscpu;
proc_register (init, &init_cpu);
proc_register (init, thiscpu, NULL);
spin_lock (&spin_proc->cpu->lock);
do_sched (spin_proc, &spin_proc->cpu->lock);

View File

@@ -17,9 +17,6 @@
#include <amd64/proc.h> /* USTACK_SIZE */
#endif
#define PROC_NEED_RESCHEDULE true
#define PROC_NO_RESCHEDULE false
/* process states */
#define PROC_READY 0
#define PROC_DEAD 1
@@ -29,6 +26,7 @@
#define PROC_USTK_PREALLOC (1 << 0)
struct cpu;
struct reschedule_ctx;
struct proc {
int pid;
@@ -50,11 +48,17 @@ struct proc {
};
void proc_sched (void);
bool proc_kill (struct proc* proc, struct cpu** reschedule_cpu);
void proc_kill (struct proc* proc, struct reschedule_ctx* rctx);
struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf);
bool proc_register (struct proc* proc, struct cpu** reschedule_cpu);
void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedule_ctx* rctx);
struct proc* proc_find_pid (int pid);
struct proc* proc_from_file (struct procgroup* procgroup, const char* mountpoint, const char* path);
void proc_init (void);
#endif // _KERNEL_PROC_PROC_H

View File

@@ -6,6 +6,7 @@
#include <mm/pmm.h>
#include <proc/proc.h>
#include <proc/procgroup.h>
#include <proc/reschedule.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
#include <sys/mm.h>
@@ -176,7 +177,8 @@ void procgroup_attach (struct procgroup* procgroup, struct proc* proc) {
spin_unlock (&procgroup->lock);
}
void procgroup_detach (struct procgroup* procgroup, struct proc* proc) {
void procgroup_detach (struct procgroup* procgroup, struct proc* proc,
struct reschedule_ctx* rctx) {
spin_lock (&procgroup->lock);
spin_lock (&proc->lock);
@@ -207,8 +209,7 @@ void procgroup_detach (struct procgroup* procgroup, struct proc* proc) {
rnode = next;
struct cpu* reschedule_cpu;
proc_delete_resource (resource, &reschedule_cpu);
proc_delete_resource (resource, rctx);
}
/* unlock VFS owned mountpoints */

View File

@@ -10,6 +10,7 @@
#include <sys/procgroup.h>
struct proc;
struct reschedule_ctx;
struct proc_mapping {
struct list_node_link proc_mappings_link;
@@ -35,11 +36,16 @@ struct procgroup {
};
struct procgroup* procgroup_create (void);
void procgroup_attach (struct procgroup* procgroup, struct proc* proc);
void procgroup_detach (struct procgroup* procgroup, struct proc* proc);
void procgroup_detach (struct procgroup* procgroup, struct proc* proc, struct reschedule_ctx* rctx);
uintptr_t procgroup_map (struct procgroup* procgroup, uintptr_t vaddr, size_t pages, uint32_t flags,
uintptr_t* out_paddr);
bool procgroup_unmap (struct procgroup* procgroup, uintptr_t start_vaddr, size_t pages);
struct procgroup* procgroup_find (int pgid);
#endif // _KERNEL_PROC_PROCGROUP_H

32
kernel/proc/reschedule.c Normal file
View File

@@ -0,0 +1,32 @@
#include <libk/list.h>
#include <mm/liballoc.h>
#include <proc/reschedule.h>
#include <sync/spin_lock.h>
#include <sys/smp.h>
void reschedule_list_append (struct reschedule_ctx* rctx, struct cpu* cpu) {
spin_lock (&rctx->lock);
struct list_node_link *node, *tmp;
list_foreach (rctx->entries, node, tmp) {
struct reschedule_entry* entry = list_entry (node, struct reschedule_entry, link);
if (entry->cpu == cpu) {
spin_unlock (&rctx->lock);
return;
}
}
struct reschedule_entry* entry = malloc (sizeof (*entry));
if (entry == NULL) {
spin_unlock (&rctx->lock);
return;
}
entry->cpu = cpu;
list_append (rctx->entries, &entry->link);
spin_unlock (&rctx->lock);
}

20
kernel/proc/reschedule.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef _KERNEL_PROC_RESCHEDULE_H
#define _KERNEL_PROC_RESCHEDULE_H
#include <libk/list.h>
#include <sync/spin_lock.h>
#include <sys/smp.h>
struct reschedule_entry {
struct cpu* cpu;
struct list_node_link link;
};
struct reschedule_ctx {
struct list_node_link* entries;
spin_lock_t lock;
};
void reschedule_list_append (struct reschedule_ctx* rctx, struct cpu* cpu);
#endif // _KERNEL_PROC_RESCHEDULE_H

View File

@@ -9,6 +9,7 @@
#include <proc/mutex.h>
#include <proc/proc.h>
#include <proc/procgroup.h>
#include <proc/reschedule.h>
#include <proc/resource.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
@@ -76,9 +77,7 @@ struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup, in
return resource;
}
bool proc_delete_resource (struct proc_resource* resource, struct cpu** reschedule_cpu) {
bool reschedule = resource->ops.cleanup (resource, reschedule_cpu);
void proc_delete_resource (struct proc_resource* resource, struct reschedule_ctx* rctx) {
resource->ops.cleanup (resource, rctx);
free (resource);
return reschedule;
}

View File

@@ -14,6 +14,7 @@
struct proc;
struct procgroup;
struct cpu;
struct reschedule_ctx;
struct proc_resource {
int type;
@@ -25,13 +26,16 @@ struct proc_resource {
struct proc_mail mail;
} u;
struct {
bool (*cleanup) (struct proc_resource* resource, struct cpu** reschedule_cpu);
void (*cleanup) (struct proc_resource* resource, struct reschedule_ctx* rctx);
} ops;
};
struct proc_resource* proc_find_resource (struct procgroup* procgroup, int rid);
struct proc_resource* proc_create_resource_mutex (struct procgroup* procgroup, int rid);
struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup, int rid);
bool proc_delete_resource (struct proc_resource* resource, struct cpu** reschedule_cpu);
void proc_delete_resource (struct proc_resource* resource, struct reschedule_ctx* rctx);
#endif // _KERNEL_PROC_RESOURCE_H

View File

@@ -3,11 +3,13 @@ c += proc/proc.c \
proc/mutex.c \
proc/procgroup.c \
proc/suspension_q.c \
proc/mail.c
proc/mail.c \
proc/reschedule.c
o += proc/proc.o \
proc/resource.o \
proc/mutex.o \
proc/procgroup.o \
proc/suspension_q.o \
proc/mail.o
proc/mail.o \
proc/reschedule.o

View File

@@ -2,20 +2,21 @@
#include <libk/std.h>
#include <mm/liballoc.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
#include <proc/resource.h>
#include <proc/suspension_q.h>
#include <sync/spin_lock.h>
#include <sys/smp.h>
#include <sys/spin_lock.h>
bool proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
struct cpu** reschedule_cpu) {
void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
struct reschedule_ctx* rctx) {
struct cpu* cpu = proc->cpu;
struct proc_sq_entry* sq_entry = malloc (sizeof (*sq_entry));
if (!sq_entry) {
spin_unlock (resource_lock);
return PROC_NO_RESCHEDULE;
return;
}
sq_entry->proc = proc;
@@ -47,13 +48,11 @@ bool proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock
spin_unlock (&proc->lock);
spin_unlock (&cpu->lock);
*reschedule_cpu = cpu;
return PROC_NEED_RESCHEDULE;
reschedule_list_append (rctx, cpu);
}
bool proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
struct cpu** reschedule_cpu) {
void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
struct reschedule_ctx* rctx) {
struct cpu* cpu = cpu_find_lightest ();
struct proc_suspension_q* sq = sq_entry->sq;
@@ -81,9 +80,7 @@ bool proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
free (sq_entry);
*reschedule_cpu = cpu;
return PROC_NEED_RESCHEDULE;
reschedule_list_append (rctx, cpu);
}
void proc_sqs_cleanup (struct proc* proc) {

View File

@@ -6,6 +6,7 @@
struct proc;
struct cpu;
struct reschedule_ctx;
struct proc_suspension_q {
struct list_node_link* proc_list;
@@ -20,9 +21,11 @@ struct proc_sq_entry {
};
void proc_sqs_cleanup (struct proc* proc);
bool proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
struct cpu** reschedule_cpu);
bool proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
struct cpu** reschedule_cpu);
void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock_t* resource_lock,
struct reschedule_ctx* rctx);
void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
struct reschedule_ctx* rctx);
#endif // _KERNEL_PROC_SUSPENTION_Q_H

View File

@@ -1,14 +1,19 @@
#ifndef _KERNEL_SYS_PROC_H
#define _KERNEL_SYS_PROC_H
#include <libk/list.h>
#include <libk/std.h>
#include <proc/reschedule.h>
struct proc;
struct proc* proc_from_elf (uint8_t* elf_contents);
struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t entry,
uintptr_t argument_ptr);
void proc_cleanup (struct proc* proc);
void proc_cleanup (struct proc* proc, struct reschedule_ctx* rctx);
void proc_init_tls (struct proc* proc);
#endif // _KERNEL_SYS_PROC_H

View File

@@ -22,10 +22,9 @@
#include <syscall/syscall.h>
#define DEFINE_SYSCALL(name) \
uintptr_t name (struct proc* UNUSED proc, void* UNUSED regs, bool* UNUSED reschedule, \
struct cpu** UNUSED reschedule_cpu, uintptr_t UNUSED a1, uintptr_t UNUSED a2, \
uintptr_t UNUSED a3, uintptr_t UNUSED a4, uintptr_t UNUSED a5, \
uintptr_t UNUSED a6)
uintptr_t name (struct proc* UNUSED proc, void* UNUSED regs, struct reschedule_ctx* UNUSED rctx, \
uintptr_t UNUSED a1, uintptr_t UNUSED a2, uintptr_t UNUSED a3, \
uintptr_t UNUSED a4, uintptr_t UNUSED a5, uintptr_t UNUSED a6)
#define SYSRESULT(x) ((uintptr_t)(x))
@@ -50,8 +49,7 @@ static void* sys_get_user_buffer (struct proc* proc, uintptr_t uvaddr, size_t si
/* int quit (void) */
DEFINE_SYSCALL (sys_quit) {
if (proc_kill (proc, reschedule_cpu) == PROC_NEED_RESCHEDULE)
*reschedule = true;
proc_kill (proc, rctx);
return SYSRESULT (ST_OK);
}
@@ -100,8 +98,7 @@ DEFINE_SYSCALL (sys_clone) {
int pid = new->pid;
if (proc_register (new, reschedule_cpu) == PROC_NEED_RESCHEDULE)
*reschedule = true;
proc_register (new, NULL, rctx);
return SYSRESULT (pid);
}
@@ -111,7 +108,7 @@ DEFINE_SYSCALL (sys_argument_ptr) { return proc->uvaddr_argument; }
/* int sched (void) */
DEFINE_SYSCALL (sys_sched) {
*reschedule = true;
reschedule_list_append (rctx, thiscpu);
return SYSRESULT (ST_OK);
}
@@ -136,8 +133,7 @@ DEFINE_SYSCALL (sys_mutex_delete) {
if (mutex_resource == NULL)
return SYSRESULT (-ST_NOT_FOUND);
if (proc_delete_resource (mutex_resource, reschedule_cpu) == PROC_NEED_RESCHEDULE)
*reschedule = true;
proc_delete_resource (mutex_resource, rctx);
return SYSRESULT (ST_OK);
}
@@ -151,8 +147,7 @@ DEFINE_SYSCALL (sys_mutex_lock) {
if (mutex_resource == NULL)
return SYSRESULT (-ST_NOT_FOUND);
if (proc_mutex_lock (proc, &mutex_resource->u.mutex, reschedule_cpu) == PROC_NEED_RESCHEDULE)
*reschedule = true;
proc_mutex_lock (proc, &mutex_resource->u.mutex, rctx);
return SYSRESULT (ST_OK);
}
@@ -166,8 +161,7 @@ DEFINE_SYSCALL (sys_mutex_unlock) {
if (mutex_resource == NULL)
return SYSRESULT (-ST_NOT_FOUND);
if (proc_mutex_unlock (proc, &mutex_resource->u.mutex, reschedule_cpu) == PROC_NEED_RESCHEDULE)
*reschedule = true;
proc_mutex_unlock (proc, &mutex_resource->u.mutex, rctx);
return SYSRESULT (ST_OK);
}
@@ -193,10 +187,7 @@ DEFINE_SYSCALL (sys_mail_send) {
if (mail_resource == NULL)
return SYSRESULT (-ST_NOT_FOUND);
if (proc_mail_send (proc, &mail_resource->u.mail, reschedule_cpu, mesg, mesg_size) ==
PROC_NEED_RESCHEDULE) {
*reschedule = true;
}
proc_mail_send (proc, &mail_resource->u.mail, rctx, mesg, mesg_size);
return SYSRESULT (ST_OK);
}
@@ -216,10 +207,7 @@ DEFINE_SYSCALL (sys_mail_receive) {
if (mail_resource == NULL)
return SYSRESULT (-ST_NOT_FOUND);
if (proc_mail_receive (proc, &mail_resource->u.mail, reschedule_cpu, mesg, mesg_size) ==
PROC_NEED_RESCHEDULE) {
*reschedule = true;
}
proc_mail_receive (proc, &mail_resource->u.mail, rctx, mesg, mesg_size);
return SYSRESULT (ST_OK);
}
@@ -264,15 +252,9 @@ DEFINE_SYSCALL (sys_device_do) {
if (device == NULL)
return SYSRESULT (-ST_NOT_FOUND);
struct device_op_ctx op_ctx = {
.proc = proc,
.reschedule = reschedule,
.reschedule_cpu = reschedule_cpu,
};
spin_lock (&device->lock);
int ret = device->ops[cmd](device, &op_ctx, (void*)ka1, (void*)ka2, (void*)ka3, (void*)ka4);
int ret = device->ops[cmd](device, proc, rctx, (void*)ka1, (void*)ka2, (void*)ka3, (void*)ka4);
spin_unlock (&device->lock);
@@ -310,8 +292,7 @@ DEFINE_SYSCALL (sys_exec) {
int pid = new->pid;
new->exec_pid = proc->pid;
if (proc_register (new, reschedule_cpu) == PROC_NEED_RESCHEDULE)
*reschedule = true;
proc_register (new, NULL, rctx);
return SYSRESULT (pid);
}
@@ -441,6 +422,9 @@ DEFINE_SYSCALL (sys_get_procgroup) {
struct proc* target_proc = proc_find_pid (pid);
if (target_proc == NULL)
return SYSRESULT (-ST_NOT_FOUND);
return SYSRESULT (target_proc->procgroup->pgid);
}

View File

@@ -1,13 +1,15 @@
#ifndef _KERNEL_SYSCALL_SYSCALL_H
#define _KERNEL_SYSCALL_SYSCALL_H
#include <libk/list.h>
#include <libk/std.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
struct cpu;
typedef uintptr_t (*syscall_handler_func_t) (struct proc* proc, void* regs, bool* reschedule,
struct cpu** reschedule_cpu, uintptr_t a1,
typedef uintptr_t (*syscall_handler_func_t) (struct proc* proc, void* regs,
struct reschedule_ctx* rctx, uintptr_t a1,
uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5,
uintptr_t a6);