diff options
Diffstat (limited to 'src/gos')
-rw-r--r-- | src/gos/gos_x_heap.c | 112 | ||||
-rw-r--r-- | src/gos/gos_x_threads.c | 7 | ||||
-rw-r--r-- | src/gos/gos_x_threads.h | 2 | ||||
-rw-r--r-- | src/gos/gos_x_threads_cortexm01.h | 57 | ||||
-rw-r--r-- | src/gos/gos_x_threads_cortexm347.h | 33 | ||||
-rw-r--r-- | src/gos/gos_x_threads_cortexm47fp.h | 37 |
6 files changed, 135 insertions, 113 deletions
diff --git a/src/gos/gos_x_heap.c b/src/gos/gos_x_heap.c index 7e79d1c6..813d0199 100644 --- a/src/gos/gos_x_heap.c +++ b/src/gos/gos_x_heap.c @@ -34,7 +34,6 @@ // Slot structure - user memory follows typedef struct memslot { - struct memslot *next; // The next memslot size_t sz; // Includes the size of this memslot. } memslot; @@ -48,13 +47,10 @@ #define Ptr2Slot(p) ((memslot *)(p) - 1) #define Slot2Ptr(pslot) ((pslot)+1) - static memslot * firstSlot; - static memslot * lastSlot; static memslot * freeSlots; static char heap[GFX_OS_HEAP_SIZE]; void _gosHeapInit(void) { - lastSlot = 0; gfxAddHeapBlock(heap, GFX_OS_HEAP_SIZE); } @@ -62,18 +58,12 @@ if (sz < sizeof(memslot)+sizeof(freeslot)) return; - if (lastSlot) - lastSlot->next = (memslot *)ptr; - else - firstSlot = lastSlot = freeSlots = (memslot *)ptr; - - lastSlot->next = 0; - lastSlot->sz = sz; - NextFree(lastSlot) = 0; + ((memslot *)ptr)->sz = sz; + gfxFree(Slot2Ptr((memslot *)ptr)); } void *gfxAlloc(size_t sz) { - register memslot *prev, *p, *new; + register memslot *prev, *p, *pnew; if (!sz) return 0; sz = GetSlotSize(sz); @@ -81,23 +71,22 @@ // Loop till we have a block big enough if (p->sz < sz) continue; + // Can we save some memory by splitting this block? if (p->sz >= sz + sizeof(memslot)+sizeof(freeslot)) { - new = (memslot *)((char *)p + sz); - new->next = p->next; - p->next = new; - new->sz = p->sz - sz; + pnew = (memslot *)((char *)p + sz); + pnew->sz = p->sz - sz; p->sz = sz; - if (lastSlot == p) - lastSlot = new; - NextFree(new) = NextFree(p); - NextFree(p) = new; + NextFree(pnew) = NextFree(p); + NextFree(p) = pnew; } + // Remove it from the free list if (prev) NextFree(prev) = NextFree(p); else freeSlots = NextFree(p); + // Return the result found return Slot2Ptr(p); } @@ -106,7 +95,7 @@ } void *gfxRealloc(void *ptr, size_t oldsz, size_t sz) { - register memslot *prev, *p, *new; + register memslot *prev, *p, *pfree; (void) oldsz; if (!ptr) @@ -120,19 +109,14 @@ sz = GetSlotSize(sz); // If the next slot is free (and contiguous) merge it into this one - if ((char *)p + p->sz == (char *)p->next) { - for (prev = 0, new = freeSlots; new != 0; prev = new, new = NextFree(new)) { - if (new == p->next) { - p->next = new->next; - p->sz += new->sz; - if (prev) - NextFree(prev) = NextFree(new); - else - freeSlots = NextFree(new); - if (lastSlot == new) - lastSlot = p; - break; - } + for (prev = 0, pfree = freeSlots; pfree != 0; prev = pfree, pfree = NextFree(pfree)) { + if (pfree == (memslot *)((char *)p + p->sz)) { + p->sz += pfree->sz; + if (prev) + NextFree(prev) = NextFree(pfree); + else + freeSlots = NextFree(pfree); + break; } } @@ -140,50 +124,54 @@ if (sz < p->sz) { // Can we save some memory by splitting this block? if (p->sz >= sz + sizeof(memslot)+sizeof(freeslot)) { - new = (memslot *)((char *)p + sz); - new->next = p->next; - p->next = new; - new->sz = p->sz - sz; + pfree = (memslot *)((char *)p + sz); + pfree->sz = p->sz - sz; p->sz = sz; - if (lastSlot == p) - lastSlot = new; - NextFree(new) = freeSlots; - freeSlots = new; + NextFree(pfree) = freeSlots; + freeSlots = pfree; } return Slot2Ptr(p); } // We need to do this the hard way - new = gfxAlloc(sz); - if (new) + pfree = gfxAlloc(sz); + if (pfree) return 0; - memcpy(new, ptr, p->sz - sizeof(memslot)); + memcpy(pfree, ptr, p->sz - sizeof(memslot)); gfxFree(ptr); - return new; + return pfree; } void gfxFree(void *ptr) { - register memslot *prev, *p, *new; + register memslot *prev, *p, *pfree; if (!ptr) return; p = Ptr2Slot(ptr); - // If the next slot is free (and contiguous) merge it into this one - if ((char *)p + p->sz == (char *)p->next) { - for (prev = 0, new = freeSlots; new != 0; prev = new, new = NextFree(new)) { - if (new == p->next) { - p->next = new->next; - p->sz += new->sz; - if (prev) - NextFree(prev) = NextFree(new); - else - freeSlots = NextFree(new); - if (lastSlot == new) - lastSlot = p; - break; - } + // Find a free slot that is contiguous precceding and merge it into us + for (prev = 0, pfree = freeSlots; pfree != 0; prev = pfree, pfree = NextFree(pfree)) { + if (p == (memslot *)((char *)pfree + pfree->sz)) { + pfree->sz += p->sz; + if (prev) + NextFree(prev) = NextFree(pfree); + else + freeSlots = NextFree(pfree); + p = pfree; + break; + } + } + + // Find a free slot that is contiguous after and merge it into this one + for (prev = 0, pfree = freeSlots; pfree != 0; prev = pfree, pfree = NextFree(pfree)) { + if (pfree == (memslot *)((char *)p + p->sz)) { + p->sz += pfree->sz; + if (prev) + NextFree(prev) = NextFree(pfree); + else + freeSlots = NextFree(pfree); + break; } } diff --git a/src/gos/gos_x_threads.c b/src/gos/gos_x_threads.c index 7afd224a..b696ee77 100644 --- a/src/gos/gos_x_threads.c +++ b/src/gos/gos_x_threads.c @@ -122,6 +122,7 @@ void gfxSleepMilliseconds(delaytime_t ms) { case TIME_INFINITE: while(1) gfxYield(); + return; } // Convert our delay to ticks @@ -143,6 +144,7 @@ void gfxSleepMicroseconds(delaytime_t ms) { case TIME_INFINITE: while(1) gfxYield(); + return; } // Convert our delay to ticks @@ -212,12 +214,12 @@ static thread mainthread; // The main thread context * If they don't exist compile them to be the standard setjmp() function. * Similarly for longjmp(). */ - #if (!defined(setjmp) && !defined(_setjmp)) || GFX_COMPILER == GFX_COMPILER_KEIL + #if (!defined(setjmp) && !defined(_setjmp)) || GFX_COMPILER == GFX_COMPILER_KEIL || GFX_COMPILER == GFX_COMPILER_MINGW32 || GFX_COMPILER == GFX_COMPILER_MINGW64 #define CXT_SAVE setjmp #else #define CXT_SAVE _setjmp #endif - #if (!defined(longjmp) && !defined(_longjmp)) || GFX_COMPILER == GFX_COMPILER_KEIL + #if (!defined(longjmp) && !defined(_longjmp)) || GFX_COMPILER == GFX_COMPILER_KEIL || GFX_COMPILER == GFX_COMPILER_MINGW32 || GFX_COMPILER == GFX_COMPILER_MINGW64 #define CXT_RESTORE longjmp #else #define CXT_RESTORE _longjmp @@ -346,6 +348,7 @@ static thread mainthread; // The main thread context uint32_t i; // Copy the stack frame + s = 0; #if AUTO_DETECT_STACKFRAME if (STACK_DIR_UP) { // Stack grows up nf = (char *)(t) + sizeof(thread) + sizeof(jmp_buf) + STACK_BASE; diff --git a/src/gos/gos_x_threads.h b/src/gos/gos_x_threads.h index ee7a9cd0..585585c5 100644 --- a/src/gos/gos_x_threads.h +++ b/src/gos/gos_x_threads.h @@ -90,7 +90,7 @@ extern "C" { threadreturn_t gfxThreadWait(gfxThreadHandle thread); gfxThreadHandle gfxThreadMe(void); - /** The following is not part of the public ugfx API has some operating systems + /** The following is not part of the public ugfx API as some operating systems * simply do not provide this capability. * For RAW32 we need it anyway so we might as well declare it here. */ diff --git a/src/gos/gos_x_threads_cortexm01.h b/src/gos/gos_x_threads_cortexm01.h index 8a44bd35..15a90b2a 100644 --- a/src/gos/gos_x_threads_cortexm01.h +++ b/src/gos/gos_x_threads_cortexm01.h @@ -27,8 +27,10 @@ "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" + "mov r4, sp \n\t" + "str r4, %[oldtcxt] \n\t" + "ldr r4, %[newtcxt] \n\t" + "mov sp, r4 \n\t" "pop {r4, r5, r6, r7} \n\t" "mov r8, r4 \n\t" "mov r9, r5 \n\t" @@ -41,15 +43,17 @@ } static __attribute__((pcs("aapcs"),naked)) void _gfxStartThread(thread *oldt, thread *newt) { - newt->cxt = (char *)newt + newt->size; + newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7); __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" + "mov r4, sp \n\t" + "str r4, %[oldtcxt] \n\t" + "ldr r4, %[newtcxt] \n\t" + "mov sp, r4 \n\t" : [newtcxt] "=m" (newt->cxt) : [oldtcxt] "m" (oldt->cxt) : "memory"); @@ -59,8 +63,12 @@ } #elif GFX_COMPILER == GFX_COMPILER_KEIL || GFX_COMPILER == GFX_COMPILER_ARMCC + #define GFX_THREADS_DONE + #define _gfxThreadsInit() static __asm void _gfxTaskSwitch(thread *oldt, thread *newt) { + PRESERVE8 + // Save the old context push {r4, r5, r6, r7, lr} mov r4, r8 @@ -68,10 +76,12 @@ mov r6, r10 mov r7, r11 push {r4, r5, r6, r7} - str sp, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt + mov r4, sp + str r4, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt // Load the new context - ldr sp, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt + ldr r4, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt + mov sp, r4 pop {r4, r5, r6, r7} mov r8, r4 mov r9, r5 @@ -81,11 +91,14 @@ } static __asm void _gfxStartThread(thread *oldt, thread *newt) { + PRESERVE8 + // Calculate where to generate the new context - // newt->cxt = (char *)newt + newt->size; - ldr r2,[r1,#__cpp(offsetof(thread,size))] - add r2,r2,r1 - str r2,[r1,#__cpp(offsetof(thread,cxt))] + // newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7); + ldr r2,[r1,#__cpp(offsetof(thread,size))] + add r2,r2,r1 + and r2, r2, #0xFFFFFFF8 + str r2,[r1,#__cpp(offsetof(thread,cxt))] // Save the old context push {r4, r5, r6, r7, lr} @@ -94,20 +107,24 @@ mov r6, r10 mov r7, r11 push {r4, r5, r6, r7} - str sp, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt + mov r4, sp + str r4, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt // Load the new (imcomplete) context - ldr sp, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt + ldr r4, [r1,#__cpp(offsetof(thread,cxt))] // newt->cxt + mov sp, r4 // Run the users function - we save some code because gfxThreadExit() never returns // gfxThreadExit(_gfxCurrentThread->fn(_gfxCurrentThread->param)); - LDR r2,__cpp(&_gfxCurrentThread) - LDR r2,[r2,#0] - LDR r0,[r2,#__cpp(offsetof(thread,param))] - LDR r1,[r2,#__cpp(offsetof(thread,fn))] - BLX r1 - MOV r4,r0 - BL gfxThreadExit + ldr r2,=__cpp(&_gfxCurrentThread) + ldr r2,[r2,#0] + ldr r0,[r2,#__cpp(offsetof(thread,param))] + ldr r1,[r2,#__cpp(offsetof(thread,fn))] + blx r1 + mov r4,r0 + bl __cpp(gfxThreadExit) + + ALIGN } #else diff --git a/src/gos/gos_x_threads_cortexm347.h b/src/gos/gos_x_threads_cortexm347.h index 03c13052..40d30138 100644 --- a/src/gos/gos_x_threads_cortexm347.h +++ b/src/gos/gos_x_threads_cortexm347.h @@ -32,7 +32,7 @@ } static __attribute__((pcs("aapcs"),naked)) void _gfxStartThread(thread *oldt, thread *newt) { - newt->cxt = (char *)newt + newt->size; + newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7); __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t" "str sp, %[oldtcxt] \n\t" "ldr sp, %[newtcxt] \n\t" @@ -45,8 +45,12 @@ } #elif GFX_COMPILER == GFX_COMPILER_KEIL || GFX_COMPILER == GFX_COMPILER_ARMCC + #define GFX_THREADS_DONE + #define _gfxThreadsInit() static __asm void _gfxTaskSwitch(thread *oldt, thread *newt) { + PRESERVE8 + // Save the old context push {r4, r5, r6, r7, r8, r9, r10, r11, lr} str sp, [r0,#__cpp(offsetof(thread,cxt))] // oldt->cxt @@ -57,11 +61,14 @@ } static __asm void _gfxStartThread(thread *oldt, thread *newt) { + PRESERVE8 + // Calculate where to generate the new context - // newt->cxt = (char *)newt + newt->size; - ldr r2,[r1,#__cpp(offsetof(thread,size))] - add r2,r2,r1 - str r2,[r1,#__cpp(offsetof(thread,cxt))] + // newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7); + ldr r2,[r1,#__cpp(offsetof(thread,size))] + add r2,r2,r1 + and r2, r2, #0xFFFFFFF8 + str r2,[r1,#__cpp(offsetof(thread,cxt))] // Save the old context push {r4, r5, r6, r7, r8, r9, r10, r11, lr} @@ -72,13 +79,15 @@ // Run the users function - we save some code because gfxThreadExit() never returns // gfxThreadExit(_gfxCurrentThread->fn(_gfxCurrentThread->param)); - LDR r2,__cpp(&_gfxCurrentThread) - LDR r2,[r2,#0] - LDR r0,[r2,#__cpp(offsetof(thread,param))] - LDR r1,[r2,#__cpp(offsetof(thread,fn))] - BLX r1 - MOV r4,r0 - BL gfxThreadExit + ldr r2,=__cpp(&_gfxCurrentThread) + ldr r2,[r2,#0] + ldr r0,[r2,#__cpp(offsetof(thread,param))] + ldr r1,[r2,#__cpp(offsetof(thread,fn))] + blx r1 + mov r4,r0 + bl __cpp(gfxThreadExit) + + ALIGN } #else diff --git a/src/gos/gos_x_threads_cortexm47fp.h b/src/gos/gos_x_threads_cortexm47fp.h index 9767ac9a..f5eeff80 100644 --- a/src/gos/gos_x_threads_cortexm47fp.h +++ b/src/gos/gos_x_threads_cortexm47fp.h @@ -12,10 +12,6 @@ * 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 - #if GFX_COMPILER == GFX_COMPILER_GCC || GFX_COMPILER == GFX_COMPILER_CYGWIN || GFX_COMPILER == GFX_COMPILER_MINGW32 || GFX_COMPILER == GFX_COMPILER_MINGW64 #define GFX_THREADS_DONE #define _gfxThreadsInit() @@ -33,7 +29,7 @@ } static __attribute__((pcs("aapcs-vfp"),naked)) void _gfxStartThread(thread *oldt, thread *newt) { - newt->cxt = (char *)newt + newt->size; + newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7); __asm__ volatile ( "push {r4, r5, r6, r7, r8, r9, r10, r11, lr} \n\t" "vpush {s16-s31} \n\t" "str sp, %[oldtcxt] \n\t" @@ -47,8 +43,12 @@ } #elif GFX_COMPILER == GFX_COMPILER_KEIL || GFX_COMPILER == GFX_COMPILER_ARMCC + #define GFX_THREADS_DONE + #define _gfxThreadsInit() static __asm void _gfxTaskSwitch(thread *oldt, thread *newt) { + PRESERVE8 + // Save the old context push {r4, r5, r6, r7, r8, r9, r10, r11, lr} vpush {s16-s31} @@ -61,11 +61,14 @@ } static __asm void _gfxStartThread(thread *oldt, thread *newt) { + PRESERVE8 + // Calculate where to generate the new context - // newt->cxt = (char *)newt + newt->size; - ldr r2,[r1,#__cpp(offsetof(thread,size))] - add r2,r2,r1 - str r2,[r1,#__cpp(offsetof(thread,cxt))] + // newt->cxt = (void *)(((unsigned)newt + newt->size) & ~7); + ldr r2,[r1,#__cpp(offsetof(thread,size))] + add r2,r2,r1 + and r2, r2, #0xFFFFFFF8 + str r2,[r1,#__cpp(offsetof(thread,cxt))] // Save the old context push {r4, r5, r6, r7, r8, r9, r10, r11, lr} @@ -77,13 +80,15 @@ // Run the users function - we save some code because gfxThreadExit() never returns // gfxThreadExit(_gfxCurrentThread->fn(_gfxCurrentThread->param)); - LDR r2,__cpp(&_gfxCurrentThread) - LDR r2,[r2,#0] - LDR r0,[r2,#__cpp(offsetof(thread,param))] - LDR r1,[r2,#__cpp(offsetof(thread,fn))] - BLX r1 - MOV r4,r0 - BL gfxThreadExit + ldr r2,=__cpp(&_gfxCurrentThread) + ldr r2,[r2,#0] + ldr r0,[r2,#__cpp(offsetof(thread,param))] + ldr r1,[r2,#__cpp(offsetof(thread,fn))] + blx r1 + mov r4,r0 + bl __cpp(gfxThreadExit) + + ALIGN } #else |