Mercurial > flash_v2
diff packages/kernel/current/src/common/thread.cxx @ 147:d397fc472bcf
Merge from eCos master repository on 2001-01-05-06:43:02-GMT
| author | jlarmour |
|---|---|
| date | Fri, 05 Jan 2001 17:12:36 +0000 |
| parents | 0ae0bc38e387 |
| children | 25e238959bae |
line wrap: on
line diff
--- a/packages/kernel/current/src/common/thread.cxx +++ b/packages/kernel/current/src/common/thread.cxx @@ -60,6 +60,10 @@ #include <cyg/kernel/sched.inl> // scheduler inlines #include <cyg/kernel/clock.inl> // clock inlines +#ifdef CYGDBG_KERNEL_THREADS_STACK_MEASUREMENT_VERBOSE_EXIT +#include <cyg/infra/diag.h> +#endif + // ========================================================================= // Cyg_HardwareThread members @@ -302,6 +306,9 @@ Cyg_Thread::check_this( cyg_assert_class // of the executing thread. if( (stack_ptr > (stack_base + stack_size)) || (stack_ptr < stack_base) ) return false; +#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT + if( stack_ptr < stack_limit ) return false; +#endif case cyg_trivial: case cyg_none: default: @@ -718,6 +725,11 @@ Cyg_Thread::exit() Cyg_Thread *self = Cyg_Thread::self(); +#ifdef CYGDBG_KERNEL_THREADS_STACK_MEASUREMENT_VERBOSE_EXIT + diag_printf( "Stack usage for thread %08x: %d\n", self, + self->measure_stack_usage() ); +#endif + Cyg_Scheduler::lock(); // clear the timer; if there was none, no worries. @@ -1031,6 +1043,56 @@ void Cyg_Thread::free_data_index( cyg_uc #endif +// ------------------------------------------------------------------------- +// Allocate some memory at the lower end of the stack +// by moving the stack limit pointer. + +#if defined(CYGFUN_KERNEL_THREADS_STACK_LIMIT) && \ + defined(CYGFUN_KERNEL_THREADS_STACK_CHECKING) +// if not doing stack checking, implementation can be found in thread.inl +// This implementation puts the magic buffer area (to watch for overruns +// *above* the stack limit, i.e. there is no official demarcation between +// the stack and the buffer. But that's okay if you think about it... having +// a demarcation would not accomplish anything more. +void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size ) +{ + void *ret = (void *)stack_limit; + + // First lock the scheduler because we're going to be tinkering with + // the check data + Cyg_Scheduler::lock(); + + // if we've inc'd the limit before, it will be off by the check data + // size, so lets correct it + if (stack_limit != stack_base) + stack_limit -= CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE; + stack_limit += size; + + // determine base of check data by rounding up to nearest word aligned + // address if not already aligned + cyg_uint32 *p = (cyg_uint32 *)((stack_limit + 3) & ~3); + // i.e. + sizeof(cyg_uint32)-1) & ~(sizeof(cyg_uint32)-1); + cyg_ucount32 i; + cyg_uint32 sig = (cyg_uint32)this; + + for ( i = 0; + i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32); + i++ ) { + p[i] = (sig ^ (i * 0x01010101)); + } + + // increment limit by the check size. Note this will not necessarily + // reach the end of the check data. But that doesn't really matter. + // Doing this allows better checking of the saved stack pointer in + // Cyg_Thread::check_this() + stack_limit += CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE; + + Cyg_Scheduler::unlock(); + + return ret; +} +#endif + // ========================================================================= // Cyg_ThreadTimer member functions
