aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/Makefile1
-rw-r--r--kernel/features/proc.c85
-rw-r--r--kernel/features/syscall.c4
-rw-r--r--kernel/inc/proc.h3
-rw-r--r--libc/inc/list.h2
-rw-r--r--libc/list.c11
6 files changed, 54 insertions, 52 deletions
diff --git a/apps/Makefile b/apps/Makefile
index 194d7df..6a6e52c 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -6,7 +6,6 @@ LD = ../cross/opt/bin/i686-elf-ld
OC = ../cross/opt/bin/i686-elf-objcopy
# Flags to make the binary smaller TODO: Remove after indirect pointer support!
-# TODO: Fix optimization flags (relocation of functions)
CSFLAGS = -mpreferred-stack-boundary=2 -fno-asynchronous-unwind-tables -Os
CFLAGS = $(CSFLAGS) -Wall -Wextra -nostdlib -nostdinc -fno-builtin -mgeneral-regs-only -std=c99 -m32 -pedantic-errors -I../libc/inc/ -I../libgui/inc/ -fPIE -Duserspace
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index d5c2895..3e99e35 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -4,6 +4,7 @@
#include <boot.h>
#include <cpu.h>
#include <interrupts.h>
+#include <list.h>
#include <load.h>
#include <mem.h>
#include <print.h>
@@ -12,39 +13,40 @@
#include <timer.h>
u32 pid = 0;
-struct proc *root;
-struct proc *current;
-struct proc *last;
+struct list *proc_list;
+struct node *current;
void scheduler(struct regs *regs)
{
if (current)
- memcpy(&current->regs, regs, sizeof(struct regs));
+ memcpy(&((struct proc *)current->data)->regs, regs, sizeof(struct regs));
timer_handler();
if (current && current->next)
current = current->next;
else
- current = root;
+ current = proc_list->head;
- while (current->state == PROC_ASLEEP) {
- if (!current->next) {
- assert(root->state != PROC_ASLEEP || pid > 1);
- current = root;
+ while (!current || ((struct proc *)current->data)->state == PROC_ASLEEP) {
+ if (!current || !current->next || !current->next->data) {
+ assert(proc_list->head);
+ assert(((struct proc *)proc_list->head->data)->state != PROC_ASLEEP);
+ current = proc_list->head;
} else {
current = current->next;
}
}
/* proc_print(); */
- memcpy(regs, &current->regs, sizeof(struct regs));
+ memcpy(regs, &((struct proc *)current->data)->regs, sizeof(struct regs));
- if (current->event) {
+ if (((struct proc *)current->data)->event) {
+ struct proc *proc = (struct proc *)current->data;
// TODO: Modify and backup EIP
- printf("Event %d for pid %d\n", current->event, current->pid);
+ printf("Event %d for pid %d\n", proc->event, proc->pid);
// TODO: Clear bit after resolve
- current->event = 0;
+ proc->event = 0;
}
if (regs->cs != GDT_USER_CODE_OFFSET) {
@@ -56,43 +58,41 @@ void scheduler(struct regs *regs)
regs->cs = GDT_USER_CODE_OFFSET;
regs->eflags = EFLAGS_ALWAYS | EFLAGS_INTERRUPTS;
}
- /* printf("%d", current->pid); */
+ /* printf("{%d}", ((struct proc *)current->data)->pid); */
}
void proc_print()
{
- struct proc *proc = root;
+ struct node *node = proc_list->head;
- printf("\n");
- while (proc) {
+ printf("\nPROCESSES\n");
+ struct proc *proc;
+ while (node && (proc = ((struct proc *)node->data))) {
printf("Process %d [%s]: %s\n", proc->pid,
proc->state == PROC_RUNNING ? "running" : "sleeping", proc->name);
- proc = proc->next;
+ node = node->next;
}
printf("\n");
}
struct proc *proc_current()
{
- return current;
-}
-
-void proc_attach(struct proc *proc)
-{
- if (!last->next) {
- last->next = proc;
- } else {
- struct proc *save = last;
- while (save->next)
- save = save->next;
- save->next = proc;
- }
+ return (struct proc *)current->data;
}
-void proc_exit(int status)
+void proc_exit(struct proc *proc, int status)
{
- printf("Process %d exited with status %d\n", current->pid, status);
- current->state = PROC_ASLEEP;
+ printf("Process %d exited with status %d\n", proc->pid, status);
+ proc->state = status == 0 ? PROC_ASLEEP : PROC_ERROR;
+
+ struct node *iterator = proc_list->head;
+ do {
+ if (iterator->data == proc) {
+ list_remove(proc_list, iterator);
+ break;
+ }
+ } while ((iterator = iterator->next) != NULL);
+ proc_print();
}
struct proc *proc_make()
@@ -100,11 +100,10 @@ struct proc *proc_make()
struct proc *proc = malloc(sizeof(*proc));
proc->pid = pid++;
proc->state = PROC_RUNNING;
- proc->next = NULL;
if (current)
- proc_attach(proc);
- last = proc;
+ list_add(proc_list, proc);
+
return proc;
}
@@ -113,15 +112,19 @@ extern void proc_jump_userspace();
u32 _esp, _eip;
void proc_init()
{
+ if (proc_list)
+ return;
+
cli();
irq_install_handler(0, scheduler);
+ proc_list = list_new();
- root = proc_make();
- bin_load("/init", root);
+ struct node *new = list_add(proc_list, proc_make());
+ bin_load("/init", new->data);
proc_print();
- _eip = root->regs.eip;
- _esp = root->regs.useresp;
+ _eip = ((struct proc *)new->data)->regs.eip;
+ _esp = ((struct proc *)new->data)->regs.useresp;
int argc = 2;
char **argv = malloc(sizeof(*argv) * (argc + 1));
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index ac79fc1..2704690 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -58,12 +58,12 @@ void syscall_handler(struct regs *r)
((u32 *)proc->regs.useresp)[0] = argc;
((u32 *)proc->regs.useresp)[1] = (u32)argv;
if (r->eax)
- proc->state = PROC_ERROR;
+ proc_exit(proc, r->eax);
break;
}
case SYS_EXIT: {
printf("exit\n");
- proc_exit(r->ebx);
+ proc_exit(proc_current(), r->ebx);
break;
}
case SYS_MAP: {
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index b2743a6..76eeb4b 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -19,14 +19,13 @@ struct proc {
enum state state;
char name[32];
struct regs regs;
- struct proc *next;
u32 event;
};
void proc_init();
void proc_print();
struct proc *proc_current();
-void proc_exit(int status);
+void proc_exit(struct proc *proc, int status);
struct proc *proc_make();
#endif
diff --git a/libc/inc/list.h b/libc/inc/list.h
index 5deaf59..0a5c6c0 100644
--- a/libc/inc/list.h
+++ b/libc/inc/list.h
@@ -19,7 +19,7 @@ struct node {
struct list *list_new();
/* struct node *list_new_node(); */ // TODO: Make node-specific things static/private?
/* void list_add_node(struct list *list, struct node *node); */
-void list_add(struct list *list, void *data);
+struct node *list_add(struct list *list, void *data);
void list_remove(struct list *list, struct node *node);
#endif
diff --git a/libc/list.c b/libc/list.c
index c36d6e1..89de4d0 100644
--- a/libc/list.c
+++ b/libc/list.c
@@ -23,14 +23,14 @@ struct node *list_new_node()
return node;
}
-void list_add_node(struct list *list, struct node *node)
+struct node *list_add_node(struct list *list, struct node *node)
{
if (list == NULL)
- return;
+ return NULL;
if (list->head == NULL) {
list->head = node;
- return;
+ return list->head;
}
struct node *iterator = list->head;
@@ -42,13 +42,14 @@ void list_add_node(struct list *list, struct node *node)
}
iterator = iterator->next;
}
+ return node;
}
-void list_add(struct list *list, void *data)
+struct node *list_add(struct list *list, void *data)
{
struct node *node = list_new_node();
node->data = data;
- list_add_node(list, node);
+ return list_add_node(list, node);
}
// Maybe list_remove_node?