159,13 → 159,22 |
*/ |
void tasklet_schedule(tasklet_descriptor_t* t) |
{ |
tasklet_schedule_SMP(t, CPU->id); |
} |
|
/** Schedules the tasklet for execution on id CPU |
* @param t tasklet to be scheduled |
* @param id CPU id on which the tasklet will be scheduled |
*/ |
void tasklet_schedule_SMP(tasklet_descriptor_t* t, uint32_t id) |
{ |
spinlock_lock(&tasklet_lock); |
//clear notactive, running and scheduled flags |
t->state &= TASKLET_STATE_DISABLED; |
//set the scheduled flag |
t->state |= TASKLET_STATE_SCHEDULED; |
t->next=tasklet_list[CPU->id]; |
tasklet_list[CPU->id]=t; |
t->next=tasklet_list[id]; |
tasklet_list[id]=t; |
spinlock_unlock(&tasklet_lock); |
} |
|
203,24 → 212,31 |
if (t) { |
//empty the tasklet_list |
tasklet_list[CPU->id]=0; |
spinlock_unlock(&tasklet_lock); |
do { |
if (!(t->state & TASKLET_STATE_DISABLED)) { |
if (t->func) { |
t->state = TASKLET_STATE_RUNNING; |
t->func(t->data); |
t->state = TASKLET_STATE_NOTACTIVE; |
//clear running flag, set not active - the tasklet can disable itself |
//thats why we don't just set it as not active |
t->state &= ~TASKLET_STATE_RUNNING; |
t->state |= TASKLET_STATE_NOTACTIVE; |
} else |
panic_printf("tasklet func NULL\n"); |
} else { |
//return it back to the queue of scheduled tasklets |
spinlock_lock(&tasklet_lock); |
t->next = tasklet_list[CPU->id]; |
tasklet_list[CPU->id] = t; |
spinlock_unlock(&tasklet_lock); |
} |
t=t->next; |
} |
while (t); |
} |
spinlock_unlock(&tasklet_lock); |
else |
spinlock_unlock(&tasklet_lock); |
} |
|
/** Frees the tasklet structure when no longer needed. The function doesn't provide |