diff --git a/ce/ce.c b/ce/ce.c index cb3be47..09d880d 100644 --- a/ce/ce.c +++ b/ce/ce.c @@ -9,7 +9,7 @@ void app_main (void) { char ch; mail_receive (&ch, 1); - test (ch); - /* mail_send (e_pgid, &ch, 1); */ + /* test (ch); */ + mail_send (e_pgid, &ch, 1); } } diff --git a/init/init.c b/init/init.c index fd83dcc..b609bee 100644 --- a/init/init.c +++ b/init/init.c @@ -18,8 +18,9 @@ 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); + /* test (rcv); */ + terminal_print (&rcv, 1); } } diff --git a/kernel/amd64/bootmain.c b/kernel/amd64/bootmain.c index 7d8d9b5..0b5bbf0 100644 --- a/kernel/amd64/bootmain.c +++ b/kernel/amd64/bootmain.c @@ -54,7 +54,7 @@ void bootmain (void) { vfs_init (); struct device* ramdisk_device = device_find (RAMDISK_DEVICE); - struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT}; + struct reschedule_ctx rctx = {.cpu = thiscpu, .reschedule = false}; int ret = vfs_create_mountpoint ("ramdisk", VFS_TARFS, ramdisk_device, NULL, &rctx); if (ret < 0) { diff --git a/kernel/amd64/debug.c b/kernel/amd64/debug.c index c63130e..a311973 100644 --- a/kernel/amd64/debug.c +++ b/kernel/amd64/debug.c @@ -26,13 +26,9 @@ 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); } /* @@ -54,10 +50,14 @@ 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 */ diff --git a/kernel/amd64/intr.c b/kernel/amd64/intr.c index 30e7721..2916644 100644 --- a/kernel/amd64/intr.c +++ b/kernel/amd64/intr.c @@ -157,35 +157,13 @@ static void amd64_intr_exception (struct saved_regs* regs) { regs->rbx); if (regs->cs == (GDT_UCODE | 0x03)) { - struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT}; - + struct reschedule_ctx rctx = {.reschedule = false, .cpu = NULL}; 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 (); - } + if (rctx.reschedule) + cpu_request_sched (rctx.cpu); } else { + __asm__ volatile ("cli"); spin (); } } @@ -215,33 +193,11 @@ void amd64_intr_handler (void* stack_ptr) { if (irq == NULL) return; - struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT}; + struct reschedule_ctx rctx = {.reschedule = false, .cpu = NULL}; 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 (); - } + if (rctx.reschedule) + cpu_request_sched (rctx.cpu); } } diff --git a/kernel/amd64/syscall.c b/kernel/amd64/syscall.c index 8810b4d..cd0f76d 100644 --- a/kernel/amd64/syscall.c +++ b/kernel/amd64/syscall.c @@ -37,7 +37,7 @@ uintptr_t amd64_syscall_dispatch (void* stack_ptr) { return -ST_SYSCALL_NOT_FOUND; } - struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT}; + struct reschedule_ctx rctx = {.reschedule = false, .cpu = NULL}; uintptr_t r = func (caller, regs, &rctx, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9); @@ -50,30 +50,8 @@ uintptr_t amd64_syscall_dispatch (void* stack_ptr) { spin_unlock (&caller->lock); } - 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 (); - } + if (rctx.reschedule) + cpu_request_sched (rctx.cpu); return r; } diff --git a/kernel/proc/mail.c b/kernel/proc/mail.c index 22687fc..d979e78 100644 --- a/kernel/proc/mail.c +++ b/kernel/proc/mail.c @@ -37,7 +37,6 @@ void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedu } spin_unlock (&mail->send_sq.lock); - spin_unlock (&mail->resource->lock); } @@ -82,9 +81,12 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul spin_unlock (&mail->recv_sq.lock); /* 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; + void* mesg = malloc (data_size); + if (mesg != NULL) { + mail->pending_mesg = mesg; + memcpy (mail->pending_mesg, data, data_size); + mail->pending_mesg_size = data_size; + } spin_unlock (&mail->resource->lock); } @@ -100,7 +102,7 @@ void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct resche /* consume mesg if available */ if (mail->pending_mesg != NULL) { - memcpy (recv_buffer, mail->pending_mesg, recv_size); + memcpy (recv_buffer, mail->pending_mesg, min (recv_size, mail->pending_mesg_size)); free (mail->pending_mesg); mail->pending_mesg = NULL; mail->pending_mesg_size = 0; diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 5a7a9d1..fcda791 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -181,8 +181,10 @@ void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedu spin_unlock (&cpu->lock); spin_unlock (&proc_tree_lock); - if (rctx != NULL) - reschedule_list_append (rctx, cpu); + if (rctx != NULL) { + rctx->reschedule = true; + rctx->cpu = cpu; + } } /* caller holds cpu->lock */ @@ -252,7 +254,7 @@ static void proc_reap (struct reschedule_ctx* rctx) { void proc_sched (void) { int s_cycles = atomic_fetch_add (&sched_cycles, 1); - struct reschedule_ctx rctx = {.entries = NULL, .lock = SPIN_LOCK_INIT}; + struct reschedule_ctx rctx = {.reschedule = false, .cpu = NULL}; if (s_cycles % SCHED_REAP_FREQ == 0) proc_reap (&rctx); @@ -295,7 +297,8 @@ void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) { spin_unlock (&proc->lock); spin_unlock (&cpu->lock); - reschedule_list_append (rctx, cpu); + rctx->reschedule = true; + rctx->cpu = cpu; DEBUG ("killed PID %d\n", proc->pid); } diff --git a/kernel/proc/reschedule.c b/kernel/proc/reschedule.c deleted file mode 100644 index 1821093..0000000 --- a/kernel/proc/reschedule.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include -#include - -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); -} diff --git a/kernel/proc/reschedule.h b/kernel/proc/reschedule.h index ad9c8c1..9f9284e 100644 --- a/kernel/proc/reschedule.h +++ b/kernel/proc/reschedule.h @@ -5,16 +5,9 @@ #include #include -struct reschedule_entry { - struct cpu* cpu; - struct list_node_link link; -}; - struct reschedule_ctx { - struct list_node_link* entries; - spin_lock_t lock; + bool reschedule; + struct cpu* cpu; }; -void reschedule_list_append (struct reschedule_ctx* rctx, struct cpu* cpu); - #endif // _KERNEL_PROC_RESCHEDULE_H diff --git a/kernel/proc/src.mk b/kernel/proc/src.mk index 538ba53..5b1510f 100644 --- a/kernel/proc/src.mk +++ b/kernel/proc/src.mk @@ -3,13 +3,11 @@ c += proc/proc.c \ proc/mutex.c \ proc/procgroup.c \ proc/suspension_q.c \ - proc/mail.c \ - proc/reschedule.c + proc/mail.c o += proc/proc.o \ proc/resource.o \ proc/mutex.o \ proc/procgroup.o \ proc/suspension_q.o \ - proc/mail.o \ - proc/reschedule.o + proc/mail.o diff --git a/kernel/proc/suspension_q.c b/kernel/proc/suspension_q.c index 72d0c1f..296db9e 100644 --- a/kernel/proc/suspension_q.c +++ b/kernel/proc/suspension_q.c @@ -48,7 +48,8 @@ void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock spin_unlock (&proc->lock); spin_unlock (&cpu->lock); - reschedule_list_append (rctx, cpu); + rctx->reschedule = true; + rctx->cpu = cpu; } void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, @@ -80,7 +81,8 @@ void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, free (sq_entry); - reschedule_list_append (rctx, cpu); + rctx->reschedule = true; + rctx->cpu = cpu; } void proc_sqs_cleanup (struct proc* proc) { diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index c8cc62d..db7bc05 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -108,7 +108,8 @@ DEFINE_SYSCALL (sys_argument_ptr) { return proc->uvaddr_argument; } /* int sched (void) */ DEFINE_SYSCALL (sys_sched) { - reschedule_list_append (rctx, thiscpu); + rctx->reschedule = true; + rctx->cpu = thiscpu; return SYSRESULT (ST_OK); }