aboutsummaryrefslogtreecommitdiffstats
path: root/src/gos/gos_x_threads.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gos/gos_x_threads.c')
-rw-r--r--src/gos/gos_x_threads.c144
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