home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CTASK22.ZIP / TSKCNT.C < prev    next >
C/C++ Source or Header  |  1990-10-12  |  5KB  |  234 lines

  1. /*
  2.    --- Version 2.2 90-10-12 10:33 ---
  3.  
  4.    TSKCNT.C - CTask - Counter handling routines.
  5.  
  6.    Public Domain Software written by
  7.       Thomas Wagner
  8.       Ferrari electronic Gmbh
  9.       Beusselstrasse 27
  10.       D-1000 Berlin 21
  11.       Germany
  12.  
  13.    Version 2.1 adds the dec_counter operation, and changes inc_counter
  14.    to return the new value of the counter state (previously, it returned
  15.    nothing).
  16. */
  17.  
  18. #include "tsk.h"
  19. #include "tsklocal.h"
  20.  
  21. /*
  22.    create_counter - initialises counter.
  23. */
  24.  
  25. counterptr Globalfunc create_counter (counterptr cnt TN(byteptr name))
  26. {
  27. #if (TSK_DYNAMIC)
  28.    if (cnt == LNULL)
  29.       {
  30.       if ((cnt = tsk_palloc (sizeof (counter))) == LNULL)
  31.          return LNULL;
  32.       cnt->flags = F_TEMP;
  33.       }
  34.    else
  35.       cnt->flags = 0;
  36. #endif
  37.  
  38.    tsk_init_qhead (&cnt->wait_set, TYP_COUNTER);
  39.    tsk_init_qhead (&cnt->wait_clear, TYP_COUNTER);
  40.    cnt->state = 0;
  41.  
  42. #if (TSK_NAMED)
  43.    tsk_add_name (&cnt->name, name, TYP_COUNTER, cnt);
  44. #endif
  45.  
  46.    return cnt;
  47. }
  48.  
  49.  
  50. /*
  51.    delete_counter - kills all processes waiting for counter
  52. */
  53.  
  54. void Globalfunc delete_counter (counterptr cnt)
  55. {
  56.    CRITICAL;
  57.  
  58.    CHECK_EVTPTR (cnt, TYP_COUNTER, "Delete Counter");
  59.  
  60.    C_ENTER;
  61.    tsk_kill_queue (&(cnt->wait_set));
  62.    tsk_kill_queue (&(cnt->wait_clear));
  63.    cnt->state = 0L;
  64.    C_LEAVE;
  65.  
  66. #if (TSK_NAMED)
  67.    tsk_del_name (&cnt->name);
  68. #endif
  69.  
  70. #if (TSK_DYNAMIC)
  71.    if (cnt->flags & F_TEMP)
  72.       tsk_pfree (cnt);
  73. #endif
  74. }
  75.  
  76.  
  77. /*
  78.    clear_counter  - Sets counter to zero. All tasks waiting for
  79.                     Counter zero are made eligible.
  80. */
  81.  
  82. void Globalfunc clear_counter (counterptr cnt)
  83. {
  84.    CRITICAL;
  85.  
  86.    CHECK_EVTPTR (cnt, TYP_COUNTER, "Clear Counter");
  87.  
  88.    C_ENTER;
  89.    cnt->state = 0L;
  90.    tsk_runable_all (&cnt->wait_clear);
  91.    C_LEAVE;
  92. }
  93.  
  94.  
  95. /*
  96.    wait_counter_set  - Wait until counter is != 0. If counter is != 0 on
  97.                        entry, the counter is decremented and the task
  98.                        continues to run. If the counter is decremented to 
  99.                        zero, tasks waiting for zero are made eligible.
  100. */
  101.  
  102. int Globalfunc wait_counter_set (counterptr cnt, dword timeout)
  103. {
  104.    CRITICAL;
  105.  
  106.    CHECK_EVTPTR (cnt, TYP_COUNTER, "Wait Counter Set");
  107.  
  108.    C_ENTER;
  109.    if (cnt->state)
  110.       {
  111.       if (!--cnt->state)
  112.          tsk_runable_all (&cnt->wait_clear);
  113.       C_LEAVE;
  114.       return 0;
  115.       }
  116.  
  117.    GLOBDATA current_task->retptr = LNULL;
  118.    tsk_wait (&cnt->wait_set, timeout);
  119.    return (int)((dword)GLOBDATA current_task->retptr);
  120. }
  121.  
  122. /*
  123.    wait_counter_clear - Wait until counter is == 0. If counter is == 0 on
  124.                        entry, the task continues to run.
  125. */
  126.  
  127. int Globalfunc wait_counter_clear (counterptr cnt, dword timeout)
  128. {
  129.    CRITICAL;
  130.  
  131.    CHECK_EVTPTR (cnt, TYP_COUNTER, "Wait Counter Clear");
  132.  
  133.    C_ENTER;
  134.    if (!cnt->state)
  135.       {
  136.       C_LEAVE;
  137.       return 0;
  138.       }
  139.  
  140.    GLOBDATA current_task->retptr = LNULL;
  141.    tsk_wait (&cnt->wait_clear, timeout);
  142.    return (int)((dword)GLOBDATA current_task->retptr);
  143. }
  144.  
  145.  
  146. /*
  147.    inc_counter - Increment counter. If there are tasks waiting for the
  148.                  set state, the first task in the queue is made eligible.
  149.                  Returns new value of counter state.
  150. */
  151.  
  152. dword Globalfunc inc_counter (counterptr cnt)
  153. {
  154.    dword st;
  155.    CRITICAL;
  156.  
  157.    CHECK_EVTPTR (cnt, TYP_COUNTER, "Inc Counter");
  158.  
  159.    C_ENTER;
  160.    if (cnt->wait_set.first->kind & Q_HEAD)
  161.       {
  162.       st = ++cnt->state;
  163.       C_LEAVE;
  164.       return st;
  165.       }
  166.    tsk_runable ((tcbptr)cnt->wait_set.first);
  167.    C_LEAVE;
  168.    return 0L;
  169. }
  170.  
  171.  
  172. /*
  173.    dec_counter - Decrement counter. If there are tasks waiting for the
  174.                  zero state, all are made eligible.
  175.                  Returns new value of counter state.
  176. */
  177.  
  178. dword Globalfunc dec_counter (counterptr cnt)
  179. {
  180.    dword st;
  181.    CRITICAL;
  182.  
  183.    CHECK_EVTPTR (cnt, TYP_COUNTER, "Dec Counter");
  184.  
  185.    C_ENTER;
  186.    if (cnt->state)
  187.       {
  188.       if ((st = --cnt->state) == 0)
  189.          tsk_runable_all (&cnt->wait_clear);
  190.       C_LEAVE;
  191.       return st;
  192.       }
  193.    C_LEAVE;
  194.    return 0L;
  195. }
  196.  
  197.  
  198. /*
  199.    check_counter - return current counter state.
  200. */
  201.  
  202. dword Globalfunc check_counter (counterptr cnt)
  203. {
  204.    CHECK_EVTPTR (cnt, TYP_COUNTER, "Check Counter");
  205.    return cnt->state;
  206. }
  207.  
  208.  
  209.  
  210. /*
  211.    set_counter  - Sets counter to given value. Depending on the value,
  212.                   tasks waiting for counter zero or counter set are made
  213.                   eligible.
  214. */
  215.  
  216. void Globalfunc set_counter (counterptr cnt, dword val)
  217. {
  218.    CRITICAL;
  219.  
  220.    CHECK_EVTPTR (cnt, TYP_COUNTER, "Set Counter");
  221.  
  222.    C_ENTER;
  223.    while (val && !(cnt->wait_set.first->kind & Q_HEAD))
  224.       {
  225.       tsk_runable ((tcbptr)cnt->wait_set.first);
  226.       val--;
  227.       }
  228.    if (!val)
  229.       tsk_runable_all (&cnt->wait_clear);
  230.    cnt->state = val;
  231.    C_LEAVE;
  232. }
  233.  
  234.