home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / cpptask.arj / TSKPIP.CPP < prev    next >
C/C++ Source or Header  |  1991-08-21  |  6KB  |  275 lines

  1. /*
  2.    CPPTask - A Multitasking Kernel For C++
  3.  
  4.    Version 1.0 08-12-91
  5.  
  6.    Ported by Rich Smith from:
  7.  
  8.    Public Domain Software written by
  9.       Thomas Wagner
  10.       Patschkauer Weg 31
  11.       D-1000 Berlin 33
  12.       West Germany
  13.  
  14.    TSKPIP.CPP - Pipe handling routines.
  15.  
  16.    Subroutines:
  17.        pipe::pipe
  18.        pipe::~pipe
  19.        pipe::read_pipe
  20.        pipe::c_read_pipe
  21.        pipe::write_pipe
  22.        pipe::c_write_pipe
  23.        pipe::wait_pipe_empty
  24.        pipe::check_pipe
  25.        pipe::pipe_free
  26.        pipe::flush_pipe
  27.        pipe::get_bufsize
  28.        pipe::get_filled
  29.        pipe::get_flags
  30.  
  31. */
  32.  
  33. #include <stdio.h>
  34.  
  35. #include "task.hpp"
  36. #include "tsklocal.hpp"
  37.  
  38. /*
  39.    tsk_getcpipe - get a byte from a pipe. For internal use only.
  40.                   Critical section assumed entered.
  41. */
  42.  
  43. byte pipe::tsk_getcpipe (void)
  44. {
  45.    byte c;
  46.  
  47.    c = contents [outptr++];
  48.    if (outptr >= bufsize)
  49.       outptr = 0;
  50.    filled--;
  51.    return c;
  52. }
  53.  
  54.  
  55. /*
  56.    tsk_putcpipe - put a byte to a pipe. For internal use only.
  57.                   Critical section assumed entered.
  58. */
  59.  
  60. void pipe::tsk_putcpipe (byte c)
  61. {
  62.    contents [inptr++] = c;
  63.    if (inptr >= bufsize)
  64.       inptr = 0;
  65.    filled++;
  66. }
  67.  
  68.  
  69. /* -------------------------------------------------------------------- */
  70.  
  71.  
  72. /*
  73.    create_pipe - initialises pipe.
  74. */
  75.  
  76. pipe::pipe (farptr buf, word buffersize)
  77. {
  78.    flags = 0;
  79.    wait_read = wait_write = wait_clear = NULL;
  80.    outptr = inptr = filled = 0;
  81.    bufsize = buffersize;
  82.    contents = (byteptr)buf;
  83. }
  84.  
  85.  
  86. /*
  87.    ~pipe - kills all processes waiting for reading from or writing
  88.                  to the pipe.
  89. */
  90.  
  91. pipe::~pipe ()
  92. {
  93.    CRITICAL;
  94.  
  95.    C_ENTER;
  96.    tsk_kill_queue (&wait_read);
  97.    tsk_kill_queue (&wait_write);
  98.    tsk_kill_queue (&wait_clear);
  99.    outptr = inptr = filled = 0;
  100.    C_LEAVE;
  101.  
  102. }
  103.  
  104.  
  105. /*
  106.    read_pipe - Wait until a character is written to the pipe. If there 
  107.                is a character in the pipe on entry, it is assigned to 
  108.                the caller, and the task continues to run. If there are
  109.                tasks waiting to write, the first task is made eligible,
  110.                and the character is inserted into the pipe.
  111. */
  112.  
  113. int far pipe::read_pipe (dword timeout)
  114. {
  115.    tcbptr curr;
  116.    int res;
  117.    CRITICAL;
  118.  
  119.    C_ENTER;
  120.  
  121.    if (filled)
  122.       {
  123.       res = tsk_getcpipe ();
  124.  
  125.       if ((curr = wait_write) != NULL)
  126.          {
  127.          tsk_putcpipe ((byte)curr->get_retsize());
  128.          wait_write = curr->tsk_runable ();
  129.          curr->set_retptr(NULL);
  130.          }
  131.       else if (!filled)
  132.          while (wait_clear != NULL)
  133.             wait_clear = wait_clear->tsk_runable ();
  134.  
  135.       C_LEAVE;
  136.       return res;
  137.       }
  138.  
  139.    tsk_wait (&wait_read, timeout);
  140.    return (int)tsk_current->get_retptr();
  141. }
  142.  
  143.  
  144. /*
  145.    c_read_pipe - If there is a character in the pipe on entry,
  146.                  read_pipe is called, otherwise en error status is returned.
  147. */
  148.  
  149. int far pipe::c_read_pipe (void)
  150. {
  151.    CRITICAL, res;
  152.  
  153.    C_ENTER;
  154.    res = (filled) ? read_pipe (0L) : -1;
  155.    C_LEAVE;
  156.    return res;
  157. }
  158.  
  159.  
  160.  
  161. /*
  162.    write_pipe - Wait until space for the character to be written to the 
  163.                 pipe is available. If there is enough space in the pipe 
  164.                 on entry, the character is inserted into the pipe, and
  165.                 the task continues to run. If there are tasks waiting 
  166.                 to read, the first task is made eligible, and the character
  167.                 is passed to the waiting task.
  168. */
  169.  
  170. int far pipe::write_pipe (byte ch, dword timeout)
  171. {
  172.    tcbptr curr;
  173.    CRITICAL;
  174.  
  175.    C_ENTER;
  176.  
  177.    if (filled < bufsize)
  178.       {
  179.       if ((curr = wait_read) != NULL)
  180.          {
  181.          wait_read = curr->tsk_runable ();
  182.          curr->set_retptr((farptr)ch);
  183.          C_LEAVE;
  184.          return 0;
  185.          }
  186.  
  187.       tsk_putcpipe (ch);
  188.       C_LEAVE;
  189.       return 0;
  190.       }
  191.  
  192.    tsk_current->set_retsize(ch);
  193.    tsk_wait (&wait_write, timeout);
  194.    return (int)tsk_current->get_retptr();
  195. }
  196.  
  197.  
  198. /*
  199.    c_write_pipe - If there is space for the character in the pipe on entry,
  200.                   write_pipe is called, otherwise en error status is returned.
  201. */
  202.  
  203. int far pipe::c_write_pipe (byte ch)
  204. {
  205.    int res;
  206.    CRITICAL;
  207.  
  208.    C_ENTER;
  209.    res = (filled < bufsize) ? write_pipe (ch, 0L) : -1;
  210.    C_LEAVE;
  211.    return res;
  212. }
  213.  
  214.  
  215. /*
  216.    wait_pipe_empty - Wait until the pipe is empty. If the pipe is
  217.                      empty on entry, the task continues to run.
  218. */
  219.  
  220. int far pipe::wait_pipe_empty (dword timeout)
  221. {
  222.    CRITICAL;
  223.  
  224.    C_ENTER;
  225.    if (!filled)
  226.       {
  227.       C_LEAVE;
  228.       return 0;
  229.       }
  230.  
  231.    tsk_current->set_retptr(NULL);
  232.    tsk_wait (&wait_clear, timeout);
  233.    return (int)tsk_current->get_retptr();
  234. }
  235.  
  236.  
  237. /*
  238.    check_pipe - returns -1 if there are no characters in the pipe, else
  239.                 the first available character.
  240. */
  241.  
  242. int far pipe::check_pipe (void)
  243. {
  244.    return (filled) ? (int)contents [outptr] : -1;
  245. }
  246.  
  247.  
  248. /*
  249.    pipe_free - returns the number of free characters in the pipe.
  250. */
  251.  
  252. word far pipe::pipe_free (void)
  253. {
  254.    return bufsize - filled;
  255. }
  256.  
  257. /*
  258.    flush_pipe - Empty the pipe buffer, activate tasks waiting for 
  259.                 pipe clear.
  260. */
  261.  
  262. void far pipe::flush_pipe (void)
  263. {
  264.    CRITICAL;
  265.  
  266.    C_ENTER;
  267.    inptr = outptr = filled = 0;
  268.  
  269.    while (wait_clear != NULL)
  270.       wait_clear = wait_clear->tsk_runable ();
  271.    C_LEAVE;
  272. }
  273.  
  274.  
  275.