Fixes to the Raw32 threading.
Optimisation of the RAM it uses for stack frame autodetection.remotes/origin_old/ugfx_release_2.6
parent
983342b001
commit
0c854f099f
117
src/gos/raw32.c
117
src/gos/raw32.c
|
@ -403,24 +403,32 @@ void gfxSleepMicroseconds(delaytime_t ms) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There are some compilers we know how they store the jmpbuf. For those
|
* There are some compilers we know how they store the jmpbuf. For those
|
||||||
* we can use the constant MASK1 and MASK2. For others we have to "auto-detect".
|
* we can use the constant macro definitions. For others we have to "auto-detect".
|
||||||
* Auto-detection is hairy and there is no guarantee it will work on all architectures.
|
* Auto-detection is hairy and there is no guarantee it will work on all architectures.
|
||||||
* For those it doesn't - read the compiler manuals and the library source code to
|
* For those it doesn't - read the compiler manuals and the library source code to
|
||||||
* work out the correct MASK values.
|
* work out the correct macro values.
|
||||||
* Using the debugger to work out the values for your compiler and putting them here
|
* You can use the debugger to work out the values for your compiler and put them here.
|
||||||
* also saves a nice block of RAM.
|
* Defining these macros as constant values makes the system behaviour guaranteed but also
|
||||||
|
* makes your code compiler and cpu architecture dependant.
|
||||||
*/
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
#define STACK_DIR_UP FALSE // usually false as most stacks grow down
|
// Define your compiler constant values here.
|
||||||
#define MASK1 somevalue1
|
// These example values are for mingw32 compiler (x86).
|
||||||
#define MASK2 somevalue2 // optional
|
#define AUTO_DETECT_MASK FALSE
|
||||||
#define STACK_BASE someindex
|
#define STACK_DIR_UP FALSE
|
||||||
|
#define MASK1 0x00000011
|
||||||
|
#define MASK2 0x00000000
|
||||||
|
#define STACK_BASE 9
|
||||||
#else
|
#else
|
||||||
#define AUTO_DETECT_MASK TRUE
|
#define AUTO_DETECT_MASK TRUE
|
||||||
#define STACK_DIR_UP stackdirup
|
#define STACK_DIR_UP stackdirup // TRUE if the stack grow up instead of down
|
||||||
#define MASK1 jmpmask1
|
#define MASK1 jmpmask1 // The 1st mask of jmp_buf elements that need relocation
|
||||||
#define MASK2 jmpmask2
|
#define MASK2 jmpmask2 // The 2nd mask of jmp_buf elements that need relocation
|
||||||
#define STACK_BASE stackbase
|
#define STACK_BASE stackbase // The base of the stack frame relative to the local variables
|
||||||
|
static bool_t stackdirup;
|
||||||
|
static uint32_t jmpmask1;
|
||||||
|
static uint32_t jmpmask2;
|
||||||
|
static size_t stackbase;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <setjmp.h> /* jmp_buf, setjmp(), longjmp() */
|
#include <setjmp.h> /* jmp_buf, setjmp(), longjmp() */
|
||||||
|
@ -473,7 +481,7 @@ static void Qinit(threadQ * q) {
|
||||||
|
|
||||||
static void Qadd(threadQ * q, thread *t) {
|
static void Qadd(threadQ * q, thread *t) {
|
||||||
t->next = 0;
|
t->next = 0;
|
||||||
if (q->tail) {
|
if (q->head) {
|
||||||
q->tail->next = t;
|
q->tail->next = t;
|
||||||
q->tail = t;
|
q->tail = t;
|
||||||
} else
|
} else
|
||||||
|
@ -491,47 +499,27 @@ static thread *Qpop(threadQ * q) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if AUTO_DETECT_MASK
|
#if AUTO_DETECT_MASK
|
||||||
static char * lowptr; // A pointer to somewhere low in the stack frame
|
// The structure for the saved stack frame information
|
||||||
static char * highptr; // A pointer to somewhere high in the stack frame
|
|
||||||
|
|
||||||
// The saved information on a stack frame
|
|
||||||
typedef struct saveloc {
|
typedef struct saveloc {
|
||||||
char * localptr;
|
char * localptr;
|
||||||
jmp_buf cxt;
|
jmp_buf cxt;
|
||||||
} saveloc;
|
} saveloc;
|
||||||
|
|
||||||
static saveloc infn; // The saved stack frame info inside a function
|
// A pointer to our auto-detection buffer.
|
||||||
static saveloc outfn; // The saved stack frame info outside a function
|
static saveloc *pframeinfo;
|
||||||
static saveloc *saveptr; // Which saved stack frame variable we are currently using
|
|
||||||
|
|
||||||
// Where we save all the information
|
|
||||||
static bool_t stackdirup; // TRUE if the stack grow up instead of down
|
|
||||||
static uint32_t jmpmask1; // The 1st mask of jmp_buf elements that need relocation
|
|
||||||
static uint32_t jmpmask2; // The 2nd mask of jmp_buf elements that need relocation
|
|
||||||
static size_t stackbase; // The base of the stack frame relative to the local variables
|
|
||||||
|
|
||||||
/* These functions are not static to prevent the compiler removing them as functions */
|
/* These functions are not static to prevent the compiler removing them as functions */
|
||||||
|
|
||||||
void get_highptr(void) {
|
|
||||||
char c;
|
|
||||||
highptr = &c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_stack(void) {
|
|
||||||
char c;
|
|
||||||
saveptr->localptr = (char *)&c;
|
|
||||||
_setjmp(saveptr->cxt);
|
|
||||||
get_highptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_stack_state(void) {
|
void get_stack_state(void) {
|
||||||
char c;
|
char c;
|
||||||
lowptr = &c;
|
pframeinfo->localptr = (char *)&c;
|
||||||
test_stack();
|
_setjmp(pframeinfo->cxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_stack_state_in_fn(void) {
|
void get_stack_state_in_fn(void) {
|
||||||
|
pframeinfo++;
|
||||||
get_stack_state();
|
get_stack_state();
|
||||||
|
pframeinfo--;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -545,28 +533,32 @@ static void _gosThreadsInit(void) {
|
||||||
current->param = 0;
|
current->param = 0;
|
||||||
|
|
||||||
#if AUTO_DETECT_MASK
|
#if AUTO_DETECT_MASK
|
||||||
// Get details of the stack frame from within a function
|
|
||||||
saveptr = &infn;
|
|
||||||
get_stack_state_in_fn();
|
|
||||||
|
|
||||||
// Get details of the stack frame outside the function
|
|
||||||
saveptr = &outfn;
|
|
||||||
get_stack_state();
|
|
||||||
|
|
||||||
/* stack direction */
|
|
||||||
stackdirup = highptr > lowptr; // Can we also test infn.localptr > outfn.localptr?
|
|
||||||
|
|
||||||
/* study the jump buffer */
|
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
char ** pout;
|
char ** pout;
|
||||||
char ** pin;
|
char ** pin;
|
||||||
size_t diff = outfn.localptr - infn.localptr;
|
size_t diff;
|
||||||
char * min_frame = outfn.localptr;
|
char * framebase;
|
||||||
|
|
||||||
|
// Allocate a buffer to store our test data
|
||||||
|
pframeinfo = (saveloc *)gfxAlloc(sizeof(saveloc)*2);
|
||||||
|
|
||||||
|
// Get details of the stack frame from within a function
|
||||||
|
get_stack_state_in_fn();
|
||||||
|
|
||||||
|
// Get details of the stack frame outside the function
|
||||||
|
get_stack_state();
|
||||||
|
|
||||||
|
/* stack direction */
|
||||||
|
stackdirup = pframeinfo[1].localptr > pframeinfo[0].localptr;
|
||||||
|
|
||||||
|
/* study the jump buffer */
|
||||||
|
diff = pframeinfo[0].localptr - pframeinfo[1].localptr;
|
||||||
|
framebase = pframeinfo[0].localptr;
|
||||||
|
|
||||||
/* following line views jump buffer as array of long int */
|
/* following line views jump buffer as array of long int */
|
||||||
pout = (char **)outfn.cxt;
|
pout = (char **)pframeinfo[0].cxt;
|
||||||
pin = (char **)infn.cxt;
|
pin = (char **)pframeinfo[1].cxt;
|
||||||
|
|
||||||
jmpmask1 = jmpmask2 = 0;
|
jmpmask1 = jmpmask2 = 0;
|
||||||
if (diff) {
|
if (diff) {
|
||||||
|
@ -579,12 +571,12 @@ static void _gosThreadsInit(void) {
|
||||||
jmpmask2 |= 1 << (i-32);
|
jmpmask2 |= 1 << (i-32);
|
||||||
|
|
||||||
if (stackdirup) {
|
if (stackdirup) {
|
||||||
if (min_frame > *pout) {
|
if (framebase > *pout) {
|
||||||
min_frame = *pout;
|
framebase = *pout;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (min_frame < *pout) {
|
if (framebase < *pout) {
|
||||||
min_frame = *pout;
|
framebase = *pout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -592,10 +584,11 @@ static void _gosThreadsInit(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stackdirup) {
|
if (stackdirup) {
|
||||||
stackbase = outfn.localptr - min_frame;
|
stackbase = pframeinfo[0].localptr - framebase;
|
||||||
} else {
|
} else {
|
||||||
stackbase = min_frame - outfn.localptr;
|
stackbase = framebase - pframeinfo[0].localptr;
|
||||||
}
|
}
|
||||||
|
gfxFree(pframeinfo);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue