Implement waiting for process, CE add command cancelation, rctx many cpus
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m27s

This commit is contained in:
2026-03-01 22:59:04 +01:00
parent 858e55118b
commit 9043c4f9ec
18 changed files with 308 additions and 89 deletions

View File

@@ -1,11 +1,11 @@
Copyright 2026 Kamil Kowalczyk Copyright 2026 Kamil Kowalczyk
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -2,4 +2,4 @@
set -x set -x
qemu-system-x86_64 -M q35 -m 4G -serial stdio -enable-kvm -cdrom mop3.iso -smp 4 $@ qemu-system-x86_64 -M q35 -m 4G -serial stdio -enable-kvm -cdrom mop3.iso -smp 1 $@

117
ce/ce.c
View File

@@ -14,6 +14,9 @@
#include <system.h> #include <system.h>
#include <terminal_cursor.h> #include <terminal_cursor.h>
#define CTRL(x) ((x) - '@')
#define CPRINTF_BUF_MAX (1024 * 16)
static struct arena arena; static struct arena arena;
struct strbuf { struct strbuf {
@@ -45,8 +48,6 @@ struct context {
struct strbuf strbuf; struct strbuf strbuf;
}; };
#define CPRINTF_BUF_MAX 4096
void cprintf (struct context* context, const char* fmt, ...) { void cprintf (struct context* context, const char* fmt, ...) {
va_list args; va_list args;
va_start (args, fmt); va_start (args, fmt);
@@ -264,8 +265,26 @@ static int e_pgid;
static bool run = true; static bool run = true;
static void putch (char ch) { mail_send (e_pgid, &ch, 1); } void putchar_ (char ch) { (void)ch; }
void putchar_ (char ch) { putch (ch); }
void mprintf (const char* fmt, ...) {
va_list args;
va_start (args, fmt);
char* buf = malloc (CPRINTF_BUF_MAX);
if (buf == NULL) {
va_end (args);
return;
}
int len = vsnprintf (buf, CPRINTF_BUF_MAX, fmt, args);
va_end (args);
mail_send (e_pgid, buf, len);
free (buf);
}
static void tokenize (struct list_node_link** tokens, const char* text) { static void tokenize (struct list_node_link** tokens, const char* text) {
const char* p = text; const char* p = text;
@@ -311,7 +330,7 @@ static void tokenize (struct list_node_link** tokens, const char* text) {
continue; continue;
} }
printf ("ERROR unknown character '%c'\n", *p); mprintf ("ERROR unknown character '%c'\r\n", *p);
p++; p++;
} }
} }
@@ -331,7 +350,7 @@ static void parse_and_execute (struct list_node_link* tokens) {
execute (root, &context); execute (root, &context);
if (context.strbuf.items != NULL) if (context.strbuf.items != NULL)
printf ("%.*s", (int)context.strbuf.count, context.strbuf.items); mprintf ("%.*s", (int)context.strbuf.count, context.strbuf.items);
} }
} }
} }
@@ -350,12 +369,12 @@ static void mkfile (struct context* context, char** file_paths, size_t files_cou
const char* file_path = file_paths[i]; const char* file_path = file_paths[i];
if (!path_parse (file_path, volume, &path)) { if (!path_parse (file_path, volume, &path)) {
cprintf (context, "ERROR bad path '%s'\n", file_path); cprintf (context, "ERROR bad path '%s'\r\n", file_path);
continue; continue;
} }
if ((ret = volume_open (volume)) < 0) { if ((ret = volume_open (volume)) < 0) {
cprintf (context, "ERROR could not open volume '%s': %s\n", volume, str_status[-ret]); cprintf (context, "ERROR could not open volume '%s': %s\r\n", volume, str_status[-ret]);
continue; continue;
} }
@@ -375,12 +394,12 @@ static void cat (struct context* context, char** file_paths, size_t files_count)
const char* file_path = file_paths[i]; const char* file_path = file_paths[i];
if (!path_parse (file_path, volume, &path)) { if (!path_parse (file_path, volume, &path)) {
cprintf (context, "ERROR bad path '%s'\n", file_path); cprintf (context, "ERROR bad path '%s'\r\n", file_path);
continue; continue;
} }
if ((ret = volume_open (volume)) < 0) { if ((ret = volume_open (volume)) < 0) {
cprintf (context, "ERROR could not open volume '%s': %s\n", volume, str_status[-ret]); cprintf (context, "ERROR could not open volume '%s': %s\r\n", volume, str_status[-ret]);
continue; continue;
} }
@@ -396,7 +415,7 @@ static void cat (struct context* context, char** file_paths, size_t files_count)
memset (buffer, 0, desc.size + 1); memset (buffer, 0, desc.size + 1);
read_file (path, 0, (uint8_t*)buffer, desc.size); read_file (path, 0, (uint8_t*)buffer, desc.size);
cprintf (context, "%s\n", buffer); cprintf (context, "%s\r\n", buffer);
close: close:
if (buffer != NULL) if (buffer != NULL)
@@ -413,26 +432,26 @@ static void ls (struct context* context, const char* path_string) {
struct dir_entry entry; struct dir_entry entry;
if (!path_parse (path_string, volume, &path)) { if (!path_parse (path_string, volume, &path)) {
cprintf (context, "ERROR bad path '%s'\n", path_string); cprintf (context, "ERROR bad path '%s'\r\n", path_string);
return; return;
} }
if ((ret = volume_open (volume)) < 0) { if ((ret = volume_open (volume)) < 0) {
cprintf (context, "ERROR could not open volume '%s': %s\n", volume, str_status[-ret]); cprintf (context, "ERROR could not open volume '%s': %s\r\n", volume, str_status[-ret]);
return; return;
} }
describe (path, &desc); describe (path, &desc);
if (desc.type != FS_DIR) { if (desc.type != FS_DIR) {
cprintf (context, "ERROR '%s' is not a directory\n", path_string); cprintf (context, "ERROR '%s' is not a directory\r\n", path_string);
volume_close (); volume_close ();
return; return;
} }
size_t entries = desc.size; size_t entries = desc.size;
cprintf (context, "total entries: %zu\n", entries); cprintf (context, "total entries: %zu\r\n", entries);
cprintf (context, "\n"); cprintf (context, "\r\n");
for (size_t entry_num = 0; entry_num < entries; entry_num++) { for (size_t entry_num = 0; entry_num < entries; entry_num++) {
memset (&desc, 0, sizeof (desc)); memset (&desc, 0, sizeof (desc));
@@ -441,7 +460,7 @@ static void ls (struct context* context, const char* path_string) {
read_dir_entry (path, &entry, entry_num); read_dir_entry (path, &entry, entry_num);
describe (entry.path, &desc); describe (entry.path, &desc);
cprintf (context, "%c %-40s %-40zu\n", (desc.type == FS_DIR ? 'D' : 'F'), entry.path, cprintf (context, "%c %-40s %-40zu\r\n", (desc.type == FS_DIR ? 'D' : 'F'), entry.path,
desc.size); desc.size);
} }
@@ -450,17 +469,33 @@ static void ls (struct context* context, const char* path_string) {
static void quit1 (struct context* context) { static void quit1 (struct context* context) {
run = false; run = false;
cprintf (context, "Goodbye!\n"); cprintf (context, "Goodbye!\r\n");
} }
static void help (struct context* context) { static void help (struct context* context) {
cprintf (context, "Available commands:\n"); cprintf (context, "Available commands:\r\n");
cprintf (context, "echo <word1> <word2> <word3> ...\n"); cprintf (context, "echo <word1> <word2> <word3> ...\r\n");
cprintf (context, "help\n"); cprintf (context, "help\r\n");
cprintf (context, "cat <file path>\n"); cprintf (context, "cat <file path>\r\n");
cprintf (context, "ls <directory path>\n"); cprintf (context, "ls <directory path>\r\n");
cprintf (context, "mkfile <file path>\n"); cprintf (context, "mkfile <file path>\r\n");
cprintf (context, "quit\n"); cprintf (context, "quit\r\n");
}
static void cmd_cancel_proc (void) {
int pid = *(int*)argument_ptr ();
char ch = 0;
for (;;) {
mail_receive (&ch, 1);
if (ch == CTRL ('C'))
break;
}
kill (pid);
quit ();
} }
static void execute_cmd (struct ast_cmd* cmd, struct context* context) { static void execute_cmd (struct ast_cmd* cmd, struct context* context) {
@@ -477,7 +512,27 @@ static void execute_cmd (struct ast_cmd* cmd, struct context* context) {
} else if (strcmp (cmd->name, "mkfile") == 0) { } else if (strcmp (cmd->name, "mkfile") == 0) {
mkfile (context, cmd->args, cmd->arg_count); mkfile (context, cmd->args, cmd->arg_count);
} else { } else {
cprintf (context, "ERROR unknown command '%s'\n", cmd->name); /* cprintf (context, "ERROR unknown command '%s'\r\n", cmd->name); */
char volume[VOLUME_MAX];
const char* path;
if (!(path_parse (cmd->name, volume, &path))) {
cprintf (context, "ERROR bad path '%s'\r\n", cmd->name);
return;
}
int pid = exec (volume, path);
if (pid < 0) {
cprintf (context, "ERROR could not run '%s': %s\r\n", cmd->name, str_status[-pid]);
return;
}
int cancel_pid = process_spawn (&cmd_cancel_proc, &pid);
wait_for_pid (pid);
kill (cancel_pid);
} }
} }
@@ -487,12 +542,12 @@ static void execute_redir (struct ast_redir* redir, struct context* context) {
int ret; int ret;
if (!(path_parse (redir->file_path, volume, &path))) { if (!(path_parse (redir->file_path, volume, &path))) {
cprintf (context, "ERROR bad path '%s'\n", redir->file_path); cprintf (context, "ERROR bad path '%s'\r\n", redir->file_path);
return; return;
} }
if ((ret = volume_open (volume)) < 0) { if ((ret = volume_open (volume)) < 0) {
cprintf (context, "ERROR could not open volume '%s': %s\n", volume, str_status[-ret]); cprintf (context, "ERROR could not open volume '%s': %s\r\n", volume, str_status[-ret]);
return; return;
} }
@@ -543,7 +598,7 @@ void app_main (void) {
memset (line_buffer, 0, sizeof (line_buffer)); memset (line_buffer, 0, sizeof (line_buffer));
while (run) { while (run) {
printf (PROMPT); mprintf (PROMPT);
char ch = 0; char ch = 0;
for (;;) { for (;;) {
@@ -554,11 +609,11 @@ void app_main (void) {
if (line_cursor < LINE_BUFFER_MAX) { if (line_cursor < LINE_BUFFER_MAX) {
line_buffer[line_cursor++] = ch; line_buffer[line_cursor++] = ch;
printf ("%c", ch); mprintf ("%c", ch);
} }
} }
printf ("\n"); mprintf ("\r\n");
exec_line (line_buffer); exec_line (line_buffer);
line_cursor = 0; line_cursor = 0;

View File

@@ -25,5 +25,7 @@
#define SYS_READ_DIR_ENTRY 22 #define SYS_READ_DIR_ENTRY 22
#define SYS_CREATE_FILE 23 #define SYS_CREATE_FILE 23
#define SYS_WRITE_FILE 24 #define SYS_WRITE_FILE 24
#define SYS_WAIT_FOR_PID 25
#define SYS_KILL 26
#endif // _M_SYSCALL_DEFS_H #endif // _M_SYSCALL_DEFS_H

View File

@@ -6,16 +6,17 @@
#include <string.h> #include <string.h>
#include <terminal.h> #include <terminal.h>
#define RECV_MAX (1024 * 16)
static int ce_pgid; static int ce_pgid;
void receiver (void) { void receiver (void) {
for (;;) { for (;;) {
char rcv; char recv[RECV_MAX];
mail_receive (&rcv, 1); memset (recv, 0, sizeof (recv));
if (rcv == '\n') mail_receive (&recv, sizeof (recv) - 1);
terminal_print ("\r\n", 2);
else terminal_print (recv, strlen (recv));
terminal_print (&rcv, 1);
} }
} }

View File

@@ -56,8 +56,6 @@ void bootmain (void) {
devices_init (); devices_init ();
vfs_init (); vfs_init ();
struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false};
struct device* ramdisk = device_find ("RD"); struct device* ramdisk = device_find ("RD");
vfs_create_volume ("RD", VFS_TARFS, ramdisk, false); vfs_create_volume ("RD", VFS_TARFS, ramdisk, false);

View File

@@ -5,6 +5,7 @@
#include <amd64/io.h> #include <amd64/io.h>
#include <aux/compiler.h> #include <aux/compiler.h>
#include <irq/irq.h> #include <irq/irq.h>
#include <libk/lengthof.h>
#include <libk/std.h> #include <libk/std.h>
#include <libk/string.h> #include <libk/string.h>
#include <mm/liballoc.h> #include <mm/liballoc.h>
@@ -160,11 +161,19 @@ static void intr_exception (struct saved_regs* regs) {
regs->rbx); regs->rbx);
if (regs->cs == (GDT_UCODE | 0x03)) { if (regs->cs == (GDT_UCODE | 0x03)) {
struct reschedule_ctx rctx = {.reschedule = false, .cpu = NULL}; struct reschedule_ctx rctx = {0};
proc_kill (thiscpu->proc_current, &rctx); proc_kill (thiscpu->proc_current, &rctx);
if (rctx.reschedule) bool do_thiscpu = false;
cpu_request_sched (rctx.cpu); for (size_t i = 0; i < lengthof (rctx.cpus); i++) {
if (rctx.cpus[i] != NULL && rctx.cpus[i] != thiscpu)
cpu_request_sched (rctx.cpus[i]);
else
do_thiscpu = true;
}
if (do_thiscpu)
cpu_request_sched (thiscpu);
} else { } else {
__asm__ volatile ("cli"); __asm__ volatile ("cli");
spin (); spin ();
@@ -196,11 +205,19 @@ void intr_handler (void* stack_ptr) {
if (irq == NULL) if (irq == NULL)
return; return;
struct reschedule_ctx rctx = {.reschedule = false, .cpu = NULL}; struct reschedule_ctx rctx = {0};
irq->func (irq->arg, stack_ptr, &rctx); irq->func (irq->arg, stack_ptr, &rctx);
if (rctx.reschedule) bool do_thiscpu = false;
cpu_request_sched (rctx.cpu); for (size_t i = 0; i < lengthof (rctx.cpus); i++) {
if (rctx.cpus[i] != NULL && rctx.cpus[i] != thiscpu)
cpu_request_sched (rctx.cpus[i]);
else
do_thiscpu = true;
}
if (do_thiscpu)
cpu_request_sched (thiscpu);
} }
} }

View File

@@ -109,6 +109,26 @@ struct proc* proc_clone (struct proc* proto, uintptr_t vstack_top, uintptr_t ent
} }
void proc_cleanup (struct proc* proc, struct reschedule_ctx* rctx) { void proc_cleanup (struct proc* proc, struct reschedule_ctx* rctx) {
spin_lock (&proc->lock);
spin_lock (&proc->done_sq.lock);
while (proc->done_sq.proc_list != NULL) {
struct list_node_link* node = proc->done_sq.proc_list;
struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link);
struct proc* suspended_proc = sq_entry->proc;
spin_unlock (&proc->done_sq.lock);
spin_unlock (&proc->lock);
proc_sq_resume (suspended_proc, sq_entry, rctx);
spin_lock (&proc->lock);
spin_lock (&proc->done_sq.lock);
}
spin_unlock (&proc->done_sq.lock);
spin_unlock (&proc->lock);
proc_sqs_cleanup (proc); proc_sqs_cleanup (proc);
proc_mutexes_cleanup (proc, rctx); proc_mutexes_cleanup (proc, rctx);

View File

@@ -100,10 +100,10 @@ static void smp_bootstrap (struct limine_mp_info* mp_info) {
atomic_fetch_sub (&cpu_counter, 1); atomic_fetch_sub (&cpu_counter, 1);
struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false}; struct reschedule_ctx rctx = {0};
struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx); struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx);
proc_register (spin_proc, thiscpu, NULL); proc_register (spin_proc, thiscpu, &rctx);
spin_lock (&spin_proc->cpu->lock); spin_lock (&spin_proc->cpu->lock);
do_sched (spin_proc, &spin_proc->cpu->lock); do_sched (spin_proc, &spin_proc->cpu->lock);

View File

@@ -3,6 +3,7 @@
#include <amd64/mm.h> #include <amd64/mm.h>
#include <amd64/msr-index.h> #include <amd64/msr-index.h>
#include <amd64/msr.h> #include <amd64/msr.h>
#include <libk/lengthof.h>
#include <libk/list.h> #include <libk/list.h>
#include <libk/string.h> #include <libk/string.h>
#include <mm/liballoc.h> #include <mm/liballoc.h>
@@ -37,7 +38,7 @@ uintptr_t syscall_dispatch (void* stack_ptr) {
return -ST_SYSCALL_NOT_FOUND; return -ST_SYSCALL_NOT_FOUND;
} }
struct reschedule_ctx rctx = {.reschedule = false, .cpu = NULL}; struct reschedule_ctx rctx = {0};
uintptr_t r = uintptr_t r =
func (caller, regs, &rctx, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9); func (caller, regs, &rctx, regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9);
@@ -50,8 +51,16 @@ uintptr_t syscall_dispatch (void* stack_ptr) {
spin_unlock (&caller->lock); spin_unlock (&caller->lock);
} }
if (rctx.reschedule) bool do_thiscpu = false;
cpu_request_sched (rctx.cpu); for (size_t i = 0; i < lengthof (rctx.cpus); i++) {
if (rctx.cpus[i] != NULL && rctx.cpus[i] != thiscpu)
cpu_request_sched (rctx.cpus[i]);
else
do_thiscpu = true;
}
if (do_thiscpu)
cpu_request_sched (thiscpu);
return r; return r;
} }

View File

@@ -37,6 +37,8 @@ void proc_mutexes_cleanup (struct proc* proc, struct reschedule_ctx* rctx) {
proc_mutex_unlock (proc, &resource->u.mutex, rctx); proc_mutex_unlock (proc, &resource->u.mutex, rctx);
} }
spin_unlock (&resource->lock);
} }
spin_unlock (&proc->procgroup->lock); spin_unlock (&proc->procgroup->lock);

View File

@@ -198,10 +198,7 @@ void proc_register (struct proc* proc, struct cpu* register_cpu, struct reschedu
spin_unlock (&cpu->lock); spin_unlock (&cpu->lock);
spin_unlock (&proc_tree_lock); spin_unlock (&proc_tree_lock);
if (rctx != NULL) { rctx_insert_cpu (rctx, cpu);
rctx->reschedule = true;
rctx->cpu = cpu;
}
} }
/* caller holds cpu->lock */ /* caller holds cpu->lock */
@@ -225,11 +222,15 @@ static struct proc* proc_find_sched (struct cpu* cpu) {
struct proc* proc = list_entry (current, struct proc, cpu_run_q_link); struct proc* proc = list_entry (current, struct proc, cpu_run_q_link);
spin_lock (&proc->lock); spin_lock (&proc->lock);
int state = proc->state;
spin_unlock (&proc->lock);
if (state == PROC_READY) int state = proc->state;
if (state == PROC_READY) {
spin_unlock (&proc->lock);
return proc; return proc;
}
spin_unlock (&proc->lock);
current = current->next ? current->next : cpu->proc_run_q; current = current->next ? current->next : cpu->proc_run_q;
} while (current != start); } while (current != start);
@@ -278,7 +279,7 @@ static void proc_reap (struct reschedule_ctx* rctx) {
void proc_sched (void) { void proc_sched (void) {
int s_cycles = atomic_fetch_add (&sched_cycles, 1); int s_cycles = atomic_fetch_add (&sched_cycles, 1);
struct reschedule_ctx rctx = {.reschedule = false, .cpu = NULL}; struct reschedule_ctx rctx = {0};
if (s_cycles % SCHED_REAP_FREQ == 0) if (s_cycles % SCHED_REAP_FREQ == 0)
proc_reap (&rctx); proc_reap (&rctx);
@@ -321,14 +322,24 @@ void proc_kill (struct proc* proc, struct reschedule_ctx* rctx) {
spin_unlock (&proc->lock); spin_unlock (&proc->lock);
spin_unlock (&cpu->lock); spin_unlock (&cpu->lock);
rctx->reschedule = true; rctx_insert_cpu (rctx, cpu);
rctx->cpu = cpu;
DEBUG ("killed PID %d\n", proc->pid); DEBUG ("killed PID %d\n", proc->pid);
} }
void proc_wait_for (struct proc* proc, struct reschedule_ctx* rctx, struct proc* wait_proc) {
proc_sq_suspend (proc, &wait_proc->done_sq, NULL, rctx);
}
static void proc_irq_sched (void* arg, void* regs, struct reschedule_ctx* rctx) { static void proc_irq_sched (void* arg, void* regs, struct reschedule_ctx* rctx) {
(void)arg, (void)regs; (void)arg, (void)regs;
#if defined(__x86_64__)
struct saved_regs* sr = regs;
if (sr->cs != (GDT_UCODE | 0x3))
return;
#endif
proc_sched (); proc_sched ();
} }
@@ -338,14 +349,14 @@ void proc_init (void) {
irq_attach (&proc_irq_sched, NULL, CPU_REQUEST_SCHED); irq_attach (&proc_irq_sched, NULL, CPU_REQUEST_SCHED);
#endif #endif
struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false}; struct reschedule_ctx rctx = {0};
struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx); struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx);
proc_register (spin_proc, thiscpu, NULL); proc_register (spin_proc, thiscpu, &rctx);
struct proc* init = proc_from_file (VFS_KERNEL, "RD", "/init", &rctx); struct proc* init = proc_from_file (VFS_KERNEL, "RD", "/init", &rctx);
init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB); init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB);
proc_register (init, thiscpu, NULL); proc_register (init, thiscpu, &rctx);
spin_lock (&spin_proc->cpu->lock); spin_lock (&spin_proc->cpu->lock);
do_sched (spin_proc, &spin_proc->cpu->lock); do_sched (spin_proc, &spin_proc->cpu->lock);

View File

@@ -47,6 +47,7 @@ struct proc {
void* mail_recv_buffer; void* mail_recv_buffer;
size_t mail_recv_size; size_t mail_recv_size;
char cwv[VOLUME_MAX]; char cwv[VOLUME_MAX];
struct proc_suspension_q done_sq;
}; };
void proc_sched (void); void proc_sched (void);
@@ -68,6 +69,8 @@ int proc_alloc_pid (void);
void proc_pid_alloc_init (void); void proc_pid_alloc_init (void);
void proc_wait_for (struct proc* proc, struct reschedule_ctx* rctx, struct proc* wait_proc);
void proc_init (void); void proc_init (void);
#endif // _KERNEL_PROC_PROC_H #endif // _KERNEL_PROC_PROC_H

View File

@@ -6,8 +6,24 @@
#include <sys/smp.h> #include <sys/smp.h>
struct reschedule_ctx { struct reschedule_ctx {
bool reschedule; struct cpu* cpus[CPUS_MAX];
struct cpu* cpu;
}; };
#define rctx_insert_cpu(rctx, cpu) \
do { \
bool __found = false; \
for (size_t __i = 0; __i < CPUS_MAX; __i++) { \
if ((rctx)->cpus[__i] == (cpu)) \
__found = true; \
} \
if (!__found) { \
for (size_t __i = 0; __i < CPUS_MAX; __i++) { \
if ((rctx)->cpus[__i] == NULL) { \
(rctx)->cpus[__i] = (cpu); \
break; \
} \
} \
} \
} while (0)
#endif // _KERNEL_PROC_RESCHEDULE_H #endif // _KERNEL_PROC_RESCHEDULE_H

View File

@@ -15,7 +15,8 @@ void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock
struct proc_sq_entry* sq_entry = malloc (sizeof (*sq_entry)); struct proc_sq_entry* sq_entry = malloc (sizeof (*sq_entry));
if (!sq_entry) { if (!sq_entry) {
spin_unlock (resource_lock); if (resource_lock != NULL)
spin_unlock (resource_lock);
return; return;
} }
@@ -26,7 +27,8 @@ void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock
spin_lock (&proc->lock); spin_lock (&proc->lock);
spin_lock (&sq->lock); spin_lock (&sq->lock);
spin_unlock (resource_lock); if (resource_lock != NULL)
spin_unlock (resource_lock);
proc->state = PROC_SUSPENDED; proc->state = PROC_SUSPENDED;
@@ -48,8 +50,7 @@ void proc_sq_suspend (struct proc* proc, struct proc_suspension_q* sq, spin_lock
spin_unlock (&proc->lock); spin_unlock (&proc->lock);
spin_unlock (&cpu->lock); spin_unlock (&cpu->lock);
rctx->reschedule = true; rctx_insert_cpu (rctx, cpu);
rctx->cpu = cpu;
} }
void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry, void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
@@ -81,8 +82,7 @@ void proc_sq_resume (struct proc* proc, struct proc_sq_entry* sq_entry,
free (sq_entry); free (sq_entry);
rctx->reschedule = true; rctx_insert_cpu (rctx, cpu);
rctx->cpu = cpu;
} }
void proc_sqs_cleanup (struct proc* proc) { void proc_sqs_cleanup (struct proc* proc) {

View File

@@ -105,12 +105,17 @@ DEFINE_SYSCALL (sys_clone) {
} }
/* void* argument_ptr (void) */ /* void* argument_ptr (void) */
DEFINE_SYSCALL (sys_argument_ptr) { return proc->uvaddr_argument; } DEFINE_SYSCALL (sys_argument_ptr) {
spin_lock (&proc->lock);
uintptr_t p = proc->uvaddr_argument;
spin_unlock (&proc->lock);
return p;
}
/* int sched (void) */ /* int sched (void) */
DEFINE_SYSCALL (sys_sched) { DEFINE_SYSCALL (sys_sched) {
rctx->reschedule = true; rctx_insert_cpu (rctx, thiscpu);
rctx->cpu = thiscpu;
return SYSRESULT (ST_OK); return SYSRESULT (ST_OK);
} }
@@ -121,7 +126,11 @@ DEFINE_SYSCALL (sys_mutex_create) {
if (mutex_resource == NULL) if (mutex_resource == NULL)
return SYSRESULT (-ST_OOM_ERROR); return SYSRESULT (-ST_OOM_ERROR);
return SYSRESULT (mutex_resource->rid); spin_lock (&mutex_resource->lock);
int rid = mutex_resource->rid;
spin_unlock (&mutex_resource->lock);
return SYSRESULT (rid);
} }
/* int mutex_delete (int mutex_rid) */ /* int mutex_delete (int mutex_rid) */
@@ -425,7 +434,18 @@ DEFINE_SYSCALL (sys_get_procgroup) {
if (target_proc == NULL) if (target_proc == NULL)
return SYSRESULT (-ST_NOT_FOUND); return SYSRESULT (-ST_NOT_FOUND);
return SYSRESULT (target_proc->procgroup->pgid); spin_lock (&target_proc->lock);
if (target_proc->state == PROC_DEAD) {
spin_unlock (&target_proc->lock);
return SYSRESULT (-ST_NOT_FOUND);
}
int pgid = target_proc->procgroup->pgid;
spin_unlock (&target_proc->lock);
return SYSRESULT (pgid);
} }
/* int read_dir_entry (char* path, struct dir_entry* entry, size_t entry_num) */ /* int read_dir_entry (char* path, struct dir_entry* entry, size_t entry_num) */
@@ -516,7 +536,60 @@ DEFINE_SYSCALL (sys_write_file) {
} }
/* int get_exec_pid (void) */ /* int get_exec_pid (void) */
DEFINE_SYSCALL (sys_get_exec_pid) { return SYSRESULT (proc->exec_pid); } DEFINE_SYSCALL (sys_get_exec_pid) {
spin_lock (&proc->lock);
int exec_pid = proc->exec_pid;
spin_unlock (&proc->lock);
return SYSRESULT (exec_pid);
}
/* wait_for_pid (int pid) */
DEFINE_SYSCALL (sys_wait_for_pid) {
int pid = (int)a1;
struct proc* wait_proc = proc_find_pid (pid);
if (wait_proc == NULL)
return SYSRESULT (-ST_NOT_FOUND);
spin_lock (&wait_proc->lock);
if (wait_proc->state == PROC_DEAD) {
spin_unlock (&wait_proc->lock);
return SYSRESULT (-ST_NOT_FOUND);
}
spin_unlock (&wait_proc->lock);
proc_wait_for (proc, rctx, wait_proc);
return SYSRESULT (ST_OK);
}
/* int kill (int pid) */
DEFINE_SYSCALL (sys_kill) {
int pid = (int)a1;
struct proc* target_proc = proc_find_pid (pid);
if (target_proc == NULL)
return SYSRESULT (-ST_NOT_FOUND);
spin_lock (&target_proc->lock);
if (target_proc->state == PROC_DEAD) {
spin_unlock (&target_proc->lock);
return SYSRESULT (-ST_NOT_FOUND);
}
spin_unlock (&target_proc->lock);
proc_kill (target_proc, rctx);
return ST_OK;
}
static syscall_handler_func_t handler_table[] = { static syscall_handler_func_t handler_table[] = {
[SYS_QUIT] = &sys_quit, [SYS_QUIT] = &sys_quit,
@@ -543,6 +616,8 @@ static syscall_handler_func_t handler_table[] = {
[SYS_READ_DIR_ENTRY] = &sys_read_dir_entry, [SYS_READ_DIR_ENTRY] = &sys_read_dir_entry,
[SYS_CREATE_FILE] = &sys_create_file, [SYS_CREATE_FILE] = &sys_create_file,
[SYS_WRITE_FILE] = &sys_write_file, [SYS_WRITE_FILE] = &sys_write_file,
[SYS_WAIT_FOR_PID] = &sys_wait_for_pid,
[SYS_KILL] = &sys_kill,
}; };
syscall_handler_func_t syscall_find_handler (int syscall_num) { syscall_handler_func_t syscall_find_handler (int syscall_num) {

View File

@@ -74,3 +74,7 @@ int create_file (const char* path) { return (int)do_syscall (SYS_CREATE_FILE, pa
int write_file (const char* path, size_t off, uint8_t* buffer, size_t size) { int write_file (const char* path, size_t off, uint8_t* buffer, size_t size) {
return (int)do_syscall (SYS_WRITE_FILE, path, off, buffer, size); return (int)do_syscall (SYS_WRITE_FILE, path, off, buffer, size);
} }
int wait_for_pid (int pid) { return (int)do_syscall (SYS_WAIT_FOR_PID, pid); }
int kill (int pid) { return (int)do_syscall (SYS_KILL, pid); }

View File

@@ -87,4 +87,10 @@ int create_file (const char* path);
/* write to a file */ /* write to a file */
int write_file (const char* path, size_t off, uint8_t* buffer, size_t size); int write_file (const char* path, size_t off, uint8_t* buffer, size_t size);
/* wait for process */
int wait_for_pid (int pid);
/* Kill process */
int kill (int pid);
#endif // _LIBMSL_M_SYSTEM_H #endif // _LIBMSL_M_SYSTEM_H