home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / ctask.zip / TSKSUB.C < prev    next >
C/C++ Source or Header  |  1988-03-01  |  4KB  |  194 lines

  1. /*
  2.    CTask Subroutines
  3.  
  4.    Public Domain Software written by
  5.       Thomas Wagner
  6.       Patschkauer Weg 31
  7.       D-1000 Berlin 33
  8.       West Germany
  9. */
  10.  
  11. #include <stdio.h>
  12.  
  13. #include "tsk.h"
  14. #include "tsklocal.h"
  15.  
  16. /*
  17.    tsk_enqueue  inserts a task into a queue based on priority.
  18. */
  19.  
  20. void far tsk_enqueue (tcbptr task, tqueptr que)
  21. {
  22.    tcbptr last, curr;
  23.  
  24.    last = NULL;
  25.    curr = *que;
  26.  
  27.    while (curr != NULL && curr->prior >= task->prior)
  28.       {
  29.       last = curr;
  30.       curr = curr->next;
  31.       }
  32.    task->next = curr;
  33.    if (last == NULL)
  34.       *que = task;
  35.    else
  36.       last->next = task;
  37.    task->queue = que;
  38. }
  39.  
  40.  
  41. /*
  42.    tsk_unqueue 
  43.       Removes a task from somewhere in the middle of a queue. It is only
  44.       used when stopping or prematurely waking a task, since in all other 
  45.       circumstances a task is only removed from the head of a queue.
  46. */
  47.  
  48. void far tsk_unqueue (tcbptr task)
  49. {
  50.    tcbptr last, curr;
  51.  
  52.    if (task->state == ST_RUNNING || task->queue == NULL)
  53.       return;
  54.  
  55.    last = NULL;
  56.    curr = *task->queue;
  57.  
  58.    while (curr != task)
  59.       {
  60.       if (curr == NULL)
  61.          return;
  62.       last = curr;
  63.       curr = curr->next;
  64.       }
  65.    if (last == NULL)
  66.       *task->queue = curr->next;
  67.    else
  68.       last->next = curr->next;
  69.    task->queue = NULL;
  70. }
  71.  
  72.  
  73. /*
  74.    tsk_enqtimer inserts a task into the timer queue.
  75. */
  76.  
  77. void far tsk_enqtimer (tcbptr task, dword tout)
  78. {
  79.    dlinkptr curr;
  80.  
  81.    if (tout == 0)
  82.       return;
  83.  
  84.    /*
  85.       Tasks are not sorted in the timer queue, so the task is inserted
  86.       at the queue head. The timer task has to step through all tasks
  87.       in the queue to cont down the timeout, so sorting would not bring
  88.       any advantages.
  89.    */
  90.  
  91.    curr = &task->timerq;
  92.    curr->follow = tsk_timer.follow;
  93.    curr->prev = &tsk_timer;
  94.    tsk_timer.follow = curr;
  95.    curr->follow->prev = curr;
  96.  
  97.    curr->timeout = tout;
  98.    task->flags |= F_TIMER;
  99. }
  100.  
  101.  
  102. /*
  103.    tsk_unqtimer 
  104.       Removes a task from the timer queue. 
  105. */
  106.  
  107. void far tsk_unqtimer (tcbptr task)
  108. {
  109.    dlinkptr curr;
  110.  
  111.    if (!(task->flags & F_TIMER))
  112.       return;
  113.  
  114.    task->flags &= ~F_TIMER;
  115.    curr = &task->timerq;
  116.  
  117.    curr->prev->follow = curr->follow;
  118.    curr->follow->prev = curr->prev;
  119. }
  120.  
  121. /*
  122.    tsk_runable
  123.       make a task eligible for running. The task is removed from the
  124.       timer queue and enqueued in the eligible queue. The old "next"
  125.       pointer of the tcb is returned. This assumes that the task
  126.       is removed from the head of a queue.
  127. */
  128.  
  129. tcbptr far tsk_runable (tcbptr task)
  130. {
  131.    tcbptr nxt;
  132.  
  133.    nxt = task->next;
  134.    task->state = ST_ELIGIBLE;
  135.    tsk_unqtimer (task);
  136.    tsk_enqueue (task, &tsk_eligible);
  137.    return nxt;
  138. }
  139.  
  140.  
  141. /*
  142.    tsk_wakeup
  143.       make a task eligible for running. The task is removed from the
  144.       timer queue and enqueued in the eligible queue. 
  145.       This routine assumes that the task is removed from the middle of
  146.       a queue.
  147. */
  148.  
  149. void far tsk_wakeup (tcbptr task)
  150. {
  151.    task->state = ST_ELIGIBLE;
  152.    tsk_unqueue (task);
  153.    tsk_unqtimer (task);
  154.    tsk_enqueue (task, &tsk_eligible);
  155. }
  156.  
  157.  
  158. /*
  159.    tsk_wait - put current running task in wait state.
  160.               Note that the task is NOT enqueued in the respective queue
  161.               here, this is done by the scheduler based on the queue head
  162.               pointer. Only the timeout queue is affected directly.
  163. */
  164.  
  165. void far tsk_wait (tqueptr que, dword timeout)
  166. {
  167.    tsk_current->state = ST_WAITING;
  168.    tsk_current->queue = que;
  169.    tsk_enqtimer (tsk_current, timeout);
  170.    schedule ();
  171. }
  172.  
  173.  
  174. /*
  175.    tsk_kill_queue
  176.       Removes all tasks from a queue. For internal use only, critical
  177.       section assumed entered.
  178. */
  179.  
  180. void far tsk_kill_queue (tqueptr que)
  181. {
  182.    tcbptr curr;
  183.  
  184.    for (curr = *que; curr != NULL; curr = curr->next)
  185.       {
  186.       tsk_unqtimer (curr);
  187.       curr->state = ST_KILLED;
  188.       }
  189.    *que = NULL;
  190. }
  191.  
  192.  
  193.  
  194.