| Index: embios/trunk/thread.c |
| — | — | @@ -31,6 +31,7 @@ |
| 32 | 32 | struct scheduler_thread scheduler_threads[MAX_THREADS] IBSS_ATTR;
|
| 33 | 33 | struct scheduler_thread* current_thread IBSS_ATTR;
|
| 34 | 34 | uint32_t last_tick IBSS_ATTR;
|
| | 35 | +bool scheduler_frozen IBSS_ATTR;
|
| 35 | 36 | extern struct wakeup dbgwakeup;
|
| 36 | 37 |
|
| 37 | 38 |
|
| — | — | @@ -217,6 +218,7 @@ |
| 218 | 219 | void scheduler_init(void)
|
| 219 | 220 | {
|
| 220 | 221 | memset(scheduler_threads, 0, sizeof(scheduler_threads));
|
| | 222 | + scheduler_frozen = false;
|
| 221 | 223 | last_tick = USEC_TIMER;
|
| 222 | 224 | current_thread = scheduler_threads;
|
| 223 | 225 | current_thread->state = THREAD_RUNNING;
|
| — | — | @@ -226,6 +228,11 @@ |
| 227 | 229 | setup_tick();
|
| 228 | 230 | }
|
| 229 | 231 |
|
| | 232 | +void scheduler_freeze(bool value)
|
| | 233 | +{
|
| | 234 | + scheduler_frozen = value;
|
| | 235 | +}
|
| | 236 | +
|
| 230 | 237 | void scheduler_switch(int thread)
|
| 231 | 238 | {
|
| 232 | 239 | int i;
|
| — | — | @@ -254,37 +261,41 @@ |
| 255 | 262 | }
|
| 256 | 263 | }
|
| 257 | 264 |
|
| 258 | | - for (i = 0; i < MAX_THREADS; i++)
|
| 259 | | - if (scheduler_threads[i].state == THREAD_BLOCKED
|
| 260 | | - && scheduler_threads[i].timeout != -1
|
| 261 | | - && TIME_AFTER(usec, scheduler_threads[i].blocked_since
|
| 262 | | - + scheduler_threads[i].timeout))
|
| 263 | | - {
|
| 264 | | - if (scheduler_threads[i].block_type == THREAD_BLOCK_MUTEX)
|
| 265 | | - mutex_remove_from_queue((struct mutex*)scheduler_threads[i].blocked_by,
|
| 266 | | - &scheduler_threads[i]);
|
| 267 | | - scheduler_threads[i].state = THREAD_READY;
|
| 268 | | - scheduler_threads[i].block_type = THREAD_NOT_BLOCKED;
|
| 269 | | - scheduler_threads[i].blocked_by = NULL;
|
| 270 | | - scheduler_threads[i].timeout = 0;
|
| 271 | | - }
|
| 272 | | -
|
| 273 | | - if (thread >= 0 && thread < MAX_THREADS && scheduler_threads[thread].state == THREAD_READY)
|
| 274 | | - current_thread = &scheduler_threads[thread];
|
| | 265 | + if (scheduler_frozen) thread = 0;
|
| 275 | 266 | else
|
| 276 | 267 | {
|
| 277 | | - thread = 0;
|
| 278 | | - best = 0xffffffff;
|
| 279 | 268 | for (i = 0; i < MAX_THREADS; i++)
|
| 280 | | - if (scheduler_threads[i].state == THREAD_READY && scheduler_threads[i].priority)
|
| | 269 | + if (scheduler_threads[i].state == THREAD_BLOCKED
|
| | 270 | + && scheduler_threads[i].timeout != -1
|
| | 271 | + && TIME_AFTER(usec, scheduler_threads[i].blocked_since
|
| | 272 | + + scheduler_threads[i].timeout))
|
| 281 | 273 | {
|
| 282 | | - score = scheduler_threads[i].cputime_current / scheduler_threads[i].priority;
|
| 283 | | - if (score < best)
|
| | 274 | + if (scheduler_threads[i].block_type == THREAD_BLOCK_MUTEX)
|
| | 275 | + mutex_remove_from_queue((struct mutex*)scheduler_threads[i].blocked_by,
|
| | 276 | + &scheduler_threads[i]);
|
| | 277 | + scheduler_threads[i].state = THREAD_READY;
|
| | 278 | + scheduler_threads[i].block_type = THREAD_NOT_BLOCKED;
|
| | 279 | + scheduler_threads[i].blocked_by = NULL;
|
| | 280 | + scheduler_threads[i].timeout = 0;
|
| | 281 | + }
|
| | 282 | +
|
| | 283 | + if (thread >= 0 && thread < MAX_THREADS && scheduler_threads[thread].state == THREAD_READY)
|
| | 284 | + current_thread = &scheduler_threads[thread];
|
| | 285 | + else
|
| | 286 | + {
|
| | 287 | + thread = 0;
|
| | 288 | + best = 0xffffffff;
|
| | 289 | + for (i = 0; i < MAX_THREADS; i++)
|
| | 290 | + if (scheduler_threads[i].state == THREAD_READY && scheduler_threads[i].priority)
|
| 284 | 291 | {
|
| 285 | | - best = score;
|
| 286 | | - thread = i;
|
| | 292 | + score = scheduler_threads[i].cputime_current / scheduler_threads[i].priority;
|
| | 293 | + if (score < best)
|
| | 294 | + {
|
| | 295 | + best = score;
|
| | 296 | + thread = i;
|
| | 297 | + }
|
| 287 | 298 | }
|
| 288 | | - }
|
| | 299 | + }
|
| 289 | 300 | }
|
| 290 | 301 |
|
| 291 | 302 | current_thread = &scheduler_threads[thread];
|
| Index: embios/trunk/usb/usb.c |
| — | — | @@ -458,6 +458,11 @@ |
| 459 | 459 | memcpy(&dbgsendbuf[4], scheduler_threads, dbgrecvbuf[1]);
|
| 460 | 460 | size = dbgrecvbuf[1] + 16;
|
| 461 | 461 | break;
|
| | 462 | + case 16: // FREEZE SCHEDULER
|
| | 463 | + scheduler_freeze(dbgrecvbuf[1]);
|
| | 464 | + dbgsendbuf[0] = 1;
|
| | 465 | + size = 16;
|
| | 466 | + break;
|
| 462 | 467 | default:
|
| 463 | 468 | dbgsendbuf[0] = 2;
|
| 464 | 469 | size = 16;
|
| Index: embios/trunk/thread.h |
| — | — | @@ -106,6 +106,7 @@ |
| 107 | 107 |
|
| 108 | 108 | void scheduler_init() INITCODE_ATTR;
|
| 109 | 109 | void scheduler_switch(int thread) ICODE_ATTR;
|
| | 110 | +void scheduler_freeze(bool value);
|
| 110 | 111 | int thread_create(const char* name, const void* code, void* stack,
|
| 111 | 112 | int stacksize, enum thread_type type, int priority, bool run);
|
| 112 | 113 | int thread_suspend(int thread);
|