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); }
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); }