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;