tskpip.cpp

来自「这是一个关于C++编程开发的算法!」· C++ 代码 · 共 275 行

CPP
275
字号
/*
   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;
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?