Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2330 → Rev 2430

/branches/rcu/kernel/generic/src/proc/tasklet.c
30,7 → 30,8
/** @addtogroup genericddi
* @{
*/
/** @file
/** @file tasklet.c
* @brief Tasklet implementation
*/
 
#include <arch.h>
91,10 → 92,10
//create the tasklet_thread, it's wired to the current cpu, we'll migrate it ourselves
thread_t* t= thread_create(&tasklet_thread, NULL, kernel_task, THREAD_FLAG_WIRED, "tasklet_thread", false);
if (t==NULL) {
//wtf?
panic_printf("tasklet thread not created\n");
} else {
spinlock_lock(&t->lock);
spinlock_lock(&t->lock);
//we'll default on the first CPU
t->cpu = &cpus[0];
t->priority = TASKLET_THREAD_PRIORITY;
spinlock_unlock(&t->lock);
114,21 → 115,25
waitq_t wq;
waitq_initialize(&wq);
//the infinite loop
while (true) {
//execute any scheduled tasklets
tasklet_do();
#ifdef CONFIG_SMP
//check whether other CPUs have tasklets to execute
if (config.cpu_active>1) {
current_cpu = CPU->id;
//find the first cpu with nonempty tasklet_list
for (new_cpu = (current_cpu + 1) % config.cpu_active; new_cpu!=current_cpu && tasklet_list[new_cpu]==0 && cpus[new_cpu].active;
new_cpu=(new_cpu + 1)% config.cpu_active);
for (new_cpu = (current_cpu + 1) % config.cpu_count; new_cpu!=current_cpu && tasklet_list[new_cpu]==0 ;
new_cpu=(new_cpu + 1)% config.cpu_count);
 
if (new_cpu!=current_cpu) {
//if we found a CPU with unsatisfied tasklet schedule to run there. It must be active!
if (new_cpu!=current_cpu && cpus[new_cpu].active) {
//we need to migrate this thread to CPU with id new_cpu
cpu = &cpus[new_cpu];
 
spinlock_lock(&THREAD->lock);
//put tasklet_thread on the new_cpu
//move tasklet_thread on the new_cpu
THREAD->cpu = cpu;
spinlock_unlock(&THREAD->lock);
}
203,12 → 208,12
 
 
 
/** Executes scheduled enabled tasklets on current CPU */
/** Executes scheduled enabled tasklets on current CPU
* this function could be called from other parts of kernel */
void tasklet_do(void)
{
spinlock_lock(&tasklet_lock);
tasklet_descriptor_t* t = tasklet_list[CPU->id];
//printf(".");
if (t) {
//empty the tasklet_list
tasklet_list[CPU->id]=0;
218,8 → 223,7
if (t->func) {
t->state = TASKLET_STATE_RUNNING;
t->func(t->data);
//clear running flag, set not active - the tasklet can disable itself
//thats why we don't just set it as not active
//clear running flag, set not active
t->state &= ~TASKLET_STATE_RUNNING;
t->state |= TASKLET_STATE_NOTACTIVE;
} else
240,7 → 244,7
}
 
/** Frees the tasklet structure when no longer needed. The function doesn't provide
* any synchronization, the caller must be sure, the tasklet is not scheduled.
* any synchronization, the caller must be sure, that the tasklet is not scheduled.
*
* @param tasklet to be freed
*/