diff options
Diffstat (limited to 'src/gos/gos_x_threads.c')
-rw-r--r-- | src/gos/gos_x_threads.c | 144 |
1 files changed, 22 insertions, 122 deletions
diff --git a/src/gos/gos_x_threads.c b/src/gos/gos_x_threads.c index 4fc66588..7afd224a 100644 --- a/src/gos/gos_x_threads.c +++ b/src/gos/gos_x_threads.c @@ -122,7 +122,6 @@ void gfxSleepMilliseconds(delaytime_t ms) { case TIME_INFINITE: while(1) gfxYield(); - return; } // Convert our delay to ticks @@ -144,7 +143,6 @@ void gfxSleepMicroseconds(delaytime_t ms) { case TIME_INFINITE: while(1) gfxYield(); - return; } // Convert our delay to ticks @@ -188,121 +186,22 @@ typedef struct threadQ { static threadQ readyQ; // The list of ready threads static threadQ deadQ; // Where we put threads waiting to be deallocated -static thread * current; // The current running thread +thread * _gfxCurrentThread; // The current running thread - unfortunately this has to be non-static for the keil compiler static thread mainthread; // The main thread context -#if GFX_CPU == GFX_CPU_CORTEX_M0 || GFX_CPU == GFX_CPU_CORTEX_M1 - - // Use the EABI calling standard (ARM's AAPCS) - Save r4 - r11 - // The context is saved at the current stack location and a pointer is maintained in the thread structure. - - #define _gfxThreadsInit() - - static __attribute__((pcs("aapcs"),naked)) void _gfxTaskSwitch(thread *oldt, thread *newt) { - __asm__ volatile ( "push {r4, r5, r6, r7, lr} \n\t" - "mov r4, r8 \n\t" - "mov r5, r9 \n\t" - "mov r6, r10 \n\t" - "mov r7, r11 \n\t" - "push {r4, r5, r6, r7} \n\t" - "str sp, %[oldtcxt] \n\t" - "ldr sp, %[newtcxt] \n\t" - "pop {r4, r5, r6, r7} \n\t" - "mov r8, r4 \n\t" - "mov r9, r5 \n\t" - "mov r10, r6 \n\t" - "mov r11, r7 \n\t" - "pop {r4, r5, r6, r7, pc} \n\t" - : [newtcxt] "=m" (newt->cxt) - : [oldtcxt] "m" (oldt->cxt) - : "memory"); - } - - static __attribute__((pcs("aapcs"),naked)) void _gfxStartThread(thread *oldt, thread *newt) { - newt->cxt = (char *)newt + newt->size; - __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t" // save current context - "str sp, %[oldtcxt] \n\t" // save context pointer - "ldr sp, %[newtcxt] \n\t" // load new context pointer - : [newtcxt] "=m" (newt->cxt) - : [oldtcxt] "m" (oldt->cxt) - : "memory"); - - // Run the users function - gfxThreadExit(current->fn(current->param)); - } +#undef GFX_THREADS_DONE +#if GFX_CPU == GFX_CPU_CORTEX_M0 || GFX_CPU == GFX_CPU_CORTEX_M1 + #include "gos_x_threads_cortexm01.h" #elif GFX_CPU == GFX_CPU_CORTEX_M3 || GFX_CPU == GFX_CPU_CORTEX_M4 || GFX_CPU == GFX_CPU_CORTEX_M7 - - // Use the EABI calling standard (ARM's AAPCS) - Save r4 - r11 - // The context is saved at the current stack location and a pointer is maintained in the thread structure. - - #if CORTEX_USE_FPU - #warning "GOS Threads: You have specified GFX_CPU=GFX_CPU_CORTX_M? with no hardware floating point support but CORTEX_USE_FPU is TRUE. Try using GFX_CPU_GFX_CPU_CORTEX_M?_FP instead" - #endif - - #define _gfxThreadsInit() - - static __attribute__((pcs("aapcs"),naked)) void _gfxTaskSwitch(thread *oldt, thread *newt) { - __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t" - "str sp, %[oldtcxt] \n\t" - "ldr sp, %[newtcxt] \n\t" - "pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} \n\t" - : [newtcxt] "=m" (newt->cxt) - : [oldtcxt] "m" (oldt->cxt) - : "memory"); - } - - static __attribute__((pcs("aapcs"),naked)) void _gfxStartThread(thread *oldt, thread *newt) { - newt->cxt = (char *)newt + newt->size; - __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t" - "str sp, %[oldtcxt] \n\t" - "ldr sp, %[newtcxt] \n\t" - : [newtcxt] "=m" (newt->cxt) - : [oldtcxt] "m" (oldt->cxt) - : "memory"); - - // Run the users function - gfxThreadExit(current->fn(current->param)); - } - + #include "gos_x_threads_cortexm347.h" #elif GFX_CPU == GFX_CPU_CORTEX_M4_FP || GFX_CPU == GFX_CPU_CORTEX_M7_FP + #include "gos_x_threads_cortexm47fp.h" +#endif - // Use the EABI calling standard (ARM's AAPCS) - Save r4 - r11 and floating point - // The context is saved at the current stack location and a pointer is maintained in the thread structure. - - #if !CORTEX_USE_FPU - #warning "GOS Threads: You have specified GFX_CPU=GFX_CPU_CORTX_M?_FP with hardware floating point support but CORTEX_USE_FPU is FALSE. Try using GFX_CPU_GFX_CPU_CORTEX_M? instead" - #endif - - #define _gfxThreadsInit() - - static __attribute__((pcs("aapcs-vfp"),naked)) void _gfxTaskSwitch(thread *oldt, thread *newt) { - __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t" - "vpush {s16-s31} \n\t" - "str sp, %[oldtcxt] \n\t" - "ldr sp, %[newtcxt] \n\t" - "vpop {s16-s31} \n\t" - "pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} \n\t" - : [newtcxt] "=m" (newt->cxt) - : [oldtcxt] "m" (oldt->cxt) - : "memory"); - } - - static __attribute__((pcs("aapcs-vfp"),naked)) void _gfxStartThread(thread *oldt, thread *newt) { - newt->cxt = (char *)newt + newt->size; - __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t" - "vpush {s16-s31} \n\t" - "str sp, %[oldtcxt] \n\t" - "ldr sp, %[newtcxt] \n\t" - : [newtcxt] "=m" (newt->cxt) - : [oldtcxt] "m" (oldt->cxt) - : "memory"); - - // Run the users function - gfxThreadExit(current->fn(current->param)); - } +#ifndef GFX_THREADS_DONE + #define GFX_THREADS_DONE -#else #include <string.h> // Prototype for memcpy() #include <setjmp.h> @@ -500,7 +399,7 @@ static thread mainthread; // The main thread context // as we are on a different stack. // Run the users function. - gfxThreadExit(current->fn(current->param)); + gfxThreadExit(_gfxCurrentThread->fn(_gfxCurrentThread->param)); // We never get here as gfxThreadExit() never returns } @@ -516,6 +415,7 @@ static thread mainthread; // The main thread context #define _gfxTaskSwitch(oldt, newt) _gfxXSwitch(oldt, newt, FALSE) #define _gfxStartThread(oldt, newt) _gfxXSwitch(oldt, newt, TRUE) #endif +#undef GFX_THREADS_DONE static void Qinit(threadQ * q) { q->head = q->tail = 0; @@ -551,11 +451,11 @@ void _gosThreadsInit(void) { _gfxThreadsInit(); - current = &mainthread; + _gfxCurrentThread = &mainthread; } gfxThreadHandle gfxThreadMe(void) { - return (gfxThreadHandle)current; + return (gfxThreadHandle)_gfxCurrentThread; } // Check if there are dead processes to deallocate @@ -576,9 +476,9 @@ void gfxYield(void) { if (!readyQ.head) return; - Qadd(&readyQ, me = current); - current = Qpop(&readyQ); - _gfxTaskSwitch(me, current); + Qadd(&readyQ, me = _gfxCurrentThread); + _gfxCurrentThread = Qpop(&readyQ); + _gfxTaskSwitch(me, _gfxCurrentThread); } // This routine is not currently public - but it could be. @@ -586,7 +486,7 @@ void gfxThreadExit(threadreturn_t ret) { thread *me; // Save the results in case someone is waiting - me = current; + me = _gfxCurrentThread; me->param = (void *)ret; me->flags |= FLG_THD_DEAD; @@ -596,11 +496,11 @@ void gfxThreadExit(threadreturn_t ret) { Qadd(&deadQ, me); // Set the next thread. Exit if it was the last thread - if (!(current = Qpop(&readyQ))) + if (!(_gfxCurrentThread = Qpop(&readyQ))) gfxExit(); // Switch to the new thread - _gfxTaskSwitch(me, current); + _gfxTaskSwitch(me, _gfxCurrentThread); // We never get back here as we didn't re-queue ourselves } @@ -630,9 +530,9 @@ gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_ t->param = param; // Add the current thread to the queue because we are starting a new thread. - me = current; + me = _gfxCurrentThread; Qadd(&readyQ, me); - current = t; + _gfxCurrentThread = t; _gfxStartThread(me, t); @@ -644,7 +544,7 @@ threadreturn_t gfxThreadWait(gfxThreadHandle th) { thread * t; t = th; - if (t == current) + if (t == _gfxCurrentThread) return -1; // Mark that we are waiting |