aboutsummaryrefslogtreecommitdiffstats
path: root/src/gos
diff options
context:
space:
mode:
Diffstat (limited to 'src/gos')
-rw-r--r--src/gos/gos_x_heap.c112
-rw-r--r--src/gos/gos_x_threads.c7
-rw-r--r--src/gos/gos_x_threads.h2
-rw-r--r--src/gos/gos_x_threads_cortexm01.h57
-rw-r--r--src/gos/gos_x_threads_cortexm347.h33
-rw-r--r--src/gos/gos_x_threads_cortexm47fp.h37
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