TABLE OF CONTENTS


/Pipe [ Modules ]

[ Top ] [ Modules ]

DESCRIPTION

A Pipe is an object dedicated to Task communication. A Task can write and read an undefined number of bytes into the Pipe. If the Pipe buffer is full when writing or empty when reading, the accessing Task either gets blocked or gets an error.

SEE ALSO

    /Messagequeue, /Mutex, /Semaphore, /Signal, /Syncpipe

Pipe/Os_pipe_header [ Object Headers ]

[ Top ] [ Pipe ] [ Object Headers ]

DESCRIPTION

Header structure of the Pipe object

DECLARATION

Const Os_pipe_hdr_size_ptr = 0                              ' data buffer size in bytes   '
Const Os_pipe_hdr_count_ptr = 2                             ' amount of data currently in the buffer   '
Const Os_pipe_hdr_writeindex_ptr = 4                        ' circular write index   '
Const Os_pipe_hdr_readindex_ptr = 6                         ' circular read index   '
Const Os_pipe_hdr_senderqueue_ptr = 8                       ' queue of tasks waiting to send   '
Const Os_pipe_hdr_receiverqueue_ptr = Os_pipe_hdr_senderqueue_ptr + Os_taskqueue_hdr_size       ' queue of tasks waiting to receive   '
Const Os_pipe_hdr_size = Os_pipe_hdr_receiverqueue_ptr + Os_pipe_hdr_senderqueue_ptr

Pipe/Os_pipe_create [ Functions ]

[ Top ] [ Pipe ] [ Functions ]

DESCRIPTION

Creates a new Pipe object.

DECLARATION

Function Os_pipe_create(byval Size As Word) As Word

SEE ALSO

    Pipe/Os_pipe_kill

SOURCE

   Local Pipe As Word

   Size = Size + Os_pipe_hdr_size
   Pipe = Malloc(size)
   If Pipe = 0 Then
      Os_pipe_create = 0
      Exit Function
   End If
   Os_mem_clear Pipe , Size
   Size = Size - Os_pipe_hdr_size

   Setword Pipe , Os_pipe_hdr_size_ptr , Size
   Os_pipe_create = Pipe
End Function

Pipe/Os_pipe_kill [ Functions ]

[ Top ] [ Pipe ] [ Functions ]

DESCRIPTION

Kills a Pipe object

DECLARATION

Sub Os_pipe_kill(byref Pipe As Word)

SEE ALSO

    Pipe/Os_pipe_create

SOURCE

   Free Pipe
End Sub

Pipe/Os_pipe_receive [ Functions ]

[ Top ] [ Pipe ] [ Functions ]

DESCRIPTION

Receives data from the Pipe. The desired byte count of the data is copied supplied memory address. If the Pipe is empty, the Task either gets blocked or an error.

DECLARATION

Function Os_pipe_receive(byref Pipe As Word , Byref Pointer As Word , Byval Length As Word , Byval Queuemode As Word) As Byte

SEE ALSO

    Pipe/Os_pipe_send

SOURCE

   Local Pipesize As Word
   Local Pipecount As Word
   Local Readindex As Word
   Local Copydata As Byte

   Os_enter_critical
   Pipesize = Getword(Pipe , Os_pipe_hdr_size_ptr)
   Pipecount = Getword(Pipe , Os_pipe_hdr_count_ptr)
   If Pipecount < Length Then Length = Pipecount
      ' Pipe empty / not enough data   '
      Select Case Queuemode
      Case Os_queuemode_noblock:
         ' return error   '
         Os_exit_critical
         Os_pipe_receive = False
         Exit Function
      Case Os_queuemode_block:
         ' suspend and wait to send   '
         Os_task_suspendmode Os_task_active , Os_task_suspend_nowakeup , 0
      Case Else
         ' suspend and wait to send or timeout   '
         Os_task_suspendmode Os_task_active , Os_task_suspend_timersingleshot , Queuemode
      End Select

      ' insert into taskqueue and suspend   '
      Pipe = Pipe + Os_message_hdr_receiverqueue_ptr
      Os_sched_taskqueue_insert Pipe , Os_task_active
      Pipe = Pipe - Os_message_hdr_receiverqueue_ptr
      Os_exit_critical
      Os_task_suspend Os_task_active
      Os_enter_critical

      Pipecount = Getword(Pipe , Os_pipe_hdr_count_ptr)
      If Pipecount < Length Then
         ' Messagequeue still empty (timeout)   '
         Os_exit_critical
         Os_pipe_receive = False
         Exit Function
      End If
   End If

   ' update indexes   '
   Pipecount = Pipecount - Length
   Setword Pipe , Os_pipe_hdr_count_ptr , Pipecount
   Readindex = Getword(Pipe , Os_pipe_hdr_readindex_ptr)
   Pipecount = Readindex
   Readindex = Readindex + Length
   If Readindex > Pipesize Then Readindex = Readindex - Pipesize
   Setword Pipe , Os_pipe_hdr_readindex_ptr , Readindex
   Os_exit_critical

   ' copy data to Task   '
   Readindex = Queuemode + Pipe                             ' write pointer   '
   Readindex = Readindex + Os_pipe_hdr_size
   Pipecount = Pipe + Os_pipe_hdr_size                      ' end of buffer   '
   Pipecount = Pipecount + Pipesize
   For Queuemode = 1 To Length
      Copydata = Inp(readindex)
      Out Pointer , Copydata
      Incr Pointer
      Incr Readindex
      If Pipecount < Readindex Then Readindex = Pipecount - Pipesize       ' circular buffer   '
   Next

   ' Task waiting for data?   '
   Writeindex = Pipe + Os_pipe_hdr_senderqueue_ptr
   Pipecount = Os_sched_taskqueue_remove(writeindex)
   If Pipecount <> 0 Then
      Os_event_task = Pipecount
      Os_task_event
   End If

   Os_pipe_send = True
End Function

Pipe/Os_pipe_send [ Functions ]

[ Top ] [ Pipe ] [ Functions ]

DESCRIPTION

Sends data into a Pipe. The data is referenced by a pointer and the data length in bytes. If the Pipe is full, the Task either gets blocked or an error.

DECLARATION

Function Os_pipe_send(byref Pipe As Word , Byref Pointer As Word , Byval Length As Word , Byval Queuemode As Word) As Byte

SEE ALSO

    Pipe/Os_pipe_receive

SOURCE

   Local Pipesize As Word
   Local Pipecount As Word
   Local Writeindex As Word
   Local Copydata As Byte

   Os_enter_critical
   Pipesize = Getword(Pipe , Os_pipe_hdr_size_ptr)
   Pipecount = Getword(Pipe , Os_pipe_hdr_count_ptr)
   Pipecount = Pipecount + Length
   If Pipesize < Pipecount Then
      ' Pipe full / data does not fit   '
      Select Case Queuemode
      Case Os_queuemode_noblock:
         ' return error   '
         Os_exit_critical
         Os_pipe_send = False
         Exit Function
      Case Os_queuemode_block:
         ' suspend and wait to send   '
         Os_task_suspendmode Os_task_active , Os_task_suspend_nowakeup , 0
      Case Else
         ' suspend and wait to send or timeout   '
         Os_task_suspendmode Os_task_active , Os_task_suspend_timersingleshot , Queuemode
      End Select

      ' insert into taskqueue and suspend   '
      Pipe = Pipe + Os_message_hdr_senderqueue_ptr
      Os_sched_taskqueue_insert Pipe , Os_task_active
      Pipe = Pipe - Os_message_hdr_senderqueue_ptr
      Os_exit_critical
      Os_task_suspend Os_task_active
      Os_enter_critical

      Pipecount = Getword(Pipe , Os_pipe_hdr_count_ptr)
      Pipecount = Pipecount + Length
      If Pipesize < Pipecount Then
         ' Messagequeue still full (timeout)   '
         Os_exit_critical
         Os_pipe_send = False
         Exit Function
      End If
   End If

   ' update indexes   '
   Setword Pipe , Os_pipe_hdr_count_ptr , Pipecount
   Writeindex = Getword(Pipe , Os_pipe_hdr_writeindex_ptr)
   Queuemode = Writeindex
   Writeindex = Writeindex + Length
   If Pipesize < Writeindex Then Writeindex = Writeindex - Pipesize
   Setword Pipe , Os_pipe_hdr_writeindex_ptr , Writeindex
   Os_exit_critical

   ' copy data to Pipe buffer   '
   Writeindex = Queuemode + Pipe                            ' write pointer   '
   Writeindex = Writeindex + Os_pipe_hdr_size
   Pipecount = Pipe + Os_pipe_hdr_size                      ' end of buffer   '
   Pipecount = Pipecount + Pipesize
   For Queuemode = 1 To Length
      Copydata = Inp(pointer)
      Out Writeindex , Copydata
      Incr Pointer
      Incr Writeindex
      If Pipecount < Writeindex Then Writeindex = Pipecount - Pipesize       ' circular buffer   '
   Next

   ' Task waiting for data?   '
   Writeindex = Pipe + Os_pipe_hdr_receiverqueue_ptr
   Pipecount = Os_sched_taskqueue_remove(writeindex)
   If Pipecount <> 0 Then
      Os_event_task = Pipecount
      Os_task_event
   End If

   Os_pipe_send = True
End Function