Example #1
0
task *
tk_init(stack_t * st_base, int st_size)
{
   task *tk;      /* pointer to the first task */
   stack_t * sp;

   /* create the first task */
   tk = (task*)TK_ALLOC(sizeof(struct task));

   /* return immediately if task structure could not be
    * allocated.  The caller must handle this scenario.
    */
   if (!tk) 
   {
      ++tk_allocfail;
      return(tk);
   }

   tk_cur = tk;      /* It is the currently running task */
   /* Task is running thus does not need to be awakened. */
   tk->tk_flags = TF_MAIN; /* mark it as using system stack */
   tk->tk_name = "Main";
   tk->tk_next = tk;       /* task is only one in list */
   tk->tk_count = 0;
   tk->tk_size = st_size;
   tk->tk_stack = st_base;

   /* fill the system stack with the guardword */
   sp = tk_getsp();
#ifdef STK_TOPDOWN   /* Intel x86 "top down" stack */
   while (sp > st_base)
   {
      sp--; /* stop when sp == base */
      *sp = GUARDWORD;
   }
#elif STK_BOTTOMUP   /* stack moves from bottom up */
   {  stack_t * stacktop = st_base + st_size/sizeof(stack_t);
      while (sp < stacktop)
      {
         sp++;
         *sp = GUARDWORD;
      }
   }
#else
#error You must define a stack type! (STK_TOPDOWN or STK_BOTTOMUP)
#endif

   tk->tk_guard = sp;   /* set address for stack check */

#ifdef   DEBUG
   if (TDEBUG)
      dprintf("tk_init: Initial stack size = %d\n", tk->tk_size);
#endif

   return(tk);
}
Example #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);
}