feature (processes): implemented signals and the 'nx_psignal' syscall
This commit is contained in:
parent
c0e1b688a4
commit
caacc16f35
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in New Issue