home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / DOOG / CTASK.ZIP / TSKSUB.C < prev    next >
C/C++ Source or Header  |  1989-12-20  |  7KB  |  299 lines

  1. /*
  2.     --- Version 2.0 89-12-17 21:19 ---
  3.  
  4.    CTask Subroutines
  5.  
  6.    Public Domain Software written by
  7.       Thomas Wagner
  8.       Patschkauer Weg 31
  9.       D-1000 Berlin 33
  10.       West Germany
  11. */
  12.  
  13. #include <stdio.h>
  14.  
  15. #include "tsk.h"
  16. #include "tsklocal.h"
  17.  
  18.  
  19. /*
  20.    tsk_runable
  21.       Make a task eligible for running. The task is removed from the
  22.       timer queue and enqueued in the eligible queue.
  23.  
  24.       CAUTION: Critical section assumed entered.
  25. */
  26.  
  27. void near tsk_runable (tcbptr task)
  28. {
  29.    task->state = ST_ELIGIBLE;
  30.    tsk_deqtimer (&task->timerq.link);
  31.    tsk_dequeue (&task->cqueue);
  32.    tsk_enqueue (task->qhead = &GLOBDATA eligible_queue, &task->cqueue);
  33. }
  34.  
  35.  
  36. /*
  37.    tsk_runable_all
  38.       Make all tasks in a queue eligible for running.
  39.  
  40.       CAUTION: Critical section assumed entered.
  41. */
  42.  
  43. void near tsk_runable_all (queheadptr que)
  44. {
  45.    queptr curr;
  46.    tcbptr task;
  47.  
  48.    for (curr = que->first; curr->kind; )
  49.       {
  50.       task = (tcbptr)curr;
  51.       curr = curr->next;
  52.       task->state = ST_ELIGIBLE;
  53.       tsk_deqtimer (&task->timerq.link);
  54.       tsk_enqueue (task->qhead = &GLOBDATA eligible_queue, &task->cqueue);
  55.       }
  56.    tsk_init_qhead (que);
  57. }
  58.  
  59.  
  60. /*
  61.    tsk_wait
  62.       put current running task in wait state.
  63.       Note that the task is NOT enqueued in the respective queue
  64.       here, this is done by the scheduler based on the queue head
  65.       pointer. Only the timeout queue is affected directly.
  66.  
  67.       CAUTION: Critical section assumed entered.
  68. */
  69.  
  70. void near tsk_wait (queheadptr que, dword timeout)
  71. {
  72.    tcbptr curr;
  73.  
  74.    curr = GLOBDATA current_task;
  75.    /*
  76.       Note: The following test shouldn't be necessary. However,
  77.       there is a time when the current task is *not* running, and
  78.       that's while the scheduler is waiting for a task to become
  79.       eligible. If an interrupt handler causes the current task to
  80.       be made waiting during this time, we have to take care not to
  81.       kill the eligible queue. Well, no interrupt handler should ever
  82.       do such a nasty thing, but...
  83.    */
  84.    if (curr->state != ST_RUNNING)
  85.       {
  86.       tsk_dequeue (&curr->cqueue);
  87.       tsk_deqtimer (&curr->timerq.link);
  88.       tsk_enqueue (que, &curr->cqueue);
  89.       }
  90.    curr->qhead = que;
  91.    curr->state = ST_WAITING;
  92.    if (timeout)
  93.       {
  94.       tsk_enqtimer (&curr->timerq.link, timeout);
  95.       curr->timerq.tstate = TSTAT_COUNTDOWN;
  96.       }
  97.    schedule ();
  98. }
  99.  
  100.  
  101. /*
  102.    tsk_kill
  103.       mark task as killed.
  104.  
  105.       CAUTION: Critical section assumed entered.
  106. */
  107.  
  108. void near tsk_kill (tcbptr task)
  109. {
  110.    task->state = ST_KILLED;
  111.    task->qhead = NULL;
  112.    tsk_deqtimer (&task->timerq.link);
  113.  
  114. #if (TSK_NAMED)
  115.    tsk_dequeue ((queptr)&task->name.list);
  116. #endif
  117.  
  118. #if (TSK_DYNAMIC)
  119.    if (task->flags & F_STTEMP)
  120.       tsk_free (task->stack);
  121.    if (task->flags & F_TEMP)
  122.       tsk_free (task);
  123. #endif
  124. }
  125.  
  126. /*
  127.    tsk_kill_queue
  128.       Removes all tasks from a queue. For internal use only.
  129.  
  130.       CAUTION: Critical section assumed entered.
  131. */
  132.  
  133. void near tsk_kill_queue (queheadptr que)
  134. {
  135.    queptr curr, next;
  136.  
  137.    for (curr = que->first; curr->kind; )
  138.       {
  139.       next = curr->next;
  140.       tsk_kill ((tcbptr)curr);
  141.       curr = next;
  142.       }
  143.    tsk_init_qhead (que);
  144. }
  145.  
  146.  
  147. #if (CLOCK_MSEC)
  148.  
  149. dword near tsk_timeout (dword tout)
  150. {
  151.    dword t;
  152.  
  153.    t = (dword) (((double)tout / tick_factor) + 0.5);
  154.    return (t) ? t : 1; 
  155. }
  156.  
  157. #endif
  158.  
  159. #if (TSK_NAMED)
  160.  
  161.  
  162. /*
  163.    tsk_copy_name
  164.       A replacement for strcpy, used for copying names. The C-runtime
  165.       strcpy is not used here to keep the kernel model independent.
  166. */
  167.  
  168. void near tsk_copy_name (nameptr elem, byteptr name)
  169. {
  170.    byteptr n;
  171.    int i;
  172.  
  173.    n = elem->name;
  174.    if (name != NULL)
  175.       for (i = 0; i < 8; i++)
  176.             if ((*n++ = *name++) == 0)
  177.             break;
  178.    *n = 0;
  179. }
  180.  
  181.  
  182. /*
  183.    tsk_add_name
  184.       Initialise name-list element and insert it into the name list.
  185.       NOTE: no check is made for duplicate names; names are not sorted.
  186. */
  187.  
  188. void near tsk_add_name (nameptr elem, byteptr name, byte kind, farptr strucp)
  189. {
  190.    CRITICAL;
  191.  
  192.    elem->list.kind = kind;
  193.    elem->strucp = strucp;
  194.    tsk_copy_name (elem, name);
  195.  
  196.    C_ENTER;
  197. #if (GROUPS)
  198.    tsk_putqueue (&GLOBDATA current_task->group->namelist.list, (queptr)&elem->list);
  199. #else
  200.    tsk_putqueue (&GLOBDATA name_list.list, &elem.list);
  201. #endif
  202.    C_LEAVE;
  203. }
  204.  
  205.  
  206. /*
  207.    tsk_del_name
  208.       delete name-element from the name-list.
  209. */
  210.  
  211. void near tsk_del_name (nameptr elem)
  212. {
  213.    CRITICAL;
  214.  
  215.    C_ENTER;
  216.    tsk_dequeue ((queptr)&elem->list);
  217.    C_LEAVE;
  218. }
  219.  
  220.  
  221. /*
  222.    find_name
  223.       find structure, given name and type. 
  224.       If type is zero, the first name-element matching the name is returned.
  225.       If type is nonzero, the first structure matching the name and type is
  226.       returned.
  227. */
  228.  
  229. local int near tsk_streq (byteptr n1, byteptr n2)
  230. {
  231.    while (*n1 && *n1 == *n2)
  232.       {
  233.       n1++;
  234.       n2++;
  235.       }
  236.    return *n1 == *n2; 
  237. }
  238.  
  239. #if (GROUPS)
  240. farptr far find_group_name (gcbptr group, byteptr name, int kind)
  241. {
  242.    queptr curr;
  243.  
  244.    if (kind == TYP_GROUP && tsk_streq (name, group->namelist.name))
  245.       return group;
  246.  
  247.    for (curr = group->namelist.list.first; curr->kind; curr = curr->next)
  248.       if (kind < 0 || (int)curr->kind == kind)
  249.          if (tsk_streq (name, ((nameptr)curr)->name))
  250.             return (kind >= 0) ? ((nameptr)curr)->strucp : curr;
  251.  
  252.    return NULL;
  253. }
  254. #endif
  255.  
  256.  
  257. farptr far find_name (byteptr name, int kind)
  258. {
  259. #if (GROUPS)
  260.    farptr curr;
  261.    gcbptr group;
  262.  
  263.    if (tsk_global == NULL)
  264.       if (!ctask_resident ())
  265.          return NULL;
  266.  
  267.     for (group = GLOBDATA current_task->group; 
  268.         group != NULL; group = group->home)
  269.       if ((curr = find_group_name (group, name, kind)) != NULL)
  270.          return curr;
  271. #else
  272.    queueptr curr;
  273.  
  274.    if (kind == TYP_GROUP && tsk_streq (name, GLOBDATA name_list.name))
  275.       return group;
  276.  
  277.    for (curr = GLOBDATA name_list.list.first; curr->kind; 
  278.         curr = curr->next)
  279.       if (kind < 0 || (int)curr->kind == kind)
  280.          if (tsk_streq (name, ((nameptr)curr)->name))
  281.             return (kind >= 0) ? ((nameptr)curr)->strucp : curr;
  282. #endif
  283.  
  284.    return NULL;
  285. }
  286. #endif
  287.  
  288. /*
  289.    tsk_init_qhead
  290.       Initializes the head of a queue.
  291. */
  292.  
  293. void near tsk_init_qhead (queheadptr head)
  294. {
  295.    head->kind = 0;
  296.    head->first = head->last = (queptr)head;
  297. }
  298.  
  299.