summaryrefslogtreecommitdiff
path: root/src/kernel/task
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2012-05-01 17:42:36 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2012-05-01 17:42:36 +0200
commite9683297bf480f9590b0e5796f4520fb430e2e03 (patch)
tree93ef75cd154edf4c342d0a22cd56eb3670feb2b5 /src/kernel/task
parente8cf65c07d78e3cfbac953b1b97c51998a5900df (diff)
downloadTCE-e9683297bf480f9590b0e5796f4520fb430e2e03.tar.gz
TCE-e9683297bf480f9590b0e5796f4520fb430e2e03.zip
Now using Doug Lea's malloc for userland too. And improved stability.
Diffstat (limited to 'src/kernel/task')
-rw-r--r--src/kernel/task/idt.c6
-rw-r--r--src/kernel/task/sched.c2
-rw-r--r--src/kernel/task/syscall.c8
-rw-r--r--src/kernel/task/task.c66
-rw-r--r--src/kernel/task/task.h19
5 files changed, 75 insertions, 26 deletions
diff --git a/src/kernel/task/idt.c b/src/kernel/task/idt.c
index ff129be..aed5ea8 100644
--- a/src/kernel/task/idt.c
+++ b/src/kernel/task/idt.c
@@ -6,7 +6,7 @@
#include "task.h"
#include "syscall.h"
-#include <stdlib.h>
+#include <stdlib_common.h>
extern void isr0();
extern void isr1();
@@ -102,7 +102,7 @@ void idt_irqHandler(struct registers regs) {
if (irq_handlers[regs.err_code] != 0) {
irq_handlers[regs.err_code](&regs);
}
- if (doSwitch) tasking_switch();
+ if (doSwitch) schedule();
}
/* Called in idt_.asm on a system call (interrupt 64).
@@ -208,7 +208,7 @@ void idt_handleIrq(int number, int_callback func) {
/* Tells the IRQ handler to wake up the current thread when specified IRQ fires. */
void idt_waitIrq(int number) {
- if (number < 16 && number >= 0 && proc_priv() <= PL_DRIVER) {
+ if (number < 16 && number >= 0 && proc_priv() <= PL_KERNEL) {
struct irq_waiter *tmp = kmalloc(sizeof(struct irq_waiter));
tmp->thread = current_thread;
tmp->next = irq_wakeup[number];
diff --git a/src/kernel/task/sched.c b/src/kernel/task/sched.c
index 2b0ef8a..aa41d5b 100644
--- a/src/kernel/task/sched.c
+++ b/src/kernel/task/sched.c
@@ -3,7 +3,7 @@
#include <mem/mem.h>
// Lower priority numbers have high priority. Priorities must start at 0.
-#define PRIORITIES 4 // we have 4 priority levels
+#define PRIORITIES 3 // we have 4 priority levels
#define PRIORITY(t) (t->process->privilege) //get priority for a thread
extern struct thread *idle_thread;
diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c
index 5d40596..bd27eba 100644
--- a/src/kernel/task/syscall.c
+++ b/src/kernel/task/syscall.c
@@ -16,13 +16,14 @@
#define CALL4V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx, r->esi); }
CALL0V(thread_exit, thread_exit_sc);
-CALL0V(tasking_switch, schedule_sc);
+CALL0V(schedule, schedule_sc);
CALL1V(thread_sleep, thread_sleep_sc);
CALL1V(process_exit, process_exit_sc);
CALL1(monitor_write, printk_sc);
CALL1V(idt_waitIrq, irq_wait_sc);
CALL0(proc_priv, proc_priv_sc);
-CALL2(process_setheapseg, proc_setheap_sc);
+CALL1(process_sbrk, proc_sbrk_sc);
+CALL1V(process_brk, proc_brk_sc);
static void thread_new_sc(struct registers* r) {
cli();
@@ -39,5 +40,6 @@ int_callback syscalls[NUMBER_OF_SYSCALLS] = {
thread_new_sc, //5
irq_wait_sc,
proc_priv_sc,
- proc_setheap_sc,
+ proc_sbrk_sc,
+ proc_brk_sc,
0 };
diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c
index 7071248..9d98165 100644
--- a/src/kernel/task/task.c
+++ b/src/kernel/task/task.c
@@ -55,7 +55,7 @@ void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint3
}
/* Called when a timer IRQ fires. Does a context switch. */
-void tasking_switch() {
+void schedule() {
if (processes == 0) PANIC("No processes are running !");
asm volatile("cli");
@@ -122,7 +122,7 @@ uint32_t tasking_handleException(struct registers *regs) {
/* Puts the current thread in an inactive state. */
void thread_goInactive() {
current_thread->state = TS_WAKEWAIT;
- tasking_switch();
+ schedule();
}
/* Wakes up the given thread. */
@@ -157,7 +157,7 @@ void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h
}
retrn:
sti();
- tasking_switch();
+ schedule();
}
/* For internal use only. Called by thread_exit and process_exit.
@@ -183,7 +183,7 @@ void thread_exit() {
}
/* System call. Exit the current process. */
-void process_exit(uint32_t retval) {
+void process_exit(size_t retval) {
if (retval == EX_TH_NORMAL || retval == EX_TH_EXCEPTION) retval = EX_PR_EXCEPTION;
thread_exit_stackJmp(retval);
}
@@ -193,7 +193,7 @@ void process_exit(uint32_t retval) {
It switches to user mode if necessary and calls the entry point. */
static void thread_run(void* u_esp, struct thread *thread, thread_entry entry_point, void *data) {
pagedir_switch(thread->process->pagedir);
- if (thread->process->privilege >= PL_SERVICE) { //User mode !
+ if (thread->process->privilege >= PL_USER) { //User mode !
uint32_t *stack = u_esp;
stack--; *stack = (uint32_t)data;
@@ -283,11 +283,12 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi
p->parent = parent;
p->pagedir = pagedir_new();
p->next = processes;
- p->heapseg = 0;
+ p->data = 0;
+ p->dataseg = 0;
p->stack = 0;
- if (p->privilege >= PL_SERVICE) { //We are running in user mode
- size_t stacksBottom = 0xDF000000;
+ if (p->privilege >= PL_USER) { //We are running in user mode
+ size_t stacksBottom = K_HIGHHALF_ADDR - 0x01000000;
seg_map(simpleseg_make(stacksBottom, USER_STACK_SIZE, 1), p->pagedir, 0);
p->stack = stacksBottom + USER_STACK_SIZE - 4;
}
@@ -340,7 +341,7 @@ static void process_delete(struct process *pr) {
}
/* System call. Called by the app to define the place for the heap. */
-int process_setheapseg(size_t start, size_t end) { //syscall
+/*int process_setheapseg(size_t start, size_t end) { //syscall
struct process *p = current_thread->process;
if (start >= K_HIGHHALF_ADDR || end >= K_HIGHHALF_ADDR) return -1;
if (p->heapseg == 0) {
@@ -359,4 +360,51 @@ int process_setheapseg(size_t start, size_t end) { //syscall
} else {
return simpleseg_resize(p->heapseg, end - start);
}
+}*/
+
+size_t process_sbrk(size_t size) {
+ struct process *p = current_thread->process;
+ if (p->data == 0) return -1;
+ ASSERT(p->data < K_HIGHHALF_ADDR);
+ if (p->data + size >= K_HIGHHALF_ADDR) return -1;
+
+ size_t ret;
+ if (p->dataseg == 0) {
+ size_t start = p->data;
+ if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000;
+ size_t end = start + size;
+ if (end & 0x0FFF) end = (end & 0xFFFFF000) + 0x1000;
+
+ struct segment *s = simpleseg_make(start, end - start, 1);
+ if (s == 0) return -5;
+ p->dataseg = seg_map(s, p->pagedir, 0);
+ if (p->dataseg == 0) return -1;
+
+ ret = start;
+ p->data = start + size;
+ } else {
+ size_t start = p->dataseg->start;
+ size_t end = p->data + size;
+ if (end <= start) return -1;
+
+ if (end & 0x0FFF) end = (end & 0xFFFFF000) + 0x1000;
+ simpleseg_resize(p->dataseg, end - start);
+
+ ret = p->data;
+ p->data += size;
+ }
+ /* (DBG) monitor_write("(sbrk ");
+ monitor_writeHex(size);
+ monitor_write(" ");
+ monitor_writeHex(ret);
+ monitor_write(")"); */
+ return ret;
}
+
+void process_brk(size_t ptr) {
+ struct process *p = current_thread->process;
+
+ ASSERT(ptr < K_HIGHHALF_ADDR);
+ process_sbrk(ptr - p->data);
+}
+
diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h
index fdffa11..63cb35a 100644
--- a/src/kernel/task/task.h
+++ b/src/kernel/task/task.h
@@ -8,17 +8,15 @@
#define TS_RUNNING 0
#define TS_WAKEWAIT 2 //Waiting to be waked up by something precise (thread currently blocked)
-#define PL_UNKNOWN 4
-#define PL_USER 3
-#define PL_SERVICE 2
-#define PL_DRIVER 1
+#define PL_UNKNOWN 2
+#define PL_USER 1
#define PL_KERNEL 0
#define EX_TH_NORMAL 0x10000 //ERROR code : just one thread exits, because it has to
#define EX_TH_EXCEPTION 0x10001 //ERROR code : just one thread exits, because of an unhandled exception
#define EX_PR_EXCEPTION 0x10002 //ERROR code : all process finishes, because of an unhandled exception
-#define USER_STACK_SIZE 0x8000 //32k, but pages will be mapped one by one as used
+#define USER_STACK_SIZE 0x10000 //64k, but pages will be mapped one by one as they are used
typedef void (*thread_entry)(void*);
@@ -26,9 +24,9 @@ struct process {
uint32_t pid, uid, privilege, thread_count;
struct process *parent;
struct page_directory *pagedir;
- size_t stack;
+ size_t stack, data;
- struct segment_map *heapseg;
+ struct segment_map *dataseg;
struct process *next; //Forms a linked list
struct thread *threads;
@@ -48,7 +46,7 @@ struct thread {
extern struct thread *current_thread;
void tasking_init();
-void tasking_switch();
+void schedule();
void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablePhysical);
uint32_t tasking_handleException(struct registers *regs);
@@ -59,7 +57,8 @@ struct thread * thread_new(struct process *proc, thread_entry entry_point, void
struct process* process_new(struct process *parent, uint32_t uid, uint32_t privilege);
void thread_exit(); //syscall
-void process_exit(uint32_t retval); //syscall
-int process_setheapseg(size_t start, size_t end); //syscall
+void process_exit(size_t retval); //syscall
+size_t process_sbrk(size_t size);
+void process_brk(size_t ptr);
#endif