diff options
Diffstat (limited to 'sched')
| -rw-r--r-- | sched/scheduler.c | 65 | ||||
| -rw-r--r-- | sched/scheduler.h | 12 | 
2 files changed, 68 insertions, 9 deletions
diff --git a/sched/scheduler.c b/sched/scheduler.c index ed85f9b..a6ace7d 100644 --- a/sched/scheduler.c +++ b/sched/scheduler.c @@ -19,6 +19,14 @@ extern uint32_t read_eip(void);  process_t *get_current_task(void) { return current_task; } +void set_signal_handler(int sig, void (*handler)(int)) { +  if (sig >= 20 || sig < 0) +    return; +  if (9 == sig) +    return; +  current_task->signal_handlers[sig] = handler; +} +  process_t *create_process(process_t *p) {    process_t *r;    r = ksbrk(sizeof(process_t)); @@ -37,9 +45,15 @@ process_t *create_process(process_t *p) {    r->cr3 = (p) ? clone_directory(get_active_pagedirectory())                 : get_active_pagedirectory();    r->next = 0; +  r->incoming_signal = 0;    r->parent = p;    r->child = NULL;    r->halt_list = NULL; + +  mmu_allocate_region((void *)(0x80000000 - 0x1000), 0x1000, MMU_FLAG_RW, +                      r->cr3); +  r->signal_handler_stack = 0x80000000; +    strcpy(r->current_working_directory, "/");    r->data_segment_end = (p) ? p->data_segment_end : NULL;    memset((void *)r->halts, 0, 2 * sizeof(uint32_t)); @@ -50,6 +64,8 @@ process_t *create_process(process_t *p) {          r->file_descriptors[i]->reference_count++;        }      } +    if (i < 20) +      r->signal_handlers[i] = NULL;      r->read_halt_inode[i] = NULL;      r->write_halt_inode[i] = NULL;      r->disconnect_halt_inode[i] = NULL; @@ -132,7 +148,8 @@ void exit(int status) {  }  uint32_t setup_stack(uint32_t stack_pointer, int argc, char **argv) { -  mmu_allocate_region(STACK_LOCATION - STACK_SIZE, STACK_SIZE, MMU_FLAG_RW); +  mmu_allocate_region(STACK_LOCATION - STACK_SIZE, STACK_SIZE, MMU_FLAG_RW, +                      NULL);    flush_tlb();    uint32_t ptr = stack_pointer; @@ -244,6 +261,8 @@ process_t *next_task(process_t *c) {      c = c->next;      if (!c)        c = ready_queue; +    if (c->incoming_signal) +      break;      if (c->sleep_until > pit_num_ms())        continue;      if (is_halted(c) || c->dead) @@ -271,6 +290,25 @@ int task_save_state(void) {    return 1;  } +int kill(pid_t pid, int sig) { +  process_t *p = current_task; +  p = p->next; +  if (!p) +    p = ready_queue; +  for (; p->pid != pid;) { +    if (p == current_task) +      break; +    p = p->next; +    if (!p) +      p = ready_queue; +  } +  if (p->pid != pid) +    return -ESRCH; +  p->incoming_signal = sig; +  return 0; +} + +void jump_signal_handler(void *func, uint32_t esp);  void switch_task() {    if (!current_task)      return; @@ -283,15 +321,32 @@ void switch_task() {    active_directory = current_task->cr3; -  asm("			\ +  if (current_task->incoming_signal) { +    uint8_t sig = current_task->incoming_signal; +    current_task->incoming_signal = 0; +    asm("mov %0, %%cr3" ::"r"(current_task->cr3->physical_address)); + +    void *handler = current_task->signal_handlers[sig]; +    if (9 == sig) { +      klog("Task recieved SIGKILL", LOG_NOTE); +      exit(0); +    } +    if (!handler) { +      klog("Task recieved unhandeled signal. Killing process.", LOG_WARN); +      exit(1); +    } +    jump_signal_handler(handler, current_task->signal_handler_stack); +  } else { +    asm("			\          mov %0, %%esp;		\          mov %1, %%ebp;		\          mov %2, %%ecx;		\          mov %3, %%cr3;		\          mov $0x1, %%eax;	\          jmp *%%ecx" ::"r"(current_task->esp), -      "r"(current_task->ebp), "r"(current_task->eip), -      "r"(current_task->cr3->physical_address)); +        "r"(current_task->ebp), "r"(current_task->eip), +        "r"(current_task->cr3->physical_address)); +  }  }  MemoryMap **get_free_map(void) { @@ -318,7 +373,7 @@ void *allocate_virtual_user_memory(size_t length, int prot, int flags) {    if ((void *)-1 == rc)      return (void *)-1; -  mmu_allocate_region(rc, length, MMU_FLAG_RW); +  mmu_allocate_region(rc, length, MMU_FLAG_RW, NULL);    return rc;  } diff --git a/sched/scheduler.h b/sched/scheduler.h index 7df7c40..fc92ff3 100644 --- a/sched/scheduler.h +++ b/sched/scheduler.h @@ -4,6 +4,7 @@  #include <fs/vfs.h>  #include <halts.h>  #include <mmu.h> +#include <signal.h>  #define MAX_PATH 256  #define KEYBOARD_HALT 0 @@ -19,6 +20,8 @@ void *mmap(void *addr, size_t length, int prot, int flags, int fd,             size_t offset);  int munmap(void *addr, size_t length);  int msync(void *addr, size_t length, int flags); +int kill(pid_t pid, int sig); +void set_signal_handler(int sig, void (*handler)(int));  typedef struct {    void *u_address; @@ -34,25 +37,26 @@ struct Process {    char program_name[100];    char current_working_directory[MAX_PATH];    uint32_t eip, esp, ebp; +  uint8_t incoming_signal; +  uint32_t signal_handler_stack; +  void *signal_handlers[20];    PageDirectory *cr3;    vfs_fd_t *file_descriptors[100];    vfs_inode_t *read_halt_inode[100];    vfs_inode_t *write_halt_inode[100];    vfs_inode_t *disconnect_halt_inode[100]; -  //	struct vfs_fd_t ** file_descriptors;    uint32_t halts[2];    struct Halt *halt_list;    void *data_segment_end; -  //	uint32_t *halts;    process_t *next;    process_t *parent; +  // TODO: Create a linkedlist of childs so that the parent process +  // can do stuff such as reap zombies and get status.    process_t *child;    MemoryMap *maps[100];    uint32_t sleep_until;    int child_rc;    int dead; -  // FIXME: Create a linkedlisti of childs so that the parent process -  // can do stuff such as reap zombies and get status.  };  process_t *get_current_task(void);  |