Rev 2296 | Rev 2330 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2296 | Rev 2309 | ||
---|---|---|---|
Line 157... | Line 157... | ||
157 | /** Schedules the tasklet for execution on current CPU |
157 | /** Schedules the tasklet for execution on current CPU |
158 | * @param t tasklet to be scheduled |
158 | * @param t tasklet to be scheduled |
159 | */ |
159 | */ |
160 | void tasklet_schedule(tasklet_descriptor_t* t) |
160 | void tasklet_schedule(tasklet_descriptor_t* t) |
161 | { |
161 | { |
- | 162 | tasklet_schedule_SMP(t, CPU->id); |
|
- | 163 | } |
|
- | 164 | ||
- | 165 | /** Schedules the tasklet for execution on id CPU |
|
- | 166 | * @param t tasklet to be scheduled |
|
- | 167 | * @param id CPU id on which the tasklet will be scheduled |
|
- | 168 | */ |
|
- | 169 | void tasklet_schedule_SMP(tasklet_descriptor_t* t, uint32_t id) |
|
- | 170 | { |
|
162 | spinlock_lock(&tasklet_lock); |
171 | spinlock_lock(&tasklet_lock); |
163 | //clear notactive, running and scheduled flags |
172 | //clear notactive, running and scheduled flags |
164 | t->state &= TASKLET_STATE_DISABLED; |
173 | t->state &= TASKLET_STATE_DISABLED; |
165 | //set the scheduled flag |
174 | //set the scheduled flag |
166 | t->state |= TASKLET_STATE_SCHEDULED; |
175 | t->state |= TASKLET_STATE_SCHEDULED; |
167 | t->next=tasklet_list[CPU->id]; |
176 | t->next=tasklet_list[id]; |
168 | tasklet_list[CPU->id]=t; |
177 | tasklet_list[id]=t; |
169 | spinlock_unlock(&tasklet_lock); |
178 | spinlock_unlock(&tasklet_lock); |
170 | } |
179 | } |
171 | 180 | ||
172 | /** Tasklet will not be run, even if scheduled |
181 | /** Tasklet will not be run, even if scheduled |
173 | * @param t tasklet to be disabled |
182 | * @param t tasklet to be disabled |
Line 201... | Line 210... | ||
201 | tasklet_descriptor_t* t = tasklet_list[CPU->id]; |
210 | tasklet_descriptor_t* t = tasklet_list[CPU->id]; |
202 | //printf("."); |
211 | //printf("."); |
203 | if (t) { |
212 | if (t) { |
204 | //empty the tasklet_list |
213 | //empty the tasklet_list |
205 | tasklet_list[CPU->id]=0; |
214 | tasklet_list[CPU->id]=0; |
- | 215 | spinlock_unlock(&tasklet_lock); |
|
206 | do { |
216 | do { |
207 | if (!(t->state & TASKLET_STATE_DISABLED)) { |
217 | if (!(t->state & TASKLET_STATE_DISABLED)) { |
208 | if (t->func) { |
218 | if (t->func) { |
209 | t->state = TASKLET_STATE_RUNNING; |
219 | t->state = TASKLET_STATE_RUNNING; |
210 | t->func(t->data); |
220 | t->func(t->data); |
- | 221 | //clear running flag, set not active - the tasklet can disable itself |
|
- | 222 | //thats why we don't just set it as not active |
|
- | 223 | t->state &= ~TASKLET_STATE_RUNNING; |
|
211 | t->state = TASKLET_STATE_NOTACTIVE; |
224 | t->state |= TASKLET_STATE_NOTACTIVE; |
212 | } else |
225 | } else |
213 | panic_printf("tasklet func NULL\n"); |
226 | panic_printf("tasklet func NULL\n"); |
214 | } else { |
227 | } else { |
215 | //return it back to the queue of scheduled tasklets |
228 | //return it back to the queue of scheduled tasklets |
- | 229 | spinlock_lock(&tasklet_lock); |
|
216 | t->next = tasklet_list[CPU->id]; |
230 | t->next = tasklet_list[CPU->id]; |
217 | tasklet_list[CPU->id] = t; |
231 | tasklet_list[CPU->id] = t; |
- | 232 | spinlock_unlock(&tasklet_lock); |
|
218 | } |
233 | } |
219 | t=t->next; |
234 | t=t->next; |
220 | } |
235 | } |
221 | while (t); |
236 | while (t); |
222 | } |
237 | } |
- | 238 | else |
|
223 | spinlock_unlock(&tasklet_lock); |
239 | spinlock_unlock(&tasklet_lock); |
224 | } |
240 | } |
225 | 241 | ||
226 | /** Frees the tasklet structure when no longer needed. The function doesn't provide |
242 | /** Frees the tasklet structure when no longer needed. The function doesn't provide |
227 | * any synchronization, the caller must be sure, the tasklet is not scheduled. |
243 | * any synchronization, the caller must be sure, the tasklet is not scheduled. |
228 | * |
244 | * |