@@ -101,20 +101,28 @@ static inline uint32_t task_get_irq(struct task *task)
101101static inline void task_set_data (struct task * task )
102102{
103103 struct list_item * dst = NULL ;
104+ struct irq_task * irq_task ;
105+ uint32_t flags ;
104106
105107 switch (task -> priority ) {
106108 case TASK_PRI_MED + 1 ... TASK_PRI_LOW :
107- dst = & ((* task_irq_low_get ())-> list );
109+ irq_task = * task_irq_low_get ();
110+ dst = & irq_task -> list ;
108111 break ;
109112 case TASK_PRI_HIGH ... TASK_PRI_MED - 1 :
110- dst = & ((* task_irq_high_get ())-> list );
113+ irq_task = * task_irq_high_get ();
114+ dst = & irq_task -> list ;
111115 break ;
112116 case TASK_PRI_MED :
113117 default :
114- dst = & ((* task_irq_med_get ())-> list );
118+ irq_task = * task_irq_med_get ();
119+ dst = & irq_task -> list ;
115120 break ;
116121 }
122+
123+ spin_lock_irq (& irq_task -> lock , flags );
117124 list_item_append (& task -> irq_list , dst );
125+ spin_unlock_irq (& irq_task -> lock , flags );
118126}
119127
120128/**
@@ -129,21 +137,19 @@ static void _irq_task(void *arg)
129137 struct task * task ;
130138 uint32_t flags ;
131139
132- /* intentionally don't lock list to have task added from schedule irq */
133- list_for_item (tlist , & irq_task -> list ) {
134- task = container_of (tlist , struct task , irq_list );
140+ spin_lock_irq (& irq_task -> lock , flags );
141+ list_for_item_safe (clist , tlist , & irq_task -> list ) {
135142
136- if ( task -> func )
137- task -> func ( task -> data );
143+ task = container_of ( clist , struct task , irq_list );
144+ list_item_del ( clist );
138145
139- schedule_task_complete (task );
140- }
146+ spin_unlock_irq (& irq_task -> lock , flags );
141147
142- spin_lock_irq (& irq_task -> lock , flags );
148+ if (task -> func && task -> state == TASK_STATE_RUNNING )
149+ task -> func (task -> data );
143150
144- list_for_item_safe (clist , tlist , & irq_task -> list ) {
145- task = container_of (clist , struct task , irq_list );
146- list_item_del (& task -> irq_list );
151+ schedule_task_complete (task );
152+ spin_lock_irq (& irq_task -> lock , flags );
147153 }
148154
149155 interrupt_clear (irq_task -> irq );
0 commit comments