summaryrefslogtreecommitdiff
path: root/src/kernel/task/task.c
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/task.c
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/task.c')
-rw-r--r--src/kernel/task/task.c66
1 files changed, 57 insertions, 9 deletions
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);
+}
+