Skip to content

Commit 7be08fd

Browse files
committed
task: refine task to avoid double task function run
Add spinlock to the arch task irq list to avoid double function run. Signed-off-by: Pan Xiuli <xiuli.pan@linux.intel.com>
1 parent f17abe6 commit 7be08fd

1 file changed

Lines changed: 20 additions & 14 deletions

File tree

  • src/arch/xtensa/include/arch

src/arch/xtensa/include/arch/task.h

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,20 +101,28 @@ static inline uint32_t task_get_irq(struct task *task)
101101
static 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

Comments
 (0)