feature (processes): implemented signals and the 'nx_psignal' syscall

This commit is contained in:
antifallobst 2023-05-07 01:16:33 +02:00
parent c0e1b688a4
commit caacc16f35
4 changed files with 60 additions and 1 deletions

View File

@ -28,6 +28,13 @@ typedef enum {
PROCESS_BLOCK_ENUM_SIZE PROCESS_BLOCK_ENUM_SIZE
} process_blockers_E; } process_blockers_E;
typedef enum {
PROCESS_SIGNAL_START, // SIGSTART
PROCESS_SIGNAL_PAUSE, // SIGPAUSE
PROCESS_SIGNAL_KILL, // SIGKILL
PROCESS_SIGNAL_PFAULT, // SIGPFAULT
} process_signals_E;
typedef struct process_T process_T; typedef struct process_T process_T;
struct process_T { struct process_T {
char name [128]; char name [128];
@ -57,6 +64,8 @@ struct process_T {
void process_kernel_spawn (elf_executable_T* executable); void process_kernel_spawn (elf_executable_T* executable);
pid_t process_spawn (pid_t parent, string_t name, elf_executable_T* executable, void* buffer); pid_t process_spawn (pid_t parent, string_t name, elf_executable_T* executable, void* buffer);
void process_signal (process_T* process, process_signals_E signal);
bool process_is_child_of (process_T* process, process_T* parent);
int32_t process_get_thread_id (process_T* process); int32_t process_get_thread_id (process_T* process);
void process_clear_thread_id (process_T* process, uint32_t id); void process_clear_thread_id (process_T* process, uint32_t id);
void process_pause_pid (pid_t pid); void process_pause_pid (pid_t pid);

View File

@ -69,12 +69,13 @@ void kmain(boot_info_T boot_info) {
syscall_perform(SYSCALL_PROCESS_CREATE, (uint64_t)"/initrd/shell.elf", 0, (uint64_t)&pid, 0); syscall_perform(SYSCALL_PROCESS_CREATE, (uint64_t)"/initrd/shell.elf", 0, (uint64_t)&pid, 0);
process_T* process = scheduler_get_process(pid); process_T* process = scheduler_get_process(pid);
thread_start(process->threads);
scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0); scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0);
g_tty->output = &process->stdin; g_tty->output = &process->stdin;
process->stdout = &g_tty->input; process->stdout = &g_tty->input;
syscall_perform(SYSCALL_PROCESS_SIGNAL, pid, PROCESS_SIGNAL_START, 0, 0);
CORE_HALT_FOREVER CORE_HALT_FOREVER
} }

View File

@ -245,6 +245,24 @@ void syscall_handle_nx_pcreate(cpu_state_T* state) {
state->rax = STATUS_SUCCESS; state->rax = STATUS_SUCCESS;
} }
void syscall_handle_nx_psignal(cpu_state_T* state) {
pid_t pid = (pid_t)state->rdi; // arg1
uint64_t signal = state->rsi; // arg2
if (pid == PROCESS_NONE) {
state->rax = STATUS_RESOURCE_NOT_AVAILABLE;
return;
}
process_T* process = scheduler_get_process(pid);
if (!process_is_child_of(process, scheduler_get_current_process())) {
state->rax = STATUS_PERMISSION_DENIED;
return;
}
process_signal(scheduler_get_process(pid), signal);
state->rax = STATUS_SUCCESS;
}
cpu_state_T* syscall_handle(cpu_state_T* state) { cpu_state_T* syscall_handle(cpu_state_T* state) {
cpu_state_T* return_state = state; cpu_state_T* return_state = state;
@ -303,6 +321,10 @@ cpu_state_T* syscall_handle(cpu_state_T* state) {
syscall_handle_nx_pcreate(state); syscall_handle_nx_pcreate(state);
break; break;
} }
case SYSCALL_PROCESS_SIGNAL: {
syscall_handle_nx_psignal(state);
break;
}
} }
break; break;
} }

View File

@ -52,6 +52,33 @@ pid_t process_spawn(pid_t parent, string_t name, elf_executable_T* executable, v
return scheduler_register_process(process); return scheduler_register_process(process);
} }
void process_signal(process_T* process, process_signals_E signal) {
switch (signal) {
case PROCESS_SIGNAL_START: {
process_start(process);
break;
}
case PROCESS_SIGNAL_PAUSE: {
process_pause(process);
break;
}
case PROCESS_SIGNAL_KILL: {
process_kill(process);
break;
}
default: break;
}
}
bool process_is_child_of(process_T* process, process_T* parent) {
process_T* tmp = process->parent;
while (tmp != NULL) {
if (tmp == parent) return true;
tmp = tmp->parent;
}
return false;
}
int32_t process_get_thread_id(process_T* process) { int32_t process_get_thread_id(process_T* process) {
for (int i = 0; i < MAX_THREADS_PER_PROCESS; i++) { for (int i = 0; i < MAX_THREADS_PER_PROCESS; i++) {
if (!bitmap_get(&process->thread_ids, i)) { if (!bitmap_get(&process->thread_ids, i)) {