summaryrefslogtreecommitdiff
path: root/firmware/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/thread.c')
-rw-r--r--firmware/thread.c70
1 files changed, 36 insertions, 34 deletions
diff --git a/firmware/thread.c b/firmware/thread.c
index e7c4606bcc..294359b762 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -112,16 +112,18 @@ void switch_thread(void)
112 112
113#endif 113#endif
114 next = current = current_thread; 114 next = current = current_thread;
115
115 if (++next >= num_threads) 116 if (++next >= num_threads)
116 next = 0; 117 next = 0;
117 current_thread = next; 118 current_thread = next;
118 store_context(&thread_contexts[current]); 119 store_context(&thread_contexts[current]);
119 load_context(&thread_contexts[next]);
120
121 stackptr = thread_stack[next];
122 120
121 /* Check if the current thread stack is overflown */
122 stackptr = thread_stack[current];
123 if(stackptr[0] != 0xdeadbeef) 123 if(stackptr[0] != 0xdeadbeef)
124 panicf("Stkov %s", thread_name[next]); 124 panicf("Stkov %s", thread_name[current]);
125
126 load_context(&thread_contexts[next]);
125} 127}
126 128
127void sleep_thread(void) 129void sleep_thread(void)
@@ -142,36 +144,36 @@ void wake_up_thread(void)
142 */ 144 */
143int create_thread(void* function, void* stack, int stack_size, char *name) 145int create_thread(void* function, void* stack, int stack_size, char *name)
144{ 146{
145 unsigned int i; 147 unsigned int i;
146 unsigned int stacklen; 148 unsigned int stacklen;
147 unsigned int *stackptr; 149 unsigned int *stackptr;
148 struct regs *regs; 150 struct regs *regs;
149 151
150 if (num_threads >= MAXTHREADS) 152 if (num_threads >= MAXTHREADS)
151 return -1; 153 return -1;
152 154
153 /* Munge the stack to make it easy to spot stack overflows */ 155 /* Munge the stack to make it easy to spot stack overflows */
154 stacklen = stack_size / 4; 156 stacklen = stack_size / 4;
155 stackptr = stack; 157 stackptr = stack;
156 for(i = 0;i < stacklen;i++) 158 for(i = 0;i < stacklen;i++)
157 { 159 {
158 stackptr[i] = 0xdeadbeef; 160 stackptr[i] = 0xdeadbeef;
159 } 161 }
160 162
161 /* Store interesting information */ 163 /* Store interesting information */
162 thread_name[num_threads] = name; 164 thread_name[num_threads] = name;
163 thread_stack[num_threads] = stack; 165 thread_stack[num_threads] = stack;
164 thread_stack_size[num_threads] = stack_size; 166 thread_stack_size[num_threads] = stack_size;
165 regs = &thread_contexts[num_threads]; 167 regs = &thread_contexts[num_threads];
166 store_context(regs); 168 store_context(regs);
167 /* Subtract 4 to leave room for the PR push in load_context() 169 /* Subtract 4 to leave room for the PR push in load_context()
168 Align it on an even 32 bit boundary */ 170 Align it on an even 32 bit boundary */
169 regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3); 171 regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3);
170 regs->sr = 0; 172 regs->sr = 0;
171 regs->pr = function; 173 regs->pr = function;
172 174
173 wake_up_thread(); 175 wake_up_thread();
174 return num_threads++; /* return the current ID, e.g for remove_thread() */ 176 return num_threads++; /* return the current ID, e.g for remove_thread() */
175} 177}
176 178
177/*--------------------------------------------------------------------------- 179/*---------------------------------------------------------------------------
@@ -222,7 +224,7 @@ int thread_stack_usage(int threadnum)
222 for(i = 0;i < thread_stack_size[threadnum]/sizeof(int);i++) 224 for(i = 0;i < thread_stack_size[threadnum]/sizeof(int);i++)
223 { 225 {
224 if(stackptr[i] != 0xdeadbeef) 226 if(stackptr[i] != 0xdeadbeef)
225 break; 227 break;
226 } 228 }
227 229
228 return ((thread_stack_size[threadnum] - i * 4) * 100) / 230 return ((thread_stack_size[threadnum] - i * 4) * 100) /