wip: thread and processes handle
This commit is contained in:
11
headers/assert.h
Normal file
11
headers/assert.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "kpanic.h"
|
||||
|
||||
#define assert(X) \
|
||||
do { \
|
||||
if (!(X)) { \
|
||||
kpanic("ASSERT_FAIL %s:%u %s\n", __FILE__, __LINE__, \
|
||||
#X); \
|
||||
} \
|
||||
} while (0)
|
||||
@ -9,13 +9,6 @@
|
||||
#define PRINT_STR(X) kprintf("%s:%u %s: %s\n", __FILE__, __LINE__, #X, X)
|
||||
#define PRINT_UINT(X) kprintf("%s:%u %s: %u\n", __FILE__, __LINE__, #X, X)
|
||||
#define PRINT_INT(X) kprintf("%s:%u %s: %d\n", __FILE__, __LINE__, #X, X)
|
||||
#define assert(X) \
|
||||
do { \
|
||||
if (!(X)) { \
|
||||
kpanic("ASSERT_FAIL %s:%u %s\n", __FILE__, __LINE__, \
|
||||
#X); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct function_entry {
|
||||
uint32_t addr;
|
||||
|
||||
25
headers/process.h
Normal file
25
headers/process.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "signal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern struct pcb *current_pcb;
|
||||
|
||||
enum owner { OWNER_KERNEL, OWNER_USER };
|
||||
|
||||
struct pcb {
|
||||
void *cr3;
|
||||
uint32_t *heap;
|
||||
uint16_t pid;
|
||||
uint8_t uid;
|
||||
struct signal_data signals;
|
||||
struct pcb *next;
|
||||
struct pcb *prev;
|
||||
struct tcb *thread_list;
|
||||
};
|
||||
|
||||
void switch_process(struct pcb *next_pcb);
|
||||
struct pcb *create_process(uint8_t uid);
|
||||
int8_t create_kernel_process(void);
|
||||
void remove_process(struct pcb *pcb);
|
||||
3
headers/scheduler.h
Normal file
3
headers/scheduler.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void scheduler(void);
|
||||
@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "list.h"
|
||||
#include "memory.h"
|
||||
#include "signal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern struct task *current_task;
|
||||
|
||||
enum status { ZOMBIE, THREAD, RUN, WAIT, SLEEP, STOPPED, FORKED };
|
||||
enum owner { OWNER_KERNEL, OWNER_USER };
|
||||
|
||||
#define STACK_SIZE PAGE_SIZE * 4
|
||||
|
||||
struct task {
|
||||
uint8_t *esp;
|
||||
uint8_t *esp0;
|
||||
uint32_t *cr3; // physical
|
||||
uint32_t *heap; // virtual
|
||||
uint32_t *eip;
|
||||
uint16_t pid;
|
||||
uint8_t status;
|
||||
uint8_t uid;
|
||||
struct task *daddy;
|
||||
struct task *child;
|
||||
struct signal_data signals;
|
||||
struct task *next;
|
||||
struct task *prev;
|
||||
};
|
||||
|
||||
void scheduler(void);
|
||||
void switch_to_task(struct task *next_task);
|
||||
struct task *create_task(uint8_t uid);
|
||||
int8_t create_kernel_task(void);
|
||||
void remove_task(struct task *task);
|
||||
struct task *copy_task(const struct task *task);
|
||||
void kfork(struct task *daddy);
|
||||
void zombify_task(struct task *task);
|
||||
|
||||
// utils
|
||||
void exec_fn(void (*fn)(void));
|
||||
uint16_t fork(void);
|
||||
uint16_t wait(void);
|
||||
27
headers/thread.h
Normal file
27
headers/thread.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "process.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define STACK_SIZE PAGE_SIZE * 4
|
||||
|
||||
typedef enum {
|
||||
NEW,
|
||||
RUNNING,
|
||||
WAITING,
|
||||
STOPPED,
|
||||
} state_t;
|
||||
|
||||
struct tcb {
|
||||
uint8_t *esp;
|
||||
uint8_t *esp0;
|
||||
uint16_t tid;
|
||||
state_t state;
|
||||
struct pcb *process;
|
||||
struct tcb *next;
|
||||
};
|
||||
|
||||
struct tcb *create_thread(struct pcb *process, void (*routine)(void));
|
||||
void delete_thread(struct tcb *thread);
|
||||
void switch_thread(struct tcb *thread_to_switch);
|
||||
@ -5,8 +5,9 @@
|
||||
#include "interrupts.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "process.h"
|
||||
#include "scheduler.h"
|
||||
#include "sys/io.h"
|
||||
#include "task.h"
|
||||
|
||||
#define PIT_CHANNEL0 0x40
|
||||
#define PIT_FREQUENCY 1193182
|
||||
|
||||
@ -38,7 +38,6 @@ irq_common_stub:
|
||||
iret
|
||||
|
||||
irq0:
|
||||
mov [esp_backup], esp
|
||||
push 0
|
||||
push 32
|
||||
jmp irq_common_stub
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
#include "memory.h"
|
||||
#include "multiboot.h"
|
||||
#include "power.h"
|
||||
#include "process.h"
|
||||
#include "shell.h"
|
||||
#include "string.h"
|
||||
#include "task.h"
|
||||
#include "terminal.h"
|
||||
#include "time.h"
|
||||
#include "vbe.h"
|
||||
@ -43,9 +43,9 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic)
|
||||
init_memory(mbd, magic);
|
||||
load_drivers();
|
||||
terminal_initialize();
|
||||
create_kernel_task();
|
||||
create_kernel_process();
|
||||
signal(4, bozo);
|
||||
kill(0, 4);
|
||||
create_task(42);
|
||||
// create_process(42);
|
||||
shell_init();
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "assert.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "string.h"
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "assert.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "string.h"
|
||||
#include "task.h"
|
||||
#include "process.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "debug.h"
|
||||
#include "assert.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
void init_page_table(uint32_t page_table[1024], uint16_t start)
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "assert.h"
|
||||
#include "kpanic.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "task.h"
|
||||
#include "process.h"
|
||||
|
||||
Zone *kzones[3];
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "assert.h"
|
||||
#include "kprintf.h"
|
||||
#include "terminal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "assert.h"
|
||||
#include "kpanic.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "task.h"
|
||||
#include "process.h"
|
||||
|
||||
Zone *vzones[3];
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "assert.h"
|
||||
#include "kprintf.h"
|
||||
#include "terminal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
#include "interrupts.h"
|
||||
#include "kprintf.h"
|
||||
#include "task.h"
|
||||
|
||||
uint16_t fork(void)
|
||||
{
|
||||
current_task->status = FORKED;
|
||||
scheduler();
|
||||
return current_task->child ? current_task->child->pid : 0;
|
||||
}
|
||||
|
||||
void kfork(struct task *daddy)
|
||||
{
|
||||
cli();
|
||||
struct task *child = copy_task(daddy);
|
||||
if (!child) {
|
||||
kprintf(KERN_ALERT "Fork failed ! retry at the next loop");
|
||||
toris();
|
||||
return;
|
||||
}
|
||||
child->daddy = daddy;
|
||||
daddy->child = child;
|
||||
daddy->status = RUN;
|
||||
child->status = RUN;
|
||||
toris();
|
||||
}
|
||||
57
src/multitasking/process.c
Normal file
57
src/multitasking/process.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include "process.h"
|
||||
#include "alloc.h"
|
||||
#include "interrupts.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "string.h"
|
||||
|
||||
int8_t create_kernel_process(void)
|
||||
{
|
||||
struct pcb *new_pcb = vmalloc(sizeof(struct pcb));
|
||||
if (!new_pcb)
|
||||
return -1;
|
||||
new_pcb->pid = 0;
|
||||
new_pcb->uid = 0;
|
||||
new_pcb->heap = kernel_pd;
|
||||
new_pcb->cr3 = (uint32_t *)((uint32_t)kernel_pd - HEAP_END);
|
||||
new_pcb->next = new_pcb;
|
||||
new_pcb->prev = new_pcb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pcb *create_process(uint8_t uid)
|
||||
{
|
||||
static uint32_t pid = 1;
|
||||
struct pcb *new_pcb = vmalloc(sizeof(struct pcb));
|
||||
if (!new_pcb)
|
||||
return NULL;
|
||||
new_pcb->uid = uid;
|
||||
new_pcb->pid = pid++;
|
||||
|
||||
new_pcb->heap = alloc_pages(4096, &new_pcb->cr3);
|
||||
if (!new_pcb->heap) {
|
||||
vfree(new_pcb);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(new_pcb->heap, current_pcb->heap, 4096);
|
||||
new_pcb->next = current_pcb->next;
|
||||
new_pcb->prev = current_pcb;
|
||||
current_pcb->next = new_pcb;
|
||||
if (current_pcb->prev == current_pcb)
|
||||
current_pcb->prev = new_pcb;
|
||||
|
||||
new_pcb->signals.pending = SIG_IGN;
|
||||
|
||||
return new_pcb;
|
||||
}
|
||||
|
||||
void remove_pcb(struct pcb *pcb)
|
||||
{
|
||||
struct pcb *left = pcb->prev;
|
||||
struct pcb *right = pcb->next;
|
||||
if (pcb->heap)
|
||||
free_pages(pcb->heap, 4096);
|
||||
left->next = right;
|
||||
right->prev = left;
|
||||
vfree(pcb);
|
||||
}
|
||||
@ -2,34 +2,28 @@
|
||||
#include "debug.h"
|
||||
#include "interrupts.h"
|
||||
#include "kprintf.h"
|
||||
#include "task.h"
|
||||
#include "process.h"
|
||||
#include "thread.h"
|
||||
#include "time.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct task *current_task;
|
||||
struct pcb *current_pcb;
|
||||
struct tcb *current_tcb;
|
||||
|
||||
void scheduler(void)
|
||||
{
|
||||
// ZOMBIE, THREAD, RUN, WAIT, SLEEP, STOPPED, FORKED
|
||||
void (*func[])(struct task *) = {
|
||||
zombify_task, NULL, NULL, NULL, NULL, remove_task, kfork,
|
||||
};
|
||||
|
||||
if (!current_task) // || current_task->next == current_task)
|
||||
return;
|
||||
cli();
|
||||
switch_pd(kernel_pd, (uint32_t *)((uint32_t)kernel_pd - HEAP_END));
|
||||
struct task *it = current_task->next;
|
||||
while (it && it->status != RUN) {
|
||||
if (it != current_task && func[it->status]) {
|
||||
struct task *new_it = it->prev;
|
||||
func[it->status](it);
|
||||
it = new_it;
|
||||
struct tcb *thread_to_switch;
|
||||
if (!current_tcb) {
|
||||
thread_to_switch = current_pcb->thread_list;
|
||||
} else {
|
||||
if (!current_tcb->next) {
|
||||
current_pcb = current_pcb->next;
|
||||
// TODO switch context
|
||||
thread_to_switch = current_pcb->thread_list;
|
||||
} else {
|
||||
thread_to_switch = current_tcb->next;
|
||||
}
|
||||
it = it->next;
|
||||
}
|
||||
switch_to_task(it);
|
||||
exec_signal_pending();
|
||||
toris();
|
||||
switch_thread(thread_to_switch);
|
||||
}
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.section .text
|
||||
.global switch_to_task
|
||||
|
||||
switch_to_task:
|
||||
push ebx
|
||||
push ebp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov eax, [current_task]
|
||||
|
||||
// save the current stack pointer to the old stack
|
||||
mov [eax+0], esp
|
||||
|
||||
// stack pointer + the 4 regs pushed
|
||||
// and + 1 to get the argument (next task)
|
||||
mov esi, [esp+(4+1)*4]
|
||||
mov [current_task], esi
|
||||
|
||||
mov eax, [current_task]
|
||||
|
||||
mov esp, [eax+0] // get esp
|
||||
|
||||
mov ecx, [eax+12] // get task's pd
|
||||
mov [current_pd], ecx
|
||||
mov ecx, [eax+8]
|
||||
mov cr3, ecx
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
pop ebx
|
||||
|
||||
|
||||
mov ecx, 0
|
||||
|
||||
cmp [eax+16], ecx
|
||||
je .END
|
||||
|
||||
sti
|
||||
|
||||
push [eax+16] // store func_ptr
|
||||
|
||||
mov [eax+16], ecx // clear eip in current_task
|
||||
|
||||
push 0
|
||||
call pic_send_eoi
|
||||
pop edx // remove pic_send_eoi argument
|
||||
|
||||
pop edx // get func_ptr
|
||||
call edx
|
||||
|
||||
call exit_task
|
||||
|
||||
.END:
|
||||
ret
|
||||
31
src/multitasking/switch_to_thread.s
Normal file
31
src/multitasking/switch_to_thread.s
Normal file
@ -0,0 +1,31 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.section .text
|
||||
.global switch_thread
|
||||
|
||||
switch_thread:
|
||||
push ebx
|
||||
push ebp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov eax, [current_tcb]
|
||||
|
||||
// save the current stack pointer to the old stack
|
||||
mov [eax+0], esp
|
||||
|
||||
// stack pointer + the 4 regs pushed
|
||||
// and + 1 to get the argument (next thread)
|
||||
mov esi, [esp+(4+1)*4]
|
||||
mov [current_tcb], esi
|
||||
|
||||
mov eax, [current_tcb]
|
||||
|
||||
mov esp, [eax+0] // get esp
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
pop ebx
|
||||
|
||||
iret
|
||||
@ -1,140 +0,0 @@
|
||||
#include "task.h"
|
||||
#include "alloc.h"
|
||||
#include "debug.h"
|
||||
#include "interrupts.h"
|
||||
#include "kpanic.h"
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "string.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t esp_backup;
|
||||
|
||||
struct task *create_task(uint8_t uid)
|
||||
{
|
||||
static uint32_t pid = 1;
|
||||
switch_pd(kernel_pd, (uint32_t *)((uint32_t)kernel_pd - HEAP_END));
|
||||
struct task *new_task = vmalloc(sizeof(struct task));
|
||||
if (!new_task) {
|
||||
switch_pd(current_task->heap, current_task->cr3);
|
||||
return NULL;
|
||||
}
|
||||
switch_pd(current_task->heap, current_task->cr3);
|
||||
new_task->status = RUN;
|
||||
new_task->uid = uid;
|
||||
new_task->esp = new_task->esp0 + STACK_SIZE;
|
||||
new_task->pid = pid++;
|
||||
|
||||
// Allocate new pd
|
||||
new_task->heap = alloc_pages(4096, (void **)&new_task->cr3);
|
||||
if (!new_task->heap) {
|
||||
vfree(new_task);
|
||||
return NULL;
|
||||
}
|
||||
new_task->heap[768] = ((uint32_t)boot_page_table1 - HEAP_END) | 0x03;
|
||||
// memcpy(new_task->heap, current_task->heap, 4096);
|
||||
current_pd = new_task->heap;
|
||||
// switch_pd(new_task->heap, new_task->cr3);
|
||||
|
||||
// Allocate new stack on the newly allocated pd
|
||||
new_task->esp0 = alloc_pages(STACK_SIZE, NULL);
|
||||
current_pd = kernel_pd;
|
||||
// switch_pd(current_task->heap, current_task->cr3);
|
||||
if (!new_task->esp0) {
|
||||
vfree(new_task);
|
||||
free_pages(new_task->heap, 4096);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_task->next = current_task->next;
|
||||
new_task->prev = current_task;
|
||||
current_task->next = new_task;
|
||||
if (current_task->prev == current_task)
|
||||
current_task->prev = new_task;
|
||||
|
||||
new_task->signals.pending = SIG_IGN;
|
||||
|
||||
return new_task;
|
||||
}
|
||||
|
||||
int8_t create_kernel_task(void)
|
||||
{
|
||||
struct task *new_task = vmalloc(sizeof(struct task));
|
||||
if (!new_task)
|
||||
return -1;
|
||||
new_task->status = RUN;
|
||||
new_task->uid = 0;
|
||||
new_task->pid = 0;
|
||||
new_task->heap = kernel_pd;
|
||||
new_task->cr3 = (uint32_t *)((uint32_t)kernel_pd - HEAP_END);
|
||||
new_task->prev = new_task;
|
||||
new_task->next = new_task;
|
||||
new_task->signals.pending = SIG_IGN;
|
||||
current_task = new_task;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void exec_fn(void (*fn)(void))
|
||||
{
|
||||
struct task *new_task = create_task(OWNER_KERNEL);
|
||||
if (!new_task)
|
||||
kpanic("failed to create new task");
|
||||
new_task->eip = (uint32_t *)fn;
|
||||
}
|
||||
|
||||
void zombify_task(struct task *task)
|
||||
{
|
||||
cli(); // Technically useless
|
||||
free_pages(task->heap, 4096);
|
||||
free_pages(task->esp0, STACK_SIZE);
|
||||
task->esp0 = NULL;
|
||||
task->heap = NULL;
|
||||
toris();
|
||||
}
|
||||
|
||||
void remove_task(struct task *task)
|
||||
{
|
||||
cli();
|
||||
struct task *left = task->prev;
|
||||
struct task *right = task->next;
|
||||
|
||||
if (task->child) {
|
||||
remove_task(task->child);
|
||||
task->child = NULL;
|
||||
}
|
||||
if (task->heap)
|
||||
free_pages(task->heap, 4096);
|
||||
if (task->esp0)
|
||||
free_pages(task->esp0, STACK_SIZE);
|
||||
left->next = right;
|
||||
right->prev = left;
|
||||
vfree(task);
|
||||
toris();
|
||||
}
|
||||
|
||||
struct task *copy_task(const struct task *task)
|
||||
{
|
||||
struct task *new_task = create_task(task->uid);
|
||||
if (!new_task)
|
||||
return NULL;
|
||||
memcpy(new_task->esp0, task->esp0, STACK_SIZE);
|
||||
new_task->esp = new_task->esp0 + (task->esp - task->esp0);
|
||||
new_task->status = task->status;
|
||||
return new_task;
|
||||
}
|
||||
|
||||
void exit_task(void)
|
||||
{
|
||||
cli();
|
||||
if (current_task->daddy && current_task->daddy->status != WAIT)
|
||||
current_task->status = ZOMBIE;
|
||||
else {
|
||||
if (current_task->daddy->status == WAIT)
|
||||
current_task->daddy->status = RUN;
|
||||
current_task->status = STOPPED;
|
||||
}
|
||||
toris();
|
||||
scheduler();
|
||||
}
|
||||
47
src/multitasking/thread.c
Normal file
47
src/multitasking/thread.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include "thread.h"
|
||||
#include "alloc.h"
|
||||
#include "assert.h"
|
||||
#include "interrupts.h"
|
||||
#include "memory.h"
|
||||
#include "string.h"
|
||||
#include "thread.h"
|
||||
|
||||
struct tcb *create_thread(struct pcb *process, void (*routine)(void))
|
||||
{
|
||||
static uint32_t tid = 1;
|
||||
struct tcb *new_tcb = vmalloc(sizeof(struct tcb));
|
||||
if (!new_tcb)
|
||||
return NULL;
|
||||
new_tcb->tid = tid++;
|
||||
|
||||
new_tcb->esp0 = alloc_pages(STACK_SIZE, NULL);
|
||||
if (!new_tcb->esp0) {
|
||||
vfree(new_tcb);
|
||||
return NULL;
|
||||
}
|
||||
// set esp to "skip" the 4 GPRs and eip later to be used as the context
|
||||
// of the thread
|
||||
new_tcb->esp = new_tcb->esp0 + STACK_SIZE - 5 * 4;
|
||||
memcpy(new_tcb->esp + 4, routine, 4);
|
||||
new_tcb->process = process;
|
||||
new_tcb->next = NULL;
|
||||
new_tcb->state = NEW;
|
||||
|
||||
struct tcb *it = process->thread_list;
|
||||
while (it)
|
||||
it = it->next;
|
||||
it = new_tcb;
|
||||
|
||||
return new_tcb;
|
||||
}
|
||||
|
||||
void delete_thread(struct tcb *thread)
|
||||
{
|
||||
vfree(thread->esp0);
|
||||
struct tcb *it = thread->process->thread_list;
|
||||
assert(it);
|
||||
while (it->next != thread)
|
||||
it = it->next;
|
||||
it->next = it->next->next;
|
||||
vfree(thread);
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
#include "interrupts.h"
|
||||
#include "task.h"
|
||||
|
||||
uint16_t wait(void)
|
||||
{
|
||||
if (current_task->child == NULL)
|
||||
return -1;
|
||||
cli();
|
||||
if (current_task->child->status == ZOMBIE)
|
||||
current_task->child->status = STOPPED;
|
||||
else
|
||||
current_task->status = WAIT;
|
||||
uint16_t child_pid = current_task->child->pid;
|
||||
toris();
|
||||
scheduler();
|
||||
return child_pid;
|
||||
}
|
||||
@ -1,21 +1,21 @@
|
||||
#include "signal.h"
|
||||
#include "kprintf.h"
|
||||
#include "task.h"
|
||||
#include "process.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void signal(SIGNAL_CODE sig_num, void *handler)
|
||||
{
|
||||
current_task->signals.handlers[sig_num] = handler;
|
||||
current_pcb->signals.handlers[sig_num] = handler;
|
||||
}
|
||||
|
||||
void kill(int pid, SIGNAL_CODE sig_num)
|
||||
{
|
||||
struct task *task = current_task;
|
||||
struct pcb *pcb = current_pcb;
|
||||
|
||||
while (task->pid != pid)
|
||||
task = task->next;
|
||||
while (pcb->pid != pid)
|
||||
pcb = pcb->next;
|
||||
|
||||
task->signals.pending = sig_num;
|
||||
pcb->signals.pending = sig_num;
|
||||
}
|
||||
|
||||
static void display_signal(SIGNAL_CODE sig_num)
|
||||
@ -25,12 +25,12 @@ static void display_signal(SIGNAL_CODE sig_num)
|
||||
|
||||
static void exec_signal(SIGNAL_CODE sig_num)
|
||||
{
|
||||
void *handler = current_task->signals.handlers[sig_num];
|
||||
void *handler = current_pcb->signals.handlers[sig_num];
|
||||
|
||||
if (handler == SIG_IGN)
|
||||
if ((int32_t)handler == SIG_IGN)
|
||||
return;
|
||||
|
||||
if (handler == SIG_DFL) {
|
||||
if ((int32_t)handler == SIG_DFL) {
|
||||
display_signal(sig_num);
|
||||
return;
|
||||
}
|
||||
@ -41,9 +41,9 @@ static void exec_signal(SIGNAL_CODE sig_num)
|
||||
|
||||
void exec_signal_pending(void)
|
||||
{
|
||||
uint32_t signal_code = current_task->signals.pending;
|
||||
int32_t signal_code = current_pcb->signals.pending;
|
||||
if (signal_code != SIG_IGN) {
|
||||
exec_signal(signal_code);
|
||||
current_task->signals.pending = SIG_IGN;
|
||||
current_pcb->signals.pending = SIG_IGN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user