summaryrefslogtreecommitdiff
path: root/firmware/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/thread.c')
-rw-r--r--firmware/thread.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/firmware/thread.c b/firmware/thread.c
index 614286c422..8022d94862 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -39,11 +39,6 @@ static unsigned short highest_priority IBSS_ATTR;
39static int boosted_threads IBSS_ATTR; 39static int boosted_threads IBSS_ATTR;
40#endif 40#endif
41 41
42#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
43#define STAY_IRQ_LEVEL -1
44static int switch_to_irq_level = STAY_IRQ_LEVEL;
45#endif
46
47/* Define to enable additional checks for blocking violations etc. */ 42/* Define to enable additional checks for blocking violations etc. */
48#define THREAD_EXTRA_CHECKS 43#define THREAD_EXTRA_CHECKS
49 44
@@ -136,11 +131,11 @@ static inline void load_context(const void* addr)
136 "movem.l (%0),%%d0/%%d2-%%d7/%%a2-%%a7 \n" /* Load context */ 131 "movem.l (%0),%%d0/%%d2-%%d7/%%a2-%%a7 \n" /* Load context */
137 "move.l %%d0,%%macsr \n" 132 "move.l %%d0,%%macsr \n"
138 "move.l (52,%0),%%d0 \n" /* Get start address */ 133 "move.l (52,%0),%%d0 \n" /* Get start address */
139 "beq.b .running \n" /* NULL -> already running */ 134 "beq.b 1f \n" /* NULL -> already running */
140 "clr.l (52,%0) \n" /* Clear start address.. */ 135 "clr.l (52,%0) \n" /* Clear start address.. */
141 "move.l %%d0,%0 \n" 136 "move.l %%d0,%0 \n"
142 "jmp (%0) \n" /* ..and start the thread */ 137 "jmp (%0) \n" /* ..and start the thread */
143 ".running: \n" 138 "1: \n"
144 : : "a" (addr) : "d0" /* only! */ 139 : : "a" (addr) : "d0" /* only! */
145 ); 140 );
146} 141}
@@ -422,10 +417,10 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list)
422 /* This has to be done after the scheduler is finished with the 417 /* This has to be done after the scheduler is finished with the
423 blocked_list pointer so that an IRQ can't kill us by attempting 418 blocked_list pointer so that an IRQ can't kill us by attempting
424 a wake but before attempting any core sleep. */ 419 a wake but before attempting any core sleep. */
425 if (switch_to_irq_level != STAY_IRQ_LEVEL) 420 if (cores[CURRENT_CORE].switch_to_irq_level != STAY_IRQ_LEVEL)
426 { 421 {
427 int level = switch_to_irq_level; 422 int level = cores[CURRENT_CORE].switch_to_irq_level;
428 switch_to_irq_level = STAY_IRQ_LEVEL; 423 cores[CURRENT_CORE].switch_to_irq_level = STAY_IRQ_LEVEL;
429 set_irq_level(level); 424 set_irq_level(level);
430 } 425 }
431#endif 426#endif
@@ -442,13 +437,14 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list)
442 for (;;) 437 for (;;)
443 { 438 {
444 int priority = cores[CURRENT_CORE].running->priority; 439 int priority = cores[CURRENT_CORE].running->priority;
445 440
446 if (priority < highest_priority) 441 if (priority < highest_priority)
447 highest_priority = priority; 442 highest_priority = priority;
448 443
449 if (priority == highest_priority || 444 if (priority == highest_priority ||
450 (current_tick - cores[CURRENT_CORE].running->last_run > 445 (current_tick - cores[CURRENT_CORE].running->last_run >
451 priority * 8)) 446 priority * 8) ||
447 cores[CURRENT_CORE].running->priority_x != 0)
452 break; 448 break;
453 449
454 cores[CURRENT_CORE].running = cores[CURRENT_CORE].running->next; 450 cores[CURRENT_CORE].running = cores[CURRENT_CORE].running->next;
@@ -567,7 +563,7 @@ void block_thread_w_tmo(struct thread_entry **list, int timeout)
567#if defined(HAVE_EXTENDED_MESSAGING_AND_NAME) && !defined(SIMULATOR) 563#if defined(HAVE_EXTENDED_MESSAGING_AND_NAME) && !defined(SIMULATOR)
568void set_irq_level_and_block_thread(struct thread_entry **list, int level) 564void set_irq_level_and_block_thread(struct thread_entry **list, int level)
569{ 565{
570 switch_to_irq_level = level; 566 cores[CURRENT_CORE].switch_to_irq_level = level;
571 block_thread(list); 567 block_thread(list);
572} 568}
573 569
@@ -575,7 +571,7 @@ void set_irq_level_and_block_thread(struct thread_entry **list, int level)
575void set_irq_level_and_block_thread_w_tmo(struct thread_entry **list, 571void set_irq_level_and_block_thread_w_tmo(struct thread_entry **list,
576 int timeout, int level) 572 int timeout, int level)
577{ 573{
578 switch_to_irq_level = level; 574 cores[CURRENT_CORE].switch_to_irq_level = level;
579 block_thread_w_tmo(list, timeout); 575 block_thread_w_tmo(list, timeout);
580} 576}
581#endif 577#endif
@@ -688,6 +684,7 @@ struct thread_entry*
688 thread->stack_size = stack_size; 684 thread->stack_size = stack_size;
689 thread->statearg = 0; 685 thread->statearg = 0;
690#ifdef HAVE_PRIORITY_SCHEDULING 686#ifdef HAVE_PRIORITY_SCHEDULING
687 thread->priority_x = 0;
691 thread->priority = priority; 688 thread->priority = priority;
692 highest_priority = 100; 689 highest_priority = 100;
693#endif 690#endif
@@ -759,7 +756,7 @@ int thread_set_priority(struct thread_entry *thread, int priority)
759 756
760 if (thread == NULL) 757 if (thread == NULL)
761 thread = cores[CURRENT_CORE].running; 758 thread = cores[CURRENT_CORE].running;
762 759
763 old_priority = thread->priority; 760 old_priority = thread->priority;
764 thread->priority = priority; 761 thread->priority = priority;
765 highest_priority = 100; 762 highest_priority = 100;
@@ -774,7 +771,15 @@ int thread_get_priority(struct thread_entry *thread)
774 771
775 return thread->priority; 772 return thread->priority;
776} 773}
777#endif 774
775void priority_yield(void)
776{
777 struct thread_entry *thread = cores[CURRENT_CORE].running;
778 thread->priority_x = 1;
779 switch_thread(true, NULL);
780 thread->priority_x = 0;
781}
782#endif /* HAVE_PRIORITY_SCHEDULING */
778 783
779struct thread_entry * thread_get_current(void) 784struct thread_entry * thread_get_current(void)
780{ 785{
@@ -789,10 +794,14 @@ void init_threads(void)
789 memset(cores, 0, sizeof cores); 794 memset(cores, 0, sizeof cores);
790 cores[core].sleeping = NULL; 795 cores[core].sleeping = NULL;
791 cores[core].running = NULL; 796 cores[core].running = NULL;
797#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
798 cores[core].switch_to_irq_level = STAY_IRQ_LEVEL;
799#endif
792 cores[core].threads[0].name = main_thread_name; 800 cores[core].threads[0].name = main_thread_name;
793 cores[core].threads[0].statearg = 0; 801 cores[core].threads[0].statearg = 0;
794#ifdef HAVE_PRIORITY_SCHEDULING 802#ifdef HAVE_PRIORITY_SCHEDULING
795 cores[core].threads[0].priority = PRIORITY_USER_INTERFACE; 803 cores[core].threads[0].priority = PRIORITY_USER_INTERFACE;
804 cores[core].threads[0].priority_x = 0;
796 highest_priority = 100; 805 highest_priority = 100;
797#endif 806#endif
798#ifdef HAVE_SCHEDULER_BOOSTCTRL 807#ifdef HAVE_SCHEDULER_BOOSTCTRL