Mercurial > nand-ecoscentric
comparison packages/kernel/current/include/thread.inl @ 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 | 6b5f480c6929 |
| children | e2d866e32dac |
comparison
equal
deleted
inserted
replaced
| 146:bd918119cf0b | 147:d397fc472bcf |
|---|---|
| 84 inline void Cyg_HardwareThread::check_stack(void) | 84 inline void Cyg_HardwareThread::check_stack(void) |
| 85 { | 85 { |
| 86 cyg_uint32 sig = (cyg_uint32)this; | 86 cyg_uint32 sig = (cyg_uint32)this; |
| 87 cyg_uint32 *base = (cyg_uint32 *)get_stack_base(); | 87 cyg_uint32 *base = (cyg_uint32 *)get_stack_base(); |
| 88 cyg_uint32 *top = (cyg_uint32 *)(stack_base + stack_size); | 88 cyg_uint32 *top = (cyg_uint32 *)(stack_base + stack_size); |
| 89 unsigned int i; | 89 cyg_ucount32 i; |
| 90 | 90 |
| 91 CYG_ASSERT( 0 == (3 & (cyg_uint32)base), "stack base not word aligned" ); | 91 CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)base), "stack base not word aligned" ); |
| 92 CYG_ASSERT( 0 == (3 & (cyg_uint32)top), "stack top not word aligned" ); | 92 CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)top), "stack top not word aligned" ); |
| 93 | 93 |
| 94 CYG_ASSERT( (cyg_uint32)stack_ptr > (cyg_uint32)stack_base, | 94 CYG_ASSERT( (cyg_uint32)stack_ptr > (cyg_uint32)stack_base, |
| 95 "Stack_ptr below base" ); | 95 "Stack_ptr below base" ); |
| 96 CYG_ASSERT( (cyg_uint32)stack_ptr <= ((cyg_uint32)stack_base + stack_size), | 96 CYG_ASSERT( (cyg_uint32)stack_ptr <= ((cyg_uint32)stack_base + stack_size), |
| 97 "Stack_ptr above top" ); | 97 "Stack_ptr above top" ); |
| 100 i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32); | 100 i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32); |
| 101 i++ ) { | 101 i++ ) { |
| 102 CYG_ASSERT( (sig ^ (i * 0x01010101)) == base[i], "Stack base corrupt" ); | 102 CYG_ASSERT( (sig ^ (i * 0x01010101)) == base[i], "Stack base corrupt" ); |
| 103 CYG_ASSERT( (sig ^ (i * 0x10101010)) == top[i], "Stack top corrupt" ); | 103 CYG_ASSERT( (sig ^ (i * 0x10101010)) == top[i], "Stack top corrupt" ); |
| 104 } | 104 } |
| 105 | |
| 106 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT | |
| 107 // we won't have added check data above the stack limit if it hasn't | |
| 108 // been incremented | |
| 109 if (stack_limit != stack_base) { | |
| 110 CYG_ADDRESS limit = stack_limit; | |
| 111 // the limit will be off by the check data size, so lets correct it | |
| 112 limit -= CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE; | |
| 113 | |
| 114 // determine base of check data by rounding up to nearest word aligned | |
| 115 // address if not already aligned | |
| 116 cyg_uint32 *p = (cyg_uint32 *)((limit + 3) & ~3); | |
| 117 // i.e. + sizeof(cyg_uint32)-1) & ~(sizeof(cyg_uint32)-1); | |
| 118 | |
| 119 for ( i = 0; | |
| 120 i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32); | |
| 121 i++ ) { | |
| 122 CYG_ASSERT( (sig ^ (i * 0x01010101)) == p[i], | |
| 123 "Gap between stack limit and base corrupt" ); | |
| 124 } | |
| 125 } | |
| 126 #endif | |
| 127 } | |
| 128 #endif | |
| 129 | |
| 130 // ------------------------------------------------------------------------- | |
| 131 // Measure the stack usage of the thread | |
| 132 #ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT | |
| 133 inline cyg_uint32 Cyg_HardwareThread::measure_stack_usage(void) | |
| 134 { | |
| 135 CYG_WORD *base = (CYG_WORD *)stack_base; | |
| 136 cyg_uint32 size = stack_size/sizeof(CYG_WORD); | |
| 137 cyg_ucount32 i; | |
| 138 | |
| 139 // Work up the stack comparing with the preset value | |
| 140 // We assume the stack grows downwards, hmm... | |
| 141 for (i=0; i<size; i++) { | |
| 142 if (base[i] != 0xDEADBEEF) | |
| 143 break; | |
| 144 } | |
| 145 return (size - i)*sizeof(CYG_WORD); | |
| 105 } | 146 } |
| 106 #endif | 147 #endif |
| 107 | 148 |
| 108 // ------------------------------------------------------------------------- | 149 // ------------------------------------------------------------------------- |
| 109 // Attach a stack to this thread. If there is a HAL defined macro to | 150 // Attach a stack to this thread. If there is a HAL defined macro to |
| 122 cyg_uint32 *top = (cyg_uint32 *)(s_base + s_size - | 163 cyg_uint32 *top = (cyg_uint32 *)(s_base + s_size - |
| 123 CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE); | 164 CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE); |
| 124 | 165 |
| 125 unsigned int i; | 166 unsigned int i; |
| 126 | 167 |
| 127 CYG_ASSERT( 0 == (3 & (cyg_uint32)base), "stack base alignment" ); | 168 CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)base), "stack base alignment" ); |
| 128 CYG_ASSERT( 0 == (3 & (cyg_uint32)top), "stack top alignment" ); | 169 CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)top), "stack top alignment" ); |
| 129 | 170 |
| 130 for ( i = 0; | 171 for ( i = 0; |
| 131 i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32); | 172 i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32); |
| 132 i++ ) { | 173 i++ ) { |
| 133 base[i] = (sig ^ (i * 0x01010101)); | 174 base[i] = (sig ^ (i * 0x01010101)); |
| 143 // this might go badly wrong. It would not detect wrap of unsigned size. | 184 // this might go badly wrong. It would not detect wrap of unsigned size. |
| 144 CYG_ASSERT( s_size >= 256, | 185 CYG_ASSERT( s_size >= 256, |
| 145 "Stack size too small after allocating checking buffer"); | 186 "Stack size too small after allocating checking buffer"); |
| 146 } | 187 } |
| 147 #endif | 188 #endif |
| 148 | 189 #ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT |
| 190 { | |
| 191 CYG_WORD *base = (CYG_WORD *)s_base; | |
| 192 cyg_uint32 size = s_size/sizeof(CYG_WORD); | |
| 193 cyg_ucount32 i; | |
| 194 | |
| 195 // initialize all of stack with known value - don't choose 0 | |
| 196 // could do with pseudo value as above, but this way, checking | |
| 197 // is faster | |
| 198 for (i=0; i<size; i++) { | |
| 199 base[i] = 0xDEADBEEF; | |
| 200 } | |
| 201 // Don't bother about the case when the stack isn't a multiple of | |
| 202 // CYG_WORD in size. Since it's at the top of the stack, it will | |
| 203 // almost certainly be overwritten the instant the thread starts | |
| 204 // anyway. | |
| 205 } | |
| 206 #endif | |
| 149 stack_base = s_base; | 207 stack_base = s_base; |
| 150 stack_size = s_size; | 208 stack_size = s_size; |
| 151 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT | 209 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT |
| 152 stack_limit = s_base; | 210 stack_limit = s_base; |
| 153 #endif | 211 #endif |
| 267 // Allocate some memory at the lower end of the stack | 325 // Allocate some memory at the lower end of the stack |
| 268 // by moving the stack limit pointer. | 326 // by moving the stack limit pointer. |
| 269 | 327 |
| 270 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT | 328 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT |
| 271 | 329 |
| 272 inline void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size) | 330 #ifndef CYGFUN_KERNEL_THREADS_STACK_CHECKING |
| 273 { | 331 // if stack checking, implementation is in thread.cxx |
| 332 inline void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size ) | |
| 333 { | |
| 334 void *ret = (void *)stack_limit; | |
| 274 stack_limit += size; | 335 stack_limit += size; |
| 275 return (void *)(stack_limit - size); | 336 return ret; |
| 276 } | 337 } |
| 277 | 338 #endif |
| 278 | 339 |
| 279 inline CYG_ADDRESS | 340 inline CYG_ADDRESS |
| 280 Cyg_HardwareThread::get_stack_limit() | 341 Cyg_HardwareThread::get_stack_limit() |
| 281 { | 342 { |
| 282 return stack_limit; | 343 return stack_limit; |
