Пример #1
0
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);
}
Пример #2
0
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 */
   }
}
Пример #3
0
/* 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 */
   }
}