Draft: lab 5 failed
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <queue.h>
|
||||
#include <interrupt.h>
|
||||
#include <string.h>
|
||||
#include <timer.h>
|
||||
|
||||
queue_t *global_run_queue = 0x0;
|
||||
queue_t *global_wait_queue = 0x0;
|
||||
@@ -21,9 +22,11 @@ thread_t *get_current(void)
|
||||
static inline
|
||||
void _thread_wrapper()
|
||||
{
|
||||
enable_interrupt();
|
||||
|
||||
thread_t *cur = get_current();
|
||||
|
||||
LOG("Running"); DEBUG_THREAD(cur->func);
|
||||
LOG("Running thread wrapper"); DEBUG_THREAD(cur->func);
|
||||
cur->func(cur->param);
|
||||
|
||||
cur->status = THREAD_STATUS_ZOMBIE;
|
||||
@@ -43,19 +46,26 @@ thread_t *_make_thread(thread_func_t func, uint64_t param)
|
||||
.status = THREAD_STATUS_RUNABLE,
|
||||
.retcode = 0,
|
||||
|
||||
.stack_pointer = allocate_page(256),
|
||||
.stack = allocate_page(256),
|
||||
.stack_size = 256 << 12,
|
||||
|
||||
.regs = kmalloc(sizeof(cpu_state_t)),
|
||||
|
||||
.process = 0x0,
|
||||
};
|
||||
memset(&ret->regs, 0, sizeof(cpu_state_t));
|
||||
ret->regs.sp = (uint64_t)ret->stack_pointer + ret->stack_size - 64;
|
||||
ret->regs.lr = (uint64_t)_thread_wrapper;
|
||||
ret->regs.fp = ret->regs.sp;
|
||||
memset(ret->regs, 0, sizeof(cpu_state_t));
|
||||
ret->regs->sp = (uint64_t)ret->stack + ret->stack_size - 64;
|
||||
ret->regs->lr = (uint64_t)_thread_wrapper;
|
||||
ret->regs->fp = ret->regs->sp;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void run_thread(thread_func_t func, uint64_t param)
|
||||
{ QUEUE_PUSH_BACK(global_run_queue, _make_thread(func, param)); }
|
||||
{
|
||||
// Runs before enable interrupt
|
||||
QUEUE_PUSH_BACK(global_run_queue, _make_thread(func, param));
|
||||
}
|
||||
|
||||
static inline
|
||||
int32_t _idle(uint64_t)
|
||||
@@ -63,7 +73,9 @@ int32_t _idle(uint64_t)
|
||||
DEBUG_THREAD("enter idle thread");
|
||||
|
||||
for (;;) {
|
||||
enable_interrupt();
|
||||
schedule();
|
||||
DEBUG_THREAD(global_gc_queue->size);
|
||||
// DEBUG_THREAD("back to idle thread");
|
||||
}
|
||||
|
||||
@@ -76,23 +88,20 @@ void thread_init(void)
|
||||
global_wait_queue = make_queue();
|
||||
global_gc_queue = make_queue();
|
||||
|
||||
thread_t *th = kmalloc(sizeof(thread_t));
|
||||
W_SYSREG(tpidr_el1, th);
|
||||
|
||||
run_thread(_idle, 0x0);
|
||||
}
|
||||
|
||||
void schedule(void)
|
||||
{
|
||||
// DEBUG_THREAD("schedule!");
|
||||
disable_interrupt();
|
||||
|
||||
// DEBUG_THREAD("run queue:");
|
||||
for (queue_node_t *n = global_run_queue->begin->next;
|
||||
n != global_run_queue->end;
|
||||
n = n->next) {
|
||||
thread_t *th = get_current(), *next = 0x0;
|
||||
LOG("Run thread"); LOG(global_run_queue->size); DEBUG_THREAD(th);
|
||||
LOG(th->stack); DEBUG_THREAD(th->regs->sp);
|
||||
|
||||
// LOG(n); DEBUG_THREAD(n->value);
|
||||
}
|
||||
|
||||
thread_t *cur = get_current(), *next = 0x0;
|
||||
while (global_run_queue->size > 0 && !next) {
|
||||
next = QUEUE_POP_FRONT(thread_t, global_run_queue);
|
||||
if (next->status == THREAD_STATUS_ZOMBIE) {
|
||||
@@ -102,8 +111,8 @@ void schedule(void)
|
||||
QUEUE_PUSH_BACK(global_run_queue, next);
|
||||
}
|
||||
|
||||
if (next && cur != next)
|
||||
context_switch(&cur->regs, &next->regs, next);
|
||||
if (next && th != next)
|
||||
context_switch(th->regs, next->regs, next);
|
||||
|
||||
enable_interrupt();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user