aboutsummaryrefslogtreecommitdiff
path: root/later/schedule.c
diff options
context:
space:
mode:
Diffstat (limited to 'later/schedule.c')
-rw-r--r--later/schedule.c167
1 files changed, 0 insertions, 167 deletions
diff --git a/later/schedule.c b/later/schedule.c
deleted file mode 100644
index c300ae0..0000000
--- a/later/schedule.c
+++ /dev/null
@@ -1,167 +0,0 @@
-#include <cpu/irq.h>
-#include <drivers/uart.h>
-#include <globals.h>
-#include <sys/core.h>
-#include <sys/schedule.h>
-#include <util/mutex.h>
-
-void init_scheduler(void)
-{
- for(int i = 0; i < PRIORITIES; i++) {
- scheduler.tlist[i].prev = &scheduler.tlist[i];
- scheduler.tlist[i].next = &scheduler.tlist[i];
- scheduler.tlist[i].data = 0;
- }
- scheduler.rthread_ll = 0;
- scheduler.ctx = &svccpu;
-}
-
-void* get_stack(void)
-{
- for (int i = 0; i < MAX_THREADS; i++) {
- if (stacks_table[i] == 0) {
- stacks_table[i] = 1;
- return (void*)heap_end() - STACK_SIZE*i;
- }
- }
- return 0;
-}
-
-void add_thread(void (*thread_fxn)(void), unsigned char priority)
-{
- struct Thread* thread = (struct Thread*)malloca(sizeof(struct Thread), 4);
- // Set the program counter to the entry
- thread->thread = thread_fxn;
- // Get a stack frame
- thread->stack_base = get_stack();
- thread->stack = thread->stack_base;
- // Put in error state for no stack
- if(thread->stack == 0)
- thread->data.status = THREAD_STACK_ERROR;
- else
- thread->data.status = THREAD_READY;
- // Doesn't wait for mutex at start
- thread->data.mutex_waiting = 0;
- // Set PID
- thread->data.pid = nextpid++;
- thread->data.preempt_count = 0;
- thread->data.cpu_context.lr = (unsigned long)cleanup;
- unsigned char p = priority;
- if (p >= PRIORITIES) {
- p = PRIORITIES - 1;
- }
- thread->data.priority = p;
- push_ll(&scheduler.tlist[p], thread);
-}
-
-struct LL* get_next_thread(void)
-{
- for(unsigned long i = 0; i < PRIORITIES; i++) {
- struct LL* thread_ll = scheduler.tlist[i].next;
- if (thread_ll == &scheduler.tlist[i])
- continue;
- do {
- struct Thread* thread = thread_ll->data;
- if((thread->data.status == THREAD_RUNNING) || (thread->data.status == THREAD_READY))
- return thread_ll;
- thread_ll = thread_ll->next;
- } while(thread_ll != &scheduler.tlist[i]);
- }
- return 0;
-}
-
-void schedule_c(void)
-{
- // Preserve registers in current context
- preserve_ctx(scheduler.ctx);
-
- // Get current thread
- struct LL* current_thread_ll = scheduler.rthread_ll;
- // Get next thread
- struct LL* next_thread_ll = get_next_thread();
-
- // If there is a current thread
- if (current_thread_ll != 0) {
- // If we are switching the thread
- if (current_thread_ll != next_thread_ll) {
- // Context switch
- struct Thread* current_thread = current_thread_ll->data;
- struct Thread* next_thread = next_thread_ll->data;
- preserve_stack(current_thread);
- //preserve_pc(current_thread);
- current_thread->thread = (void*)current_thread->data.cpu_context.lr;
- restore_stack(next_thread);
- scheduler.rthread_ll = next_thread_ll;
- scheduler.ctx = &next_thread->data.cpu_context;
- }
- }
- else if (next_thread_ll != 0) {
- struct Thread* next_thread = next_thread_ll->data;
- preserve_sys_stack(&svcsp);
- restore_stack(next_thread);
- scheduler.rthread_ll = next_thread_ll;
- scheduler.ctx = &next_thread->data.cpu_context;
- }
- if (scheduler.rthread_ll) {
- struct Thread* rthread = scheduler.rthread_ll->data;
- restore_ctx(scheduler.ctx);
- asm volatile ("bx %0" :: "r"(rthread->thread));
- } else {
- scheduler.ctx = &svccpu;
- restore_sys_stack(&svcsp);
- restore_ctx(scheduler.ctx);
- }
-}
-
-void cleanup(void)
-{
- if (scheduler.rthread_ll != 0) {
- // Mark the thread as finished
- struct Thread* t = scheduler.rthread_ll->data;
- //uart_string("Cleaning up thread ");
- //uart_10(t->data.pid);
- //uart_char('\n');
- t->data.status = THREAD_FINISHED;
- // Mark the stack space as free
- unsigned long sidx = (unsigned long)(heap_end() - t->stack_base)/STACK_SIZE;
- stacks_table[sidx] = 0;
- // Remove the thread
- struct LL* ll = scheduler.rthread_ll;
- struct LL* prev = ll->prev;
- struct LL* next = ll->next;
- prev->next = ll->next;
- next->prev = ll->prev;
- free(ll->data);
- free(ll);
- scheduler.rthread_ll = 0;
- }
- // Schedule next thread
- schedule();
-}
-
-void sched_info(void)
-{
- uart_string("Scheduler Information\n");
- for(unsigned long i = 0; i < PRIORITIES; i++) {
- struct LL* ll = scheduler.tlist[i].next;
- uart_string("Queue ");
- uart_10(i);
- while (ll != &scheduler.tlist[i]) {
- uart_string("\nThread ");
- struct Thread* t = ll->data;
- uart_hex((unsigned long)t->thread);uart_char(' ');
- uart_hex((unsigned long)t->stack);uart_char(' ');
- uart_hex((unsigned long)t->stack_base);uart_char(' ');
- uart_10(t->data.priority);uart_char(' ');
- uart_10(t->data.preempt_count);uart_char(' ');
- uart_10(t->data.status);uart_char(' ');
- uart_hex((unsigned long)t->data.mutex_waiting);uart_char(' ');
- uart_10(t->data.pid);uart_char('\n');
- memshow32((unsigned long*)&t->data.cpu_context, 10);
- ll = ll->next;
- }
- uart_char('\n');
- }
- uart_string("Stacks:\n");
- memshow32((unsigned long*)stacks_table, 6);
-}