comparison packages/kernel/current/include/thread.inl @ 143:6b5f480c6929 ecos-sw-2000-12-08

Merge from eCos master repository on 2000-12-08-02:09:36-GMT
author jlarmour
date Fri, 08 Dec 2000 03:30:06 +0000
parents 6ed91473a1cd
children d397fc472bcf
comparison
equal deleted inserted replaced
142:12eccf9656f3 143:6b5f480c6929
54 #include <cyg/kernel/thread.hxx> 54 #include <cyg/kernel/thread.hxx>
55 #include <cyg/hal/hal_arch.h> 55 #include <cyg/hal/hal_arch.h>
56 56
57 #include <cyg/kernel/clock.inl> 57 #include <cyg/kernel/clock.inl>
58 58
59 #ifndef CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE
60 #define CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE (0)
61 #endif
62
59 //========================================================================== 63 //==========================================================================
60 // Inlines for Cyg_HardwareThread 64 // Inlines for Cyg_HardwareThread
65
66 // -------------------------------------------------------------------------
67 // get the size/base of this thread's stack
68
69 inline CYG_ADDRESS
70 Cyg_HardwareThread::get_stack_base()
71 {
72 return stack_base - CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
73 }
74
75 inline cyg_uint32
76 Cyg_HardwareThread::get_stack_size()
77 {
78 return stack_size + 2 * CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
79 }
80
81 // -------------------------------------------------------------------------
82 // Check the stack bounds of this thread:
83 #ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
84 inline void Cyg_HardwareThread::check_stack(void)
85 {
86 cyg_uint32 sig = (cyg_uint32)this;
87 cyg_uint32 *base = (cyg_uint32 *)get_stack_base();
88 cyg_uint32 *top = (cyg_uint32 *)(stack_base + stack_size);
89 unsigned int i;
90
91 CYG_ASSERT( 0 == (3 & (cyg_uint32)base), "stack base not word aligned" );
92 CYG_ASSERT( 0 == (3 & (cyg_uint32)top), "stack top not word aligned" );
93
94 CYG_ASSERT( (cyg_uint32)stack_ptr > (cyg_uint32)stack_base,
95 "Stack_ptr below base" );
96 CYG_ASSERT( (cyg_uint32)stack_ptr <= ((cyg_uint32)stack_base + stack_size),
97 "Stack_ptr above top" );
98
99 for ( i = 0;
100 i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
101 i++ ) {
102 CYG_ASSERT( (sig ^ (i * 0x01010101)) == base[i], "Stack base corrupt" );
103 CYG_ASSERT( (sig ^ (i * 0x10101010)) == top[i], "Stack top corrupt" );
104 }
105 }
106 #endif
61 107
62 // ------------------------------------------------------------------------- 108 // -------------------------------------------------------------------------
63 // Attach a stack to this thread. If there is a HAL defined macro to 109 // Attach a stack to this thread. If there is a HAL defined macro to
64 // do this, then we use that, otherwise assume a falling stack. 110 // do this, then we use that, otherwise assume a falling stack.
65 inline void Cyg_HardwareThread::attach_stack(CYG_ADDRESS s_base, cyg_uint32 s_size) 111 inline void Cyg_HardwareThread::attach_stack(CYG_ADDRESS s_base, cyg_uint32 s_size)
66 { 112 {
67 #ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM 113 #ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM
68 CYG_ASSERT( s_size >= CYGNUM_HAL_STACK_SIZE_MINIMUM, 114 CYG_ASSERT( s_size >= CYGNUM_HAL_STACK_SIZE_MINIMUM,
69 "Stack size too small"); 115 "Stack size too small");
70 #endif 116 #endif
117
118 #ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
119 {
120 cyg_uint32 sig = (cyg_uint32)this;
121 cyg_uint32 *base = (cyg_uint32 *)s_base;
122 cyg_uint32 *top = (cyg_uint32 *)(s_base + s_size -
123 CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);
124
125 unsigned int i;
126
127 CYG_ASSERT( 0 == (3 & (cyg_uint32)base), "stack base alignment" );
128 CYG_ASSERT( 0 == (3 & (cyg_uint32)top), "stack top alignment" );
129
130 for ( i = 0;
131 i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
132 i++ ) {
133 base[i] = (sig ^ (i * 0x01010101));
134 top[i] = (sig ^ (i * 0x10101010));
135 }
136 // This check for overlap of the two signature areas also detects
137 // wrap round zero of the size in the unsigned subtraction below.
138 CYG_ASSERT( &base[i] < &top[0], "Stack is so small size wrapped" );
139 // Use this 'i' expression to round correctly to whole words.
140 s_base += i * sizeof(cyg_uint32);
141 s_size -= i * sizeof(cyg_uint32) * 2;
142 // This is a complete guess, the 256; the point is to assert early that
143 // this might go badly wrong. It would not detect wrap of unsigned size.
144 CYG_ASSERT( s_size >= 256,
145 "Stack size too small after allocating checking buffer");
146 }
147 #endif
148
71 stack_base = s_base; 149 stack_base = s_base;
72 stack_size = s_size; 150 stack_size = s_size;
73 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT 151 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
74 stack_limit = s_base; 152 stack_limit = s_base;
75 #endif 153 #endif
80 158
81 #else 159 #else
82 160
83 stack_ptr = stack_base + stack_size; 161 stack_ptr = stack_base + stack_size;
84 162
163 #endif
164
165 #ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
166 check_stack();
85 #endif 167 #endif
86 } 168 }
87 169
88 // ------------------------------------------------------------------------- 170 // -------------------------------------------------------------------------
89 171
100 saved_context = 0; 182 saved_context = 0;
101 #endif 183 #endif
102 184
103 attach_stack( s_base, s_size ); 185 attach_stack( s_base, s_size );
104 }; 186 };
105
106 // -------------------------------------------------------------------------
107 // get the size/base of this thread's stack
108
109 inline CYG_ADDRESS
110 Cyg_HardwareThread::get_stack_base()
111 {
112 return stack_base;
113 }
114
115 inline cyg_uint32
116 Cyg_HardwareThread::get_stack_size()
117 {
118 return stack_size;
119 }
120 187
121 // ------------------------------------------------------------------------- 188 // -------------------------------------------------------------------------
122 189
123 #ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT 190 #ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
124 191