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

  1. /*
  2.     --- Version 2.0 89-12-14 13:33 ---
  3.  
  4.    TSKWPIP.C - CTask - Word Pipe handling routines.
  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.    tsk_getwpipe - get a word from a pipe. For internal use only.
  20.                   Critical section assumed entered.
  21. */
  22.  
  23. local word near tsk_getwpipe (wpipeptr pip)
  24. {
  25.    word c;
  26.  
  27.    c = pip->wcontents [pip->outptr++];
  28.    if (pip->outptr >= pip->bufsize)
  29.       pip->outptr = 0;
  30.    pip->filled--;
  31.    return c;
  32. }
  33.  
  34.  
  35. /*
  36.    tsk_putwpipe - put a word to a pipe. For internal use only.
  37.                   Critical section assumed entered.
  38. */
  39.  
  40. local void near tsk_putwpipe (wpipeptr pip, word c)
  41. {
  42.    pip->wcontents [pip->inptr++] = c;
  43.    if (pip->inptr >= pip->bufsize)
  44.       pip->inptr = 0;
  45.    pip->filled++;
  46. }
  47.  
  48.  
  49. /* -------------------------------------------------------------------- */
  50.  
  51.  
  52. /*
  53.    create_wpipe - initialises wpipe.
  54. */
  55.  
  56. wpipeptr far create_wpipe (wpipeptr pip, farptr buf, word bufsize
  57. #if (TSK_NAMEPAR)
  58.                            ,byteptr name
  59. #endif
  60.                            )
  61. {
  62. #if (TSK_DYNAMIC)
  63.    if (pip == NULL)
  64.       {
  65.       if ((pip = tsk_alloc (sizeof (wpipe))) == NULL)
  66.          return NULL;
  67.       pip->flags = F_TEMP;
  68.       }
  69.    else
  70.       pip->flags = 0;
  71.    if (buf == NULL)
  72.       {
  73.       if ((buf = tsk_alloc (bufsize)) == NULL)
  74.          {
  75.          if (pip->flags & F_TEMP)
  76.             tsk_free (pip);
  77.          return NULL;
  78.          }
  79.       pip->flags |= F_STTEMP;
  80.       }
  81. #endif
  82.  
  83.    tsk_init_qhead (&pip->wait_read);
  84.    tsk_init_qhead (&pip->wait_write);
  85.    tsk_init_qhead (&pip->wait_clear);
  86.    pip->outptr = pip->inptr = pip->filled = 0;
  87.    pip->bufsize = bufsize >> 1;
  88.    pip->wcontents = (wordptr)buf;
  89.  
  90. #if (TSK_NAMED)
  91.    tsk_add_name (&pip->name, name, TYP_WPIPE, pip);
  92. #endif
  93.  
  94.    return pip;
  95. }
  96.  
  97.  
  98. /*
  99.    delete_wpipe - kills all processes waiting for reading from or writing
  100.                   to the wpipe.
  101. */
  102.  
  103. void far delete_wpipe (wpipeptr pip)
  104. {
  105.    CRITICAL;
  106.  
  107.    C_ENTER;
  108.    tsk_kill_queue (&(pip->wait_read));
  109.    tsk_kill_queue (&(pip->wait_write));
  110.    tsk_kill_queue (&(pip->wait_clear));
  111.    pip->outptr = pip->inptr = pip->filled = 0;
  112.    C_LEAVE;
  113.  
  114. #if (TSK_NAMED)
  115.    tsk_del_name (&pip->name);
  116. #endif
  117.  
  118. #if (TSK_DYNAMIC)
  119.    if (pip->flags & F_STTEMP)
  120.       tsk_free (pip->wcontents);
  121.    if (pip->flags & F_TEMP)
  122.       tsk_free (pip);
  123. #endif
  124. }
  125.  
  126.  
  127. /*
  128.    read_wpipe - Wait until a word is written to the wpipe. If there 
  129.                 is a word in the wpipe on entry, it is assigned to 
  130.                 the caller, and the task continues to run. If there are
  131.                 tasks waiting to write, the first task is made eligible,
  132.                 and the word is inserted into the wpipe.
  133. */
  134.  
  135. word far read_wpipe (wpipeptr pip, dword timeout)
  136. {
  137.    tcbptr curr;
  138.    word res;
  139.    CRITICAL;
  140.  
  141.    C_ENTER;
  142.  
  143.    if (pip->filled)
  144.       {
  145.       res = tsk_getwpipe (pip);
  146.  
  147.       if ((curr = (tcbptr)pip->wait_write.first)->cqueue.kind)
  148.          {
  149.          tsk_putwpipe (pip, curr->retsize);
  150.          tsk_runable (curr);
  151.          curr->retptr = NULL;
  152.          }
  153.       else if (!pip->filled)
  154.          tsk_runable_all (&pip->wait_clear);
  155.  
  156.       C_LEAVE;
  157.       return res;
  158.       }
  159.  
  160.    tsk_wait (&pip->wait_read, timeout);
  161.    return (word)GLOBDATA current_task->retptr;
  162. }
  163.  
  164.  
  165. /*
  166.    c_read_wpipe - If there is a word in the wpipe on entry,
  167.                   read_wpipe is called, otherwise an error status is returned.
  168. */
  169.  
  170. word far c_read_wpipe (wpipeptr pip)
  171. {
  172.    CRITICAL, res;
  173.  
  174.    C_ENTER;
  175.    res = (pip->filled) ? read_wpipe (pip, 0L) : (word)-1;
  176.    C_LEAVE;
  177.    return res;
  178. }
  179.  
  180.  
  181.  
  182. /*
  183.    write_wpipe - Wait until space for the word to be written to the 
  184.                  wpipe is available. If there is enough space in the wpipe 
  185.                  on entry, the word is inserted into the wpipe, and
  186.                  the task continues to run. If there are tasks waiting 
  187.                  to read, the first task is made eligible, and the word
  188.                  is passed to the waiting task.
  189. */
  190.  
  191. int far write_wpipe (wpipeptr pip, word ch, dword timeout)
  192. {
  193.    tcbptr curr;
  194.    CRITICAL;
  195.  
  196.    C_ENTER;
  197.  
  198.    if (pip->filled < pip->bufsize)
  199.       {
  200.       if ((curr = (tcbptr)pip->wait_read.first)->cqueue.kind)
  201.          {
  202.          tsk_runable (curr);
  203.          curr->retptr = (farptr)ch;
  204.          C_LEAVE;
  205.          return 0;
  206.          }
  207.  
  208.       tsk_putwpipe (pip, ch);
  209.       C_LEAVE;
  210.       return 0;
  211.       }
  212.  
  213.    GLOBDATA current_task->retsize = ch;
  214.    tsk_wait (&pip->wait_write, timeout);
  215.    return (int)GLOBDATA current_task->retptr;
  216. }
  217.  
  218.  
  219. /*
  220.    c_write_wpipe - If there is space for the word in the wpipe on entry,
  221.                    write_wpipe is called, otherwise an error status is returned.
  222. */
  223.  
  224. int far c_write_wpipe (wpipeptr pip, word ch)
  225. {
  226.    int res;
  227.    CRITICAL;
  228.  
  229.    C_ENTER;
  230.    res = (pip->filled < pip->bufsize) ? write_wpipe (pip, ch, 0L) : -1;
  231.    C_LEAVE;
  232.    return res;
  233. }
  234.  
  235.  
  236. /*
  237.    wait_wpipe_empty - Wait until the pipe is empty. If the pipe is
  238.                       empty on entry, the task continues to run.
  239. */
  240.  
  241. int far wait_wpipe_empty (wpipeptr pip, dword timeout)
  242. {
  243.    CRITICAL;
  244.  
  245.    C_ENTER;
  246.    if (!pip->filled)
  247.       {
  248.       C_LEAVE;
  249.       return 0;
  250.       }
  251.  
  252.    GLOBDATA current_task->retptr = NULL;
  253.    tsk_wait (&pip->wait_clear, timeout);
  254.    return (int)GLOBDATA current_task->retptr;
  255. }
  256.  
  257.  
  258. /*
  259.    check_wpipe - returns -1 if there are no words in the wpipe, else
  260.                  the first available word.
  261. */
  262.  
  263. word far check_wpipe (wpipeptr pip)
  264. {
  265.    return (pip->filled) ? pip->wcontents [pip->outptr] : (word)-1;
  266. }
  267.  
  268.  
  269. /*
  270.    wpipe_free - returns the number of free words in the pipe.
  271. */
  272.  
  273. word far wpipe_free (wpipeptr pip)
  274. {
  275.    return pip->bufsize - pip->filled;
  276. }
  277.  
  278. /*
  279.    flush_wpipe - Empty the pipe buffer, activate tasks waiting for 
  280.                  pipe clear.
  281. */
  282.  
  283. void far flush_wpipe (wpipeptr pip)
  284. {
  285.    CRITICAL;
  286.  
  287.    C_ENTER;
  288.    pip->inptr = pip->outptr = pip->filled = 0;
  289.  
  290.    tsk_runable_all (&pip->wait_clear);
  291.    C_LEAVE;
  292. }
  293.  
  294.  
  295.