home *** CD-ROM | disk | FTP | other *** search
- /*
- CPPTask - A Multitasking Kernel For C++
-
- Version 1.0 08-12-91
-
- Ported by Rich Smith from:
-
- Public Domain Software written by
- Thomas Wagner
- Patschkauer Weg 31
- D-1000 Berlin 33
- West Germany
-
- TSKPIP.CPP - Pipe handling routines.
-
- Subroutines:
- pipe::pipe
- pipe::~pipe
- pipe::read_pipe
- pipe::c_read_pipe
- pipe::write_pipe
- pipe::c_write_pipe
- pipe::wait_pipe_empty
- pipe::check_pipe
- pipe::pipe_free
- pipe::flush_pipe
- pipe::get_bufsize
- pipe::get_filled
- pipe::get_flags
-
- */
-
- #include <stdio.h>
-
- #include "task.hpp"
- #include "tsklocal.hpp"
-
- /*
- tsk_getcpipe - get a byte from a pipe. For internal use only.
- Critical section assumed entered.
- */
-
- byte pipe::tsk_getcpipe (void)
- {
- byte c;
-
- c = contents [outptr++];
- if (outptr >= bufsize)
- outptr = 0;
- filled--;
- return c;
- }
-
-
- /*
- tsk_putcpipe - put a byte to a pipe. For internal use only.
- Critical section assumed entered.
- */
-
- void pipe::tsk_putcpipe (byte c)
- {
- contents [inptr++] = c;
- if (inptr >= bufsize)
- inptr = 0;
- filled++;
- }
-
-
- /* -------------------------------------------------------------------- */
-
-
- /*
- create_pipe - initialises pipe.
- */
-
- pipe::pipe (farptr buf, word buffersize)
- {
- flags = 0;
- wait_read = wait_write = wait_clear = NULL;
- outptr = inptr = filled = 0;
- bufsize = buffersize;
- contents = (byteptr)buf;
- }
-
-
- /*
- ~pipe - kills all processes waiting for reading from or writing
- to the pipe.
- */
-
- pipe::~pipe ()
- {
- CRITICAL;
-
- C_ENTER;
- tsk_kill_queue (&wait_read);
- tsk_kill_queue (&wait_write);
- tsk_kill_queue (&wait_clear);
- outptr = inptr = filled = 0;
- C_LEAVE;
-
- }
-
-
- /*
- read_pipe - Wait until a character is written to the pipe. If there
- is a character in the pipe on entry, it is assigned to
- the caller, and the task continues to run. If there are
- tasks waiting to write, the first task is made eligible,
- and the character is inserted into the pipe.
- */
-
- int far pipe::read_pipe (dword timeout)
- {
- tcbptr curr;
- int res;
- CRITICAL;
-
- C_ENTER;
-
- if (filled)
- {
- res = tsk_getcpipe ();
-
- if ((curr = wait_write) != NULL)
- {
- tsk_putcpipe ((byte)curr->get_retsize());
- wait_write = curr->tsk_runable ();
- curr->set_retptr(NULL);
- }
- else if (!filled)
- while (wait_clear != NULL)
- wait_clear = wait_clear->tsk_runable ();
-
- C_LEAVE;
- return res;
- }
-
- tsk_wait (&wait_read, timeout);
- return (int)tsk_current->get_retptr();
- }
-
-
- /*
- c_read_pipe - If there is a character in the pipe on entry,
- read_pipe is called, otherwise en error status is returned.
- */
-
- int far pipe::c_read_pipe (void)
- {
- CRITICAL, res;
-
- C_ENTER;
- res = (filled) ? read_pipe (0L) : -1;
- C_LEAVE;
- return res;
- }
-
-
-
- /*
- write_pipe - Wait until space for the character to be written to the
- pipe is available. If there is enough space in the pipe
- on entry, the character is inserted into the pipe, and
- the task continues to run. If there are tasks waiting
- to read, the first task is made eligible, and the character
- is passed to the waiting task.
- */
-
- int far pipe::write_pipe (byte ch, dword timeout)
- {
- tcbptr curr;
- CRITICAL;
-
- C_ENTER;
-
- if (filled < bufsize)
- {
- if ((curr = wait_read) != NULL)
- {
- wait_read = curr->tsk_runable ();
- curr->set_retptr((farptr)ch);
- C_LEAVE;
- return 0;
- }
-
- tsk_putcpipe (ch);
- C_LEAVE;
- return 0;
- }
-
- tsk_current->set_retsize(ch);
- tsk_wait (&wait_write, timeout);
- return (int)tsk_current->get_retptr();
- }
-
-
- /*
- c_write_pipe - If there is space for the character in the pipe on entry,
- write_pipe is called, otherwise en error status is returned.
- */
-
- int far pipe::c_write_pipe (byte ch)
- {
- int res;
- CRITICAL;
-
- C_ENTER;
- res = (filled < bufsize) ? write_pipe (ch, 0L) : -1;
- C_LEAVE;
- return res;
- }
-
-
- /*
- wait_pipe_empty - Wait until the pipe is empty. If the pipe is
- empty on entry, the task continues to run.
- */
-
- int far pipe::wait_pipe_empty (dword timeout)
- {
- CRITICAL;
-
- C_ENTER;
- if (!filled)
- {
- C_LEAVE;
- return 0;
- }
-
- tsk_current->set_retptr(NULL);
- tsk_wait (&wait_clear, timeout);
- return (int)tsk_current->get_retptr();
- }
-
-
- /*
- check_pipe - returns -1 if there are no characters in the pipe, else
- the first available character.
- */
-
- int far pipe::check_pipe (void)
- {
- return (filled) ? (int)contents [outptr] : -1;
- }
-
-
- /*
- pipe_free - returns the number of free characters in the pipe.
- */
-
- word far pipe::pipe_free (void)
- {
- return bufsize - filled;
- }
-
- /*
- flush_pipe - Empty the pipe buffer, activate tasks waiting for
- pipe clear.
- */
-
- void far pipe::flush_pipe (void)
- {
- CRITICAL;
-
- C_ENTER;
- inptr = outptr = filled = 0;
-
- while (wait_clear != NULL)
- wait_clear = wait_clear->tsk_runable ();
- C_LEAVE;
- }
-
-
-