Ejemplo n.º 1
0
task * 
tk_new(task * prev_tk,     /* predecessor (sp?) to the new task */
   int    (*start)(int),   /* Where the new task starts execution. */
   int      stksiz,  /* The size in bytes of the stack of the new task. */
   char   * name,    /* The task's name as a string */
   int      arg)     /* argument to the task */
{
   task * tk;     /* a pointer to the new task */
   stack_t * sp;  /* pointer to task stack area for fill */

   /* create the new task */
   tk = (task *)TK_ALLOC(sizeof(task));
   if (tk == NULL)
   {
      ++tk_allocfail;
      return NULL;        /* if no memory left, return null */
   }
   tk->tk_size = stksiz;
   tk->tk_stack = (stack_t *)STK_ALLOC(stksiz);
   if (tk->tk_stack == NULL)
   {
      ++tk_allocfail;
      TK_FREE(tk);
      return NULL;
   }

   /* set it up to run */
   tk->tk_fp = tk_frame (tk, start, arg);

   /* fill stack with guardword */
   sp = tk->tk_fp;

#ifdef STK_TOPDOWN   /* Intel x86 "top down" stack */
   sp--;
   while (sp > tk->tk_stack)
   {
      sp--;
      *sp = GUARDWORD;
   }
#else /* stack moves from bottom up */
   dtrap(); /* untested */
   x = stksiz - (sp - tk->tk_stack);   /* bytes to fill */
   x = x/(sizeof(stack_t));
   x++;
   sp++;
   while (x++ > 0)
      *sp++ = GUARDWORD;   
#endif

   tk->tk_guard = sp;
   tk->tk_flags |= TF_AWAKE;  /* Schedule the task to run. */
   tk->tk_next = prev_tk->tk_next;  /* Fit it in after prev_tk. */
   prev_tk->tk_next = tk;
   tk->tk_name = name;        /* Set its name */
   tk->tk_count = 0;          /* init the count */

   return (tk);
}
Ejemplo n.º 2
0
TASK * 
tk_new(TASK *prev_tk, void (*start)(void *), int stksiz, char *name,
       uint32_t flags, void *arg)
{
   TASK *tk;                  /* a pointer to the new task */
   int  i;

   /* find unused task struct */
   tk = tk_tasklist;
   for (i = 0; i < tk_max_tasks; i++)
   {
      if (tk->tk_flags == 0)
         break;
      tk++;
   }

   if (i >= tk_max_tasks)
   {
      ++tk_allocfail;
      return ((TASK *)NULL);  /* if no memory left, return null */
   }

#ifndef SUPERLOOP

   if (flags & TF_MAIN)       /* task will use system stack */
   {
      tk->tk_size = stksiz;
      tk->tk_stack = tk_getspbase() - (stksiz / sizeof(stack_t));
      tk->tk_fp = tk_getsp();
   }
   else                       /* task will use private stack */
   {
      tk->tk_size = stksiz;
      tk->tk_stack = (stack_t *)STK_ALLOC(stksiz);
      if (tk->tk_stack == (stack_t *)NULL)
      {
         ++tk_allocfail;
         return ((TASK *)NULL);
      }

      /* set it up to run */
      tk->tk_fp = tk_frame(tk, start, arg);
   }

   /* fill stack with guardword */
   {
      stack_t *sp = tk->tk_fp;   /* pointer to task stack area for fill */

#ifdef STK_TOPDOWN   /* Intel x86 "top down" stack */
      sp--;
      while (sp > tk->tk_stack)
      {
         sp--;
         *sp = GUARDWORD;
      }
      tk->tk_guard = sp;
#else /* stack moves from bottom up */
      dtrap(); /* untested */
      x = stksiz - (sp - tk->tk_stack);   /* bytes to fill */
      x = x/(sizeof(stack_t));
      x++;
      sp++;
      while (x++ > 0)
         *sp++ = GUARDWORD;   
#endif
   }

   /* add the new task to the list of tasks */
   if (prev_tk)
   {
      tk->tk_next = prev_tk->tk_next;  /* Fit it in after prev_tk. */
      prev_tk->tk_next = tk;
   }
   else     /* insert task before the current task */
   {
      prev_tk = tk_cur;
      if (prev_tk == (TASK *)NULL)
      {
         tk->tk_next = tk;
         tk_cur = tk;
      }
      else
      {
         while (prev_tk->tk_next != tk_cur)
            prev_tk = prev_tk->tk_next;
         tk->tk_next = prev_tk->tk_next;  /* Fit it in after prev_tk */
         prev_tk->tk_next = tk;
      }
   }

   tk->tk_event = NULL;
   if ((tk->tk_semaphore = SEM_ALLOC()) == (IN_SEM *)NULL)
   {
      ++tk_allocfail;
      return ((TASK *)NULL);
   }

#else  /* SUPERLOOP */

   tk->tk_flags |= TF_MAIN;
   tk->tk_func = start;
   tk->tk_param = arg;

#endif /* SUPERLOOP */

   tk->tk_name = name;        /* Set its name */
   tk->tk_count = 0;          /* init the wakeup count */
   tk->tk_waketick = 0;
   tk->tk_flags |= (flags | TF_ACTIVE);

#ifndef SUPERLOOP
   TK_SUSPEND(tk);
#endif

   return (tk);
}