From ad9e577e8b2f6431d48a6a64fd95aff432e48441 Mon Sep 17 00:00:00 2001 From: Christian Cunningham Date: Thu, 10 Mar 2022 20:01:25 -0800 Subject: More Deterministic --- include/globals.h | 7 ++---- include/lib/kmem.h | 4 --- include/sys/schedule.h | 13 +++------- include/util/lock.h | 1 - include/util/mutex.h | 2 -- linker.ld | 4 +++ src/drivers/uart.c | 1 - src/exceptions/svc.S | 18 ++++---------- src/globals.c | 13 +++++----- src/lib/kmem.c | 53 --------------------------------------- src/lib/strings.c | 8 +++--- src/sys/schedule.S | 2 +- src/sys/schedule.c | 67 +++++++++++++++++++------------------------------- src/tests/test.S | 2 +- src/util/lock.c | 8 ------ src/util/mutex.c | 52 --------------------------------------- src/util/status.c | 10 -------- 17 files changed, 53 insertions(+), 212 deletions(-) diff --git a/include/globals.h b/include/globals.h index 156968a..7bda83c 100644 --- a/include/globals.h +++ b/include/globals.h @@ -8,17 +8,14 @@ extern unsigned long cntfrq; extern char* os_name; extern char* os_info_v; -extern unsigned char kmem_begin[0x2000000]; -extern unsigned char kmem_lookup[0xD000]; extern unsigned long nextpid; -extern unsigned long sched_stack_count; extern unsigned long stimel; extern unsigned long stimeh; -extern struct Drawer g_Drawer; extern struct Scheduler scheduler; extern struct Thread usrloopthread; extern unsigned int gwidth, gheight, gpitch, gisrgb; -extern unsigned char stacks_table[MAX_THREADS]; +extern unsigned char thread_table[MAX_THREADS]; +extern struct Thread threads[MAX_THREADS]; #endif #endif diff --git a/include/lib/kmem.h b/include/lib/kmem.h index 67751cd..e942c0d 100644 --- a/include/lib/kmem.h +++ b/include/lib/kmem.h @@ -1,10 +1,6 @@ #ifndef LIB_KMEM_H #define LIB_KMEM_H -void* kmalloc(unsigned int size); -void* kcalloc(unsigned int size); -void kfree(void* ptr); - void kmemshow32(void* data, unsigned long length); void kmemshow(void* data, unsigned long length); diff --git a/include/sys/schedule.h b/include/sys/schedule.h index 67f2f9c..397ab2e 100644 --- a/include/sys/schedule.h +++ b/include/sys/schedule.h @@ -4,7 +4,7 @@ // If TQUEUE_MAX is changed, ensure sys/schedule.S's value gets changed #define TQUEUE_MAX 0x100 #define STACK_SIZE 0x4000 -#define TQUEUE_CNT 4 +#define TQUEUE_CNT 3 #define PRIORITIES 8 #define MAX_THREADS TQUEUE_MAX*PRIORITIES*TQUEUE_CNT @@ -12,13 +12,6 @@ enum ThreadStatus { THREAD_READY = 0, THREAD_MWAIT = 1, THREAD_SWAIT = 2, - THREAD_SERROR = 3, // Stack Error - THREAD_FINISH = 4, // Need to clean up -}; - -struct RStack { - void* sp; - unsigned long idx; }; struct Thread { @@ -31,7 +24,10 @@ struct Thread { unsigned char preempt; unsigned short status; void* mptr; + unsigned long offset; unsigned char old_priority; + unsigned char c_reserved; + unsigned short s_reserved; }; struct ThreadRotBuffer { @@ -44,7 +40,6 @@ struct ThreadQueues { struct ThreadRotBuffer ready; struct ThreadRotBuffer mwait; struct ThreadRotBuffer swait; - struct ThreadRotBuffer serror; }; struct Scheduler { diff --git a/include/util/lock.h b/include/util/lock.h index f6f8f53..c5b2f7e 100644 --- a/include/util/lock.h +++ b/include/util/lock.h @@ -9,6 +9,5 @@ struct Lock { void lock(struct Lock* l); void unlock(struct Lock* l); -struct Lock* create_lock(void); #endif diff --git a/include/util/mutex.h b/include/util/mutex.h index 61237b8..ab318b4 100644 --- a/include/util/mutex.h +++ b/include/util/mutex.h @@ -15,6 +15,4 @@ struct Mutex { void* addr; } __attribute__((packed, aligned(4))); -struct Mutex* create_mutex(void* addr); - #endif diff --git a/linker.ld b/linker.ld index 60f16de..dcb5a9b 100644 --- a/linker.ld +++ b/linker.ld @@ -34,6 +34,10 @@ SECTIONS . = ALIGN(4096); KEEP(*(.bss.kmem)) . = ALIGN(4096); + KEEP(*(.bss.threadl")) + . = ALIGN(4096); + KEEP(*(.bss.threads")) + . = ALIGN(4096); *(.bss) *(.bss.*) KEEP(*(.bss.mmheap)) diff --git a/src/drivers/uart.c b/src/drivers/uart.c index e4ae2d1..deaa84a 100644 --- a/src/drivers/uart.c +++ b/src/drivers/uart.c @@ -74,7 +74,6 @@ void uart_10(unsigned long val) { char* dptr = u32_to_str(val); uart_string(dptr); - kfree(dptr); } void uart_hexn(unsigned long c_val) diff --git a/src/exceptions/svc.S b/src/exceptions/svc.S index c23df82..1b0cc1f 100644 --- a/src/exceptions/svc.S +++ b/src/exceptions/svc.S @@ -33,22 +33,14 @@ svc_000001: // Get time svc_000002: // Run Schedule ldmfd sp!, {r0-r12,lr} b schedule -svc_000003: // Clean task stack +svc_000003: // Free Thread in Table ldr r3, =scheduler ldr r2, [r3, #0] // struct Thread* rthread - ldr r1, [r2, #8] // sp_base - cmp r1, #-1 - beq svc_exit - ldr r3, =stacks_table + ldr r1, [r2, #0x1c] // thread offset mov r0, #0 - strb r0, [r3, r1] - // Free the thread after freeing the stack - mov r0, r2 - bl kfree - ldr r3, =sched_stack_count - ldr r2, [r3] - sub r2, #1 - str r2, [r3] + ldr r2, =thread_table + add r2, r1 + str r0, [r2] b svc_exit svc_000004: // Lock Lock (usr_r0 = struct Lock*) ldr r3, =scheduler diff --git a/src/globals.c b/src/globals.c index e94580c..29760b6 100644 --- a/src/globals.c +++ b/src/globals.c @@ -1,6 +1,4 @@ #define GLOBALS_C -#include -#include #include char* os_name = "Jobbed"; #ifndef VERSION @@ -9,10 +7,7 @@ char* os_info_v = "?"; char* os_info_v = VERSION; #endif -__attribute__((section(".bss.kmem"))) unsigned char kmem_begin[0x2000000]; -__attribute__((section(".bss"))) unsigned char kmem_lookup[0xD000]; __attribute__((section(".bss"))) unsigned long nextpid; -__attribute__((section(".bss"))) unsigned long sched_stack_count; __attribute__((section(".bss"))) unsigned long stimel; __attribute__((section(".bss"))) unsigned long stimeh; __attribute__((section(".bss"))) struct Scheduler scheduler; @@ -21,4 +16,10 @@ __attribute__((section(".bss"))) unsigned int gwidth; __attribute__((section(".bss"))) unsigned int gheight; __attribute__((section(".bss"))) unsigned int gpitch; __attribute__((section(".bss"))) unsigned int gisrgb; -__attribute__((section(".bss"))) unsigned char stacks_table[MAX_THREADS]; +// 0 - Free +// 1 - Ready +// 2 - Waiting for Mutex +// 3 - Waiting for Signal +// 4+ - Reserved +__attribute__((section(".bss.threadl"))) unsigned char thread_table[MAX_THREADS]; +__attribute__((section(".bss.threads"))) struct Thread threads[MAX_THREADS]; diff --git a/src/lib/kmem.c b/src/lib/kmem.c index 931d5e3..0419662 100644 --- a/src/lib/kmem.c +++ b/src/lib/kmem.c @@ -2,59 +2,6 @@ #include #include -void* kmalloc(unsigned int size) -{ - unsigned int sz = 1; - while (sz < size && sz < 0x1000) - sz *= 2; - unsigned long offset = 0x1000*(sz/2); - unsigned int exp = 0; - unsigned int tmp = sz; - while (tmp != 0) { - exp++; - tmp = tmp >> 1; - } - unsigned int i = 0; - while (i < 0x1000) { - if (kmem_lookup[0x1000*exp + i] == 0) { - kmem_lookup[0x1000*exp + i] = 1; - return (void*)kmem_begin + offset + i*sz; - } - i++; - } - return 0; -} - -void* kcalloc(unsigned int size) -{ - unsigned char* ptr = kmalloc(size); - if (ptr == 0) - return 0; - for(unsigned int i = 0; i < size; i++) - ptr[i] = 0; - return ptr; -} - -void kfree(void* ptr) -{ - if (!((unsigned long)kmem_begin <= (unsigned long)ptr && (unsigned long)ptr < (unsigned long)kmem_begin + 0x200000)) - return; - unsigned long size = 1; - while (!((unsigned long)kmem_begin + 0x1000*(size/2) <= (unsigned long)ptr && (unsigned long)ptr < (unsigned long)kmem_begin + 0x1000*size)) { - size *= 2; - } - void* base = (void*)((unsigned long)ptr - ((unsigned long)ptr % size)); - void* block_base = kmem_begin + 0x1000*(size/2); - unsigned int lookup_offset = (base - block_base)/size; - unsigned int exp = 0; - unsigned int tmp = size; - while (tmp != 0) { - exp++; - tmp = tmp >> 1; - } - kmem_lookup[0x1000*exp + lookup_offset] = 0; -} - void kmemshow32(void* data, unsigned long length) { unsigned long* ptr = data; diff --git a/src/lib/strings.c b/src/lib/strings.c index 53caaec..3155afa 100644 --- a/src/lib/strings.c +++ b/src/lib/strings.c @@ -36,7 +36,7 @@ unsigned char strcmpn(string_t a, string_t b, unsigned int n) char* zhex32_to_str(unsigned long value) { - char* data = kcalloc(9); + static char data[10]; char tmp = 0; char isz = -1; for (int i = 0; i < 8; i++) { @@ -53,7 +53,7 @@ char* zhex32_to_str(unsigned long value) char* hex32_to_str(unsigned long value) { - char* data = kcalloc(9); + static char data[10]; char tmp = 0; for (int i = 0; i < 8; i++) { tmp = (value >> 4*(8-i-1))&0xF; @@ -69,7 +69,7 @@ char* u32_to_str(unsigned long value) { unsigned long t = value; unsigned long c; - char* data = kcalloc(11); + static char data[12]; char* dptr = data + 9; for (int i = 0; i <= 10; i++) { c = t%10; @@ -91,7 +91,7 @@ char* s32_to_str(unsigned long value) t = -t; is_neg = 1; } - char* data = kcalloc(12); + static char data[13]; char* dptr = data + 10; for (int i = 0; i <= 10; i++) { c = t%10; diff --git a/src/sys/schedule.S b/src/sys/schedule.S index e44d12b..d7301fc 100644 --- a/src/sys/schedule.S +++ b/src/sys/schedule.S @@ -35,7 +35,7 @@ cleanup: mov r1, #0 1: str r1, [r0, #0] - // cleanup stack + // Free thread in table svc #3 // usrloop -> rthread ldr r3, =scheduler diff --git a/src/sys/schedule.c b/src/sys/schedule.c index b068963..8c65c6f 100644 --- a/src/sys/schedule.c +++ b/src/sys/schedule.c @@ -34,71 +34,54 @@ void init_scheduler(void) trb += 1; } } - sched_stack_count = 0; // Initialize nextpid nextpid = FIRST_AVAIL_PID; + + for (unsigned long i = 0; i < MAX_THREADS; i++) { + struct Thread* t = &threads[i]; + t->offset = i; + t->sp_base = 0x20000000 - STACK_SIZE*i; + } } -struct RStack get_stack(void) +struct Thread* get_available_thread(void) { - struct RStack r = {.sp = 0, .idx = -1}; - // Find an available stack - for (int i = 0; i < MAX_THREADS; i++) { - if (stacks_table[i] == 0) { - // Mark unavailable - stacks_table[i] = 1; - r.idx = i; - r.sp = (void*)0x20000000 - STACK_SIZE*i; - return r; - } + for(unsigned long i = 0; i < MAX_THREADS; i++) { + if (thread_table[i] == 0) + return &threads[i]; } - return r; + return 0; } void add_thread(void* pc, void* arg, unsigned char priority) { - //void* sp = get_stack(); - struct RStack r = get_stack(); - //struct Thread* thread = (struct Thread*)malloca(sizeof(struct Thread), 4); - struct Thread* thread = (struct Thread*)kmalloc(sizeof(struct Thread)); + struct Thread* thread = get_available_thread(); + thread_table[thread->offset] = 1; thread->pc = pc; - // Valid stack has been obtained for this thread - if (r.sp) { - thread->sp_base = r.idx; - unsigned long* argp = r.sp; - argp -= 13; - *argp = (unsigned long)arg; // Set r0 to the argument - argp -= 1; - *(unsigned long**)argp = (unsigned long*)cleanup; // Set lr to the cleanup function - thread->sp = (void*)argp; - thread->status = THREAD_READY; - sched_stack_count++; - } - // Couldn't allocate a proper stack - else { - thread->sp_base = r.idx; - thread->sp = r.sp; - thread->status = THREAD_SERROR; - } + unsigned long* argp = (void*)thread->sp_base; + argp -= 13; + *argp = (unsigned long)arg; // Set r0 to the argument + argp -= 1; + *(unsigned long**)argp = (unsigned long*)cleanup; // Set lr to the cleanup function + thread->sp = argp; + thread->status = THREAD_READY; thread->mptr = (void*)0; thread->pid = nextpid++; // Reset next pid on overflow if (nextpid < FIRST_AVAIL_PID) { nextpid = FIRST_AVAIL_PID; } - thread->priority = priority % PRIORITIES; + if (priority >= PRIORITIES) + thread->priority = PRIORITIES - 1; + else + thread->priority = priority; thread->old_priority = -1; thread->preempt = 0; // Add Thread* to scheduler's appropriate buffer struct ThreadQueues* tq = &scheduler.thread_queues[thread->priority]; struct ThreadRotBuffer* trb; // Add to stack error queue if stack was not obtained - if (thread->status == THREAD_SERROR) { - trb = &tq->serror; - } - else { - trb = &tq->ready; - } + trb = &tq->ready; trb->queue[trb->woffset++] = thread; trb->woffset %= TQUEUE_MAX; // Schedule if this was called in usermode diff --git a/src/tests/test.S b/src/tests/test.S index ebb901c..035f8f6 100644 --- a/src/tests/test.S +++ b/src/tests/test.S @@ -1,6 +1,6 @@ .section .text -btest: +a.btest: push {lr} pop {pc} diff --git a/src/util/lock.c b/src/util/lock.c index 6c7d07e..95f93af 100644 --- a/src/util/lock.c +++ b/src/util/lock.c @@ -1,6 +1,5 @@ #include #include -#include #include // TODO: Improve locking for system @@ -25,10 +24,3 @@ void unlock(struct Lock* l) atm_release((unsigned long*)l); } } - -struct Lock* create_lock(void) -{ - struct Lock* l = (struct Lock*)kmalloc(sizeof(struct Lock)); - l->pid = 0; - return l; -} diff --git a/src/util/mutex.c b/src/util/mutex.c index 995ef62..e69de29 100644 --- a/src/util/mutex.c +++ b/src/util/mutex.c @@ -1,52 +0,0 @@ -#include -#include -#include -#include -#include - -///unsigned char lock_mutex(struct Mutex* m, unsigned long pid) -///{ -/// if (m->pid == NULL_PID) { -/// // Use currently running thread's PID if no pid given -/// if (pid == 0) { -/// struct Thread* thread = scheduler.rthread; -/// atm_lock(thread->pid, &m->pid); -/// } else { -/// atm_lock(pid, &m->pid); -/// } -/// return 0; -/// } -/// struct Thread* thread = scheduler.rthread; -/// thread->status = THREAD_MWAIT; -/// thread->mptr = m; -/// return 1; -///} -/// -///// Eventually, there will need to be a hook into the scheduling mechanism -///// that checks the currently running process and check that against the -///// mutex's pid lock -///unsigned char release_mutex(struct Mutex* m, unsigned long pid) -///{ -/// // Use current thread's PID if no pid -/// if (pid == 0) { -/// struct Thread* thread = scheduler.rthread; -/// if (m->pid == thread->pid) { -/// atm_release(&m->pid); -/// return 0; -/// } -/// } -/// else if (m->pid == pid) { -/// atm_release(&m->pid); -/// return 0; -/// } -/// return 1; -///} - -struct Mutex* create_mutex(void* addr) -{ - // Ensure aligned to word - Important for Atomic Swap - struct Mutex* m = (struct Mutex*)kmalloc(sizeof(struct Mutex)); - m->addr = addr; - m->pid = 0; - return m; -} diff --git a/src/util/status.c b/src/util/status.c index 5aef915..828dfa3 100644 --- a/src/util/status.c +++ b/src/util/status.c @@ -64,11 +64,6 @@ void status(void) draw_cstring(9, 0, "v", 0x00FFFF); draw_cstring(0, 0, os_name, 0xFF0000); draw_cstring(10, 0, os_info_v, 0x00FFFF); - draw_cstring(16, 0, "# TStacks:", 0xFFDF00); - draw_string(27, 0, " "); - char* st_str = u32_to_str(sched_stack_count); - draw_cstring(27, 0, st_str, 0xFFDF00); - kfree(st_str); // GPU IRQ Statuses output_irq_status(); @@ -81,7 +76,6 @@ void status(void) char* frq_str = u32_to_str(frq); unsigned long fs_len = strlen(frq_str)+1; draw_string(8, 3, frq_str); - kfree(frq_str); draw_string(8+fs_len, 3, "kHz"); // Output the value unsigned long v = read_cntv_tval(); @@ -89,7 +83,6 @@ void status(void) unsigned long vs_len = strlen(v_str) + 1; draw_string(8+fs_len+4, 3, v_str); draw_string(8+fs_len+4 +vs_len, 3, " "); - kfree(v_str); draw_letter(8+fs_len+4 +vs_len+1, 3, '|'); draw_hex32(8+fs_len+7+vs_len, 3, v); @@ -99,12 +92,10 @@ void status(void) gwidth_str = u32_to_str(gwidth); unsigned long gs_len = strlen(gwidth_str) + 1; draw_string(6, 4, gwidth_str); - kfree(gwidth_str); draw_letter(6+gs_len-1, 4, 'x'); gwidth_str = u32_to_str(gheight); unsigned long gs_len1 = strlen(gwidth_str) + 1; draw_string(6+gs_len, 4, gwidth_str); - kfree(gwidth_str); if(gisrgb) draw_string(6+gs_len+gs_len1, 4, "RGB"); else @@ -143,5 +134,4 @@ void status(void) draw_string(19+14+18, 8, " "); char* t_str = u32_to_str(((unsigned long)tval)/1000000); draw_string(19+14+18, 8, t_str); - kfree(t_str); } -- cgit v1.2.1