summaryrefslogtreecommitdiff
path: root/uisimulator/sdl
diff options
context:
space:
mode:
Diffstat (limited to 'uisimulator/sdl')
-rw-r--r--uisimulator/sdl/button.c4
-rw-r--r--uisimulator/sdl/kernel.c225
-rw-r--r--uisimulator/sdl/thread-sdl.c160
3 files changed, 311 insertions, 78 deletions
diff --git a/uisimulator/sdl/button.c b/uisimulator/sdl/button.c
index a15faf72c0..e50bfea087 100644
--- a/uisimulator/sdl/button.c
+++ b/uisimulator/sdl/button.c
@@ -743,7 +743,7 @@ int button_queue_count( void )
743 743
744long button_get(bool block) 744long button_get(bool block)
745{ 745{
746 struct event ev; 746 struct queue_event ev;
747 747
748 if ( block || !queue_empty(&button_queue) ) { 748 if ( block || !queue_empty(&button_queue) ) {
749 queue_wait(&button_queue, &ev); 749 queue_wait(&button_queue, &ev);
@@ -755,7 +755,7 @@ long button_get(bool block)
755 755
756long button_get_w_tmo(int ticks) 756long button_get_w_tmo(int ticks)
757{ 757{
758 struct event ev; 758 struct queue_event ev;
759 queue_wait_w_tmo(&button_queue, &ev, ticks); 759 queue_wait_w_tmo(&button_queue, &ev, ticks);
760 if (ev.id == SYS_TIMEOUT) 760 if (ev.id == SYS_TIMEOUT)
761 ev.id = BUTTON_NONE; 761 ev.id = BUTTON_NONE;
diff --git a/uisimulator/sdl/kernel.c b/uisimulator/sdl/kernel.c
index e2aa0d31c4..8a54cd91fc 100644
--- a/uisimulator/sdl/kernel.c
+++ b/uisimulator/sdl/kernel.c
@@ -29,7 +29,7 @@ volatile long current_tick = 0;
29static void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 29static void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
30 30
31/* This array holds all queues that are initiated. It is used for broadcast. */ 31/* This array holds all queues that are initiated. It is used for broadcast. */
32static struct event_queue *all_queues[32]; 32static struct event_queue *all_queues[MAX_NUM_QUEUES];
33static int num_queues = 0; 33static int num_queues = 0;
34 34
35#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME 35#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
@@ -53,7 +53,7 @@ static void queue_release_sender(struct thread_entry **sender,
53 intptr_t retval) 53 intptr_t retval)
54{ 54{
55 (*sender)->retval = retval; 55 (*sender)->retval = retval;
56 wakeup_thread(sender); 56 wakeup_thread_no_listlock(sender);
57 if(*sender != NULL) 57 if(*sender != NULL)
58 { 58 {
59 fprintf(stderr, "queue->send slot ovf: %p\n", *sender); 59 fprintf(stderr, "queue->send slot ovf: %p\n", *sender);
@@ -98,14 +98,14 @@ void queue_init(struct event_queue *q, bool register_queue)
98{ 98{
99 q->read = 0; 99 q->read = 0;
100 q->write = 0; 100 q->write = 0;
101 q->thread = NULL; 101 thread_queue_init(&q->queue);
102#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME 102#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
103 q->send = NULL; /* No message sending by default */ 103 q->send = NULL; /* No message sending by default */
104#endif 104#endif
105 105
106 if(register_queue) 106 if(register_queue)
107 { 107 {
108 if(num_queues >= 32) 108 if(num_queues >= MAX_NUM_QUEUES)
109 { 109 {
110 fprintf(stderr, "queue_init->out of queues"); 110 fprintf(stderr, "queue_init->out of queues");
111 exit(-1); 111 exit(-1);
@@ -142,7 +142,7 @@ void queue_delete(struct event_queue *q)
142 } 142 }
143 143
144 /* Release threads waiting on queue head */ 144 /* Release threads waiting on queue head */
145 wakeup_thread(&q->thread); 145 thread_queue_wake(&q->queue);
146 146
147#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME 147#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
148 /* Release waiting threads and reply to any dequeued message 148 /* Release waiting threads and reply to any dequeued message
@@ -155,7 +155,7 @@ void queue_delete(struct event_queue *q)
155 q->write = 0; 155 q->write = 0;
156} 156}
157 157
158void queue_wait(struct event_queue *q, struct event *ev) 158void queue_wait(struct event_queue *q, struct queue_event *ev)
159{ 159{
160 unsigned int rd; 160 unsigned int rd;
161 161
@@ -169,7 +169,11 @@ void queue_wait(struct event_queue *q, struct event *ev)
169 169
170 if (q->read == q->write) 170 if (q->read == q->write)
171 { 171 {
172 block_thread(&q->thread); 172 do
173 {
174 block_thread(&q->queue);
175 }
176 while (q->read == q->write);
173 } 177 }
174 178
175 rd = q->read++ & QUEUE_LENGTH_MASK; 179 rd = q->read++ & QUEUE_LENGTH_MASK;
@@ -184,7 +188,7 @@ void queue_wait(struct event_queue *q, struct event *ev)
184#endif 188#endif
185} 189}
186 190
187void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks) 191void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, int ticks)
188{ 192{
189#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME 193#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
190 if (q->send && q->send->curr_sender) 194 if (q->send && q->send->curr_sender)
@@ -196,7 +200,7 @@ void queue_wait_w_tmo(struct event_queue *q, struct event *ev, int ticks)
196 200
197 if (q->read == q->write && ticks > 0) 201 if (q->read == q->write && ticks > 0)
198 { 202 {
199 block_thread_w_tmo(&q->thread, ticks); 203 block_thread_w_tmo(&q->queue, ticks);
200 } 204 }
201 205
202 if(q->read != q->write) 206 if(q->read != q->write)
@@ -238,7 +242,7 @@ void queue_post(struct event_queue *q, long id, intptr_t data)
238 } 242 }
239#endif 243#endif
240 244
241 wakeup_thread(&q->thread); 245 wakeup_thread(&q->queue);
242} 246}
243 247
244/* Special thread-synced queue_post for button driver or any other preemptive sim thread */ 248/* Special thread-synced queue_post for button driver or any other preemptive sim thread */
@@ -268,9 +272,9 @@ intptr_t queue_send(struct event_queue *q, long id, intptr_t data)
268 queue_release_sender(spp, 0); 272 queue_release_sender(spp, 0);
269 } 273 }
270 274
271 wakeup_thread(&q->thread); 275 wakeup_thread(&q->queue);
272 276
273 block_thread(spp); 277 block_thread_no_listlock(spp);
274 return thread_get_current()->retval; 278 return thread_get_current()->retval;
275 } 279 }
276 280
@@ -370,7 +374,7 @@ int queue_syncbroadcast(long id, intptr_t data)
370 374
371void yield(void) 375void yield(void)
372{ 376{
373 switch_thread(true, NULL); 377 switch_thread(NULL);
374} 378}
375 379
376void sleep(int ticks) 380void sleep(int ticks)
@@ -431,39 +435,218 @@ int tick_remove_task(void (*f)(void))
431 multitasking, but is better than nothing at all */ 435 multitasking, but is better than nothing at all */
432void mutex_init(struct mutex *m) 436void mutex_init(struct mutex *m)
433{ 437{
438 m->queue = NULL;
434 m->thread = NULL; 439 m->thread = NULL;
440 m->count = 0;
435 m->locked = 0; 441 m->locked = 0;
436} 442}
437 443
438void mutex_lock(struct mutex *m) 444void mutex_lock(struct mutex *m)
439{ 445{
440 if (test_and_set(&m->locked, 1)) 446 struct thread_entry *const thread = thread_get_current();
447
448 if(thread == m->thread)
449 {
450 m->count++;
451 return;
452 }
453
454 if (!test_and_set(&m->locked, 1))
441 { 455 {
442 block_thread(&m->thread); 456 m->thread = thread;
457 return;
443 } 458 }
459
460 block_thread_no_listlock(&m->queue);
444} 461}
445 462
446void mutex_unlock(struct mutex *m) 463void mutex_unlock(struct mutex *m)
447{ 464{
448 if (m->thread != NULL) 465 /* unlocker not being the owner is an unlocking violation */
466 if(m->thread != thread_get_current())
449 { 467 {
450 wakeup_thread(&m->thread); 468 fprintf(stderr, "spinlock_unlock->wrong thread");
469 exit(-1);
470 }
471
472 if (m->count > 0)
473 {
474 /* this thread still owns lock */
475 m->count--;
476 return;
451 } 477 }
452 else 478
479 m->thread = wakeup_thread_no_listlock(&m->queue);
480
481 if (m->thread == NULL)
453 { 482 {
483 /* release lock */
454 m->locked = 0; 484 m->locked = 0;
455 } 485 }
456} 486}
457 487
458void spinlock_lock(struct mutex *l) 488void spinlock_init(struct spinlock *l)
489{
490 l->locked = 0;
491 l->thread = NULL;
492 l->count = 0;
493}
494
495void spinlock_lock(struct spinlock *l)
459{ 496{
497 struct thread_entry *const thread = thread_get_current();
498
499 if (l->thread == thread)
500 {
501 l->count++;
502 return;
503 }
504
460 while(test_and_set(&l->locked, 1)) 505 while(test_and_set(&l->locked, 1))
461 { 506 {
462 switch_thread(true, NULL); 507 switch_thread(NULL);
463 } 508 }
509
510 l->thread = thread;
464} 511}
465 512
466void spinlock_unlock(struct mutex *l) 513void spinlock_unlock(struct spinlock *l)
467{ 514{
515 /* unlocker not being the owner is an unlocking violation */
516 if(l->thread != thread_get_current())
517 {
518 fprintf(stderr, "spinlock_unlock->wrong thread");
519 exit(-1);
520 }
521
522 if (l->count > 0)
523 {
524 /* this thread still owns lock */
525 l->count--;
526 return;
527 }
528
529 /* clear owner */
530 l->thread = NULL;
468 l->locked = 0; 531 l->locked = 0;
469} 532}
533
534void semaphore_init(struct semaphore *s, int max, int start)
535{
536 if(max <= 0 || start < 0 || start > max)
537 {
538 fprintf(stderr, "semaphore_init->inv arg");
539 exit(-1);
540 }
541 s->queue = NULL;
542 s->max = max;
543 s->count = start;
544}
545
546void semaphore_wait(struct semaphore *s)
547{
548 if(--s->count >= 0)
549 return;
550 block_thread_no_listlock(&s->queue);
551}
552
553void semaphore_release(struct semaphore *s)
554{
555 if(s->count < s->max)
556 {
557 if(++s->count <= 0)
558 {
559 if(s->queue == NULL)
560 {
561 /* there should be threads in this queue */
562 fprintf(stderr, "semaphore->wakeup");
563 exit(-1);
564 }
565 /* a thread was queued - wake it up */
566 wakeup_thread_no_listlock(&s->queue);
567 }
568 }
569}
570
571void event_init(struct event *e, unsigned int flags)
572{
573 e->queues[STATE_NONSIGNALED] = NULL;
574 e->queues[STATE_SIGNALED] = NULL;
575 e->state = flags & STATE_SIGNALED;
576 e->automatic = (flags & EVENT_AUTOMATIC) ? 1 : 0;
577}
578
579void event_wait(struct event *e, unsigned int for_state)
580{
581 unsigned int last_state = e->state;
582
583 if(e->automatic != 0)
584 {
585 /* wait for false always satisfied by definition
586 or if it just changed to false */
587 if(last_state == STATE_SIGNALED || for_state == STATE_NONSIGNALED)
588 {
589 /* automatic - unsignal */
590 e->state = STATE_NONSIGNALED;
591 return;
592 }
593 /* block until state matches */
594 }
595 else if(for_state == last_state)
596 {
597 /* the state being waited for is the current state */
598 return;
599 }
600
601 /* current state does not match wait-for state */
602 block_thread_no_listlock(&e->queues[for_state]);
603}
604
605void event_set_state(struct event *e, unsigned int state)
606{
607 unsigned int last_state = e->state;
608
609 if(last_state == state)
610 {
611 /* no change */
612 return;
613 }
614
615 if(state == STATE_SIGNALED)
616 {
617 if(e->automatic != 0)
618 {
619 struct thread_entry *thread;
620
621 if(e->queues[STATE_NONSIGNALED] != NULL)
622 {
623 /* no thread should have ever blocked for nonsignaled */
624 fprintf(stderr, "set_event_state->queue[NS]:S");
625 exit(-1);
626 }
627
628 /* pass to next thread and keep unsignaled - "pulse" */
629 thread = wakeup_thread_no_listlock(&e->queues[STATE_SIGNALED]);
630 e->state = thread != NULL ? STATE_NONSIGNALED : STATE_SIGNALED;
631 }
632 else
633 {
634 /* release all threads waiting for signaled */
635 thread_queue_wake_no_listlock(&e->queues[STATE_SIGNALED]);
636 e->state = STATE_SIGNALED;
637 }
638 }
639 else
640 {
641 /* release all threads waiting for unsignaled */
642 if(e->queues[STATE_NONSIGNALED] != NULL && e->automatic != 0)
643 {
644 /* no thread should have ever blocked */
645 fprintf(stderr, "set_event_state->queue[NS]:NS");
646 exit(-1);
647 }
648
649 thread_queue_wake_no_listlock(&e->queues[STATE_NONSIGNALED]);
650 e->state = STATE_NONSIGNALED;
651 }
652}
diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c
index 0bd7d2534e..6a3c4af9eb 100644
--- a/uisimulator/sdl/thread-sdl.c
+++ b/uisimulator/sdl/thread-sdl.c
@@ -131,7 +131,7 @@ bool thread_sdl_init(void *param)
131 running->stack = " "; 131 running->stack = " ";
132 running->stack_size = 8; 132 running->stack_size = 8;
133 running->name = "main"; 133 running->name = "main";
134 running->statearg = STATE_RUNNING; 134 running->state = STATE_RUNNING;
135 running->context.c = SDL_CreateCond(); 135 running->context.c = SDL_CreateCond();
136 136
137 if (running->context.c == NULL) 137 if (running->context.c == NULL)
@@ -154,43 +154,55 @@ bool thread_sdl_init(void *param)
154 return true; 154 return true;
155} 155}
156 156
157void thread_sdl_lock(void)
158{
159 SDL_LockMutex(m);
160}
161
162void thread_sdl_unlock(void)
163{
164 SDL_UnlockMutex(m);
165}
166
157static int find_empty_thread_slot(void) 167static int find_empty_thread_slot(void)
158{ 168{
159 int n; 169 int n;
160 170
161 for (n = 0; n < MAXTHREADS; n++) 171 for (n = 0; n < MAXTHREADS; n++)
162 { 172 {
163 if (threads[n].name == NULL) 173 int state = threads[n].state;
174
175 if (state == STATE_KILLED)
164 break; 176 break;
165 } 177 }
166 178
167 return n; 179 return n;
168} 180}
169 181
170static void add_to_list(struct thread_entry **list, 182static void add_to_list_l(struct thread_entry **list,
171 struct thread_entry *thread) 183 struct thread_entry *thread)
172{ 184{
173 if (*list == NULL) 185 if (*list == NULL)
174 { 186 {
175 /* Insert into unoccupied list */ 187 /* Insert into unoccupied list */
176 thread->next = thread; 188 thread->l.next = thread;
177 thread->prev = thread; 189 thread->l.prev = thread;
178 *list = thread; 190 *list = thread;
179 } 191 }
180 else 192 else
181 { 193 {
182 /* Insert last */ 194 /* Insert last */
183 thread->next = *list; 195 thread->l.next = *list;
184 thread->prev = (*list)->prev; 196 thread->l.prev = (*list)->l.prev;
185 thread->prev->next = thread; 197 thread->l.prev->l.next = thread;
186 (*list)->prev = thread; 198 (*list)->l.prev = thread;
187 } 199 }
188} 200}
189 201
190static void remove_from_list(struct thread_entry **list, 202static void remove_from_list_l(struct thread_entry **list,
191 struct thread_entry *thread) 203 struct thread_entry *thread)
192{ 204{
193 if (thread == thread->next) 205 if (thread == thread->l.next)
194 { 206 {
195 /* The only item */ 207 /* The only item */
196 *list = NULL; 208 *list = NULL;
@@ -200,12 +212,12 @@ static void remove_from_list(struct thread_entry **list,
200 if (thread == *list) 212 if (thread == *list)
201 { 213 {
202 /* List becomes next item */ 214 /* List becomes next item */
203 *list = thread->next; 215 *list = thread->l.next;
204 } 216 }
205 217
206 /* Fix links to jump over the removed entry. */ 218 /* Fix links to jump over the removed entry. */
207 thread->prev->next = thread->next; 219 thread->l.prev->l.next = thread->l.next;
208 thread->next->prev = thread->prev; 220 thread->l.next->l.prev = thread->l.prev;
209} 221}
210 222
211struct thread_entry *thread_get_current(void) 223struct thread_entry *thread_get_current(void)
@@ -213,17 +225,7 @@ struct thread_entry *thread_get_current(void)
213 return running; 225 return running;
214} 226}
215 227
216void thread_sdl_lock(void) 228void switch_thread(struct thread_entry *old)
217{
218 SDL_LockMutex(m);
219}
220
221void thread_sdl_unlock(void)
222{
223 SDL_UnlockMutex(m);
224}
225
226void switch_thread(bool save_context, struct thread_entry **blocked_list)
227{ 229{
228 struct thread_entry *current = running; 230 struct thread_entry *current = running;
229 231
@@ -235,7 +237,7 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list)
235 if (threads_exit) 237 if (threads_exit)
236 remove_thread(NULL); 238 remove_thread(NULL);
237 239
238 (void)save_context; (void)blocked_list; 240 (void)old;
239} 241}
240 242
241void sleep_thread(int ticks) 243void sleep_thread(int ticks)
@@ -244,7 +246,7 @@ void sleep_thread(int ticks)
244 int rem; 246 int rem;
245 247
246 current = running; 248 current = running;
247 current->statearg = STATE_SLEEPING; 249 current->state = STATE_SLEEPING;
248 250
249 rem = (SDL_GetTicks() - start_tick) % (1000/HZ); 251 rem = (SDL_GetTicks() - start_tick) % (1000/HZ);
250 if (rem < 0) 252 if (rem < 0)
@@ -267,7 +269,7 @@ void sleep_thread(int ticks)
267 269
268 running = current; 270 running = current;
269 271
270 current->statearg = STATE_RUNNING; 272 current->state = STATE_RUNNING;
271 273
272 if (threads_exit) 274 if (threads_exit)
273 remove_thread(NULL); 275 remove_thread(NULL);
@@ -289,10 +291,21 @@ int runthread(void *data)
289 if (setjmp(*current_jmpbuf) == 0) 291 if (setjmp(*current_jmpbuf) == 0)
290 { 292 {
291 /* Run the thread routine */ 293 /* Run the thread routine */
292 current->context.start(); 294 if (current->state == STATE_FROZEN)
293 THREAD_SDL_DEBUGF("Thread Done: %d (%s)\n", 295 {
294 current - threads, THREAD_SDL_GET_NAME(current)); 296 SDL_CondWait(current->context.c, m);
295 /* Thread routine returned - suicide */ 297 running = current;
298
299 }
300
301 if (!threads_exit)
302 {
303 current->context.start();
304 THREAD_SDL_DEBUGF("Thread Done: %d (%s)\n",
305 current - threads, THREAD_SDL_GET_NAME(current));
306 /* Thread routine returned - suicide */
307 }
308
296 remove_thread(NULL); 309 remove_thread(NULL);
297 } 310 }
298 else 311 else
@@ -306,7 +319,7 @@ int runthread(void *data)
306 319
307struct thread_entry* 320struct thread_entry*
308 create_thread(void (*function)(void), void* stack, int stack_size, 321 create_thread(void (*function)(void), void* stack, int stack_size,
309 const char *name) 322 unsigned flags, const char *name)
310{ 323{
311 /** Avoid compiler warnings */ 324 /** Avoid compiler warnings */
312 SDL_Thread* t; 325 SDL_Thread* t;
@@ -340,7 +353,8 @@ struct thread_entry*
340 threads[slot].stack = stack; 353 threads[slot].stack = stack;
341 threads[slot].stack_size = stack_size; 354 threads[slot].stack_size = stack_size;
342 threads[slot].name = name; 355 threads[slot].name = name;
343 threads[slot].statearg = STATE_RUNNING; 356 threads[slot].state = (flags & CREATE_THREAD_FROZEN) ?
357 STATE_FROZEN : STATE_RUNNING;
344 threads[slot].context.start = function; 358 threads[slot].context.start = function;
345 threads[slot].context.t = t; 359 threads[slot].context.t = t;
346 threads[slot].context.c = cond; 360 threads[slot].context.c = cond;
@@ -351,12 +365,13 @@ struct thread_entry*
351 return &threads[slot]; 365 return &threads[slot];
352} 366}
353 367
354void block_thread(struct thread_entry **list) 368void _block_thread(struct thread_queue *tq)
355{ 369{
356 struct thread_entry *thread = running; 370 struct thread_entry *thread = running;
357 371
358 thread->statearg = STATE_BLOCKED; 372 thread->state = STATE_BLOCKED;
359 add_to_list(list, thread); 373 thread->bqp = tq;
374 add_to_list_l(&tq->queue, thread);
360 375
361 SDL_CondWait(thread->context.c, m); 376 SDL_CondWait(thread->context.c, m);
362 running = thread; 377 running = thread;
@@ -365,44 +380,56 @@ void block_thread(struct thread_entry **list)
365 remove_thread(NULL); 380 remove_thread(NULL);
366} 381}
367 382
368void block_thread_w_tmo(struct thread_entry **list, int ticks) 383void block_thread_w_tmo(struct thread_queue *tq, int ticks)
369{ 384{
370 struct thread_entry *thread = running; 385 struct thread_entry *thread = running;
371 386
372 thread->statearg = STATE_BLOCKED_W_TMO; 387 thread->state = STATE_BLOCKED_W_TMO;
373 add_to_list(list, thread); 388 thread->bqp = tq;
389 add_to_list_l(&tq->queue, thread);
374 390
375 SDL_CondWaitTimeout(thread->context.c, m, (1000/HZ) * ticks); 391 SDL_CondWaitTimeout(thread->context.c, m, (1000/HZ) * ticks);
376 running = thread; 392 running = thread;
377 393
378 if (thread->statearg == STATE_BLOCKED_W_TMO) 394 if (thread->state == STATE_BLOCKED_W_TMO)
379 { 395 {
380 /* Timed out */ 396 /* Timed out */
381 remove_from_list(list, thread); 397 remove_from_list_l(&tq->queue, thread);
382 thread->statearg = STATE_RUNNING; 398 thread->state = STATE_RUNNING;
383 } 399 }
384 400
385 if (threads_exit) 401 if (threads_exit)
386 remove_thread(NULL); 402 remove_thread(NULL);
387} 403}
388 404
389void wakeup_thread(struct thread_entry **list) 405struct thread_entry * _wakeup_thread(struct thread_queue *tq)
390{ 406{
391 struct thread_entry *thread = *list; 407 struct thread_entry *thread = tq->queue;
392 408
393 if (thread == NULL) 409 if (thread == NULL)
394 { 410 {
395 return; 411 return NULL;
396 } 412 }
397 413
398 switch (thread->statearg) 414 switch (thread->state)
399 { 415 {
400 case STATE_BLOCKED: 416 case STATE_BLOCKED:
401 case STATE_BLOCKED_W_TMO: 417 case STATE_BLOCKED_W_TMO:
402 remove_from_list(list, thread); 418 remove_from_list_l(&tq->queue, thread);
403 thread->statearg = STATE_RUNNING; 419 thread->state = STATE_RUNNING;
420 SDL_CondSignal(thread->context.c);
421 return thread;
422 default:
423 return NULL;
424 }
425}
426
427void thread_thaw(struct thread_entry *thread)
428{
429 if (thread->state == STATE_FROZEN)
430 {
431 thread->state = STATE_RUNNING;
404 SDL_CondSignal(thread->context.c); 432 SDL_CondSignal(thread->context.c);
405 break;
406 } 433 }
407} 434}
408 435
@@ -434,12 +461,24 @@ void remove_thread(struct thread_entry *thread)
434 thread->context.t = NULL; 461 thread->context.t = NULL;
435 462
436 if (thread != current) 463 if (thread != current)
464 {
465 switch (thread->state)
466 {
467 case STATE_BLOCKED:
468 case STATE_BLOCKED_W_TMO:
469 /* Remove thread from object it's waiting on */
470 remove_from_list_l(&thread->bqp->queue, thread);
471 break;
472 }
473
437 SDL_CondSignal(c); 474 SDL_CondSignal(c);
475 }
438 476
439 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n", 477 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
440 thread - threads, THREAD_SDL_GET_NAME(thread)); 478 thread - threads, THREAD_SDL_GET_NAME(thread));
441 479
442 thread->name = NULL; 480 thread_queue_wake_no_listlock(&thread->queue);
481 thread->state = STATE_KILLED;
443 482
444 SDL_DestroyCond(c); 483 SDL_DestroyCond(c);
445 484
@@ -453,15 +492,26 @@ void remove_thread(struct thread_entry *thread)
453 SDL_KillThread(t); 492 SDL_KillThread(t);
454} 493}
455 494
495void thread_wait(struct thread_entry *thread)
496{
497 if (thread == NULL)
498 thread = running;
499
500 if (thread->state != STATE_KILLED)
501 {
502 block_thread_no_listlock(&thread->queue);
503 }
504}
505
456int thread_stack_usage(const struct thread_entry *thread) 506int thread_stack_usage(const struct thread_entry *thread)
457{ 507{
458 return 50; 508 return 50;
459 (void)thread; 509 (void)thread;
460} 510}
461 511
462int thread_get_status(const struct thread_entry *thread) 512unsigned thread_get_status(const struct thread_entry *thread)
463{ 513{
464 return thread->statearg; 514 return thread->state;
465} 515}
466 516
467/* Return name if one or ID if none */ 517/* Return name if one or ID if none */