void tk_kill(task * tk_to_die) { task *tk; if(tk_died) /* Is another task in the process of dying? */ { tk_yield(); /* this should allow it to finish */ if(tk_died) /* Other task still dying? */ { dtrap(); /* system bug */ } } /* hunt for the task which tk_to_die is the successor of */ for (tk = tk_cur; tk->tk_next != tk_to_die; tk = tk->tk_next) ; /* now patch around tk_to_die */ tk->tk_next = tk_to_die->tk_next; /* If I'm killing myself, die the next time I block */ if (tk_cur == tk_to_die) { tk_died = tk_cur; } else tk_del(tk_to_die); }
void tk_block () { char msg[255]; task * tk = tk_cur; /* the next task to run */ /* check if the guard word is still intact */ if (*(tk->tk_guard) != GUARDWORD) { sprintf(msg, "tk_block stack: task name = %s", tk->tk_name); panic(msg); return; } #ifdef NPDEBUG if (TDEBUG) dprintf("TASK: Task %s blocking.\n", tk->tk_name); #endif IN_PROFILER(PF_IDLE, PF_ENTRY); /* measure time in the idle loop */ /* find the next ready to run task */ do { tk = tk->tk_next; /* see if a sleeping task is ready to wake */ if (tk->tk_waketick && tk->tk_waketick < cticks) { tk->tk_waketick = 0; /* clear wakeup tick flag */ break; /* go run this task */ } } while ((tk->tk_flags & TF_AWAKE) == 0); IN_PROFILER(PF_IDLE, PF_EXIT); tk->tk_flags &= ~TF_AWAKE; /* clear wake flag before it runs */ tk_switch (tk); /* Run the next task. */ #ifdef NPDEBUG if (TDEBUG) dprintf("TASK: Task %s running\n", tk_cur->tk_name); #endif if (tk_died) { tk_del(tk_died); /* delete dead task */ tk_died = NULL; /* clear pointer/flag */ } }
/* FUNCTION: tk_block() * * Block the currently running task and run the next task in the * circular list of tasks that is awake. Before returning, see if any * cleanup has to be done for another task. * * PARAMS: task * pointer to currently executing task or NULL * * RETURN: none */ void tk_block(TASK *tk_old) { TASK *tk, *tk_prev; /* check the stack of the currently executing task for overflow */ if (tk_old != (TASK *)NULL) { /* check if the guard word is still intact */ if (*(tk_cur->tk_guard) != GUARDWORD) { dprintf("tk_block stack: task name = %s", tk_cur->tk_name); dtrap(); return; } } #ifdef NPDEBUG if (TDEBUG) dprintf("TASK: Task %s blocking.\n", tk_cur->tk_name); #endif IN_PROFILER(PF_IDLE, PF_ENTRY); /* measure time in the idle loop */ /* find the next ready to run task */ tk = tk_cur; #ifdef DEBUG_TASK_STATE dprintf("tk_block: %s, flags = %lx, event = %p\n", tk->tk_name, tk->tk_flags, tk->tk_event); #endif do { tk_prev = tk; tk = tk->tk_next; /* TODO: check for deleted task here */ /* see if a sleeping task is ready to wake */ if ((tk->tk_flags & TF_TIMER) && TIME_EXP(tk->tk_waketick, CTICKS)) { tk_timeout(tk); /* clean up after timeout */ } } while (!(tk->tk_flags & TF_AWAKE)); IN_PROFILER(PF_IDLE, PF_EXIT); tk->tk_count++; /* increment wakeup count */ tk_cur = tk; /* update current task pointer */ #ifdef NPDEBUG if (TDEBUG) dprintf("TASK: Task %s running\n", tk->tk_name); #endif #ifdef DEBUG_TASK_STATE dprintf("tk_ready: %s, flags = %lx, event = %p\n", tk->tk_name, tk->tk_flags, tk->tk_event); #endif tk_switch (tk, tk_old); /* Run the next task. */ if (tk_died) { tk_del(tk_died); /* delete dead task */ tk_died = NULL; /* clear pointer/flag */ } }