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