The file Common\Cqueues.fth provides circular character
(byte) queues. If the equate TASKING?
is non-zero, the
blocking routines will use PAUSE
. Interrupts are
disabled for the queue empty/full checks.
struct /cqueue \ -- size ; character queue structure in idata, buffer in udata
Circular queue data structure.
int >qhead \ Offset of head, where characters are taken from int >qtail \ Offset of tail, where characters are put int >qchars \ Number of characters in the queue int >qmask \ Mask to apply to pointers ptr >qbuffer \ Base address of character buffer end-struct
: cqueue: \ size -- ; -- cqueue ; size CQUEUE: <name>
An interpreter definition to build a character queue of the
specified size. The queue data structure is built in the current
IDATA
space, and the buffer itself is in the current
UDATA
space. Executing <name>
returns the address
of the queue data structure.
N.B. The size of a queue must be a power of two, e.g. 32, 64 ...
: init-cqueue \ cqueue -- ; initialise queue
Initialise the specified queue created by CQUEUE:
.
: init-hcqueue \ size cqueue -- ; SFP002
Initialise the specified queue created by ALLOCATE
.
When a queue is allocated from the heap by a phrase
of the form /CQUEUE <size> + ALLOCATE
, this word
must be used.
: (>cqueue) \ char cqueue -- ; put character on cqueue
Put char into the queue with no checks.
: (cqueue>) \ cqueue -- char ; get next character from queue
Get the next character from the queue with no checks.
: (cqfull?) \ queue -- flag ; TRUE if queue full
Return true if the queue is full. No interrupt
protection is provided.
: cqfull? \ queue -- flag ; TRUE if queue full
Return true if the queue is full. Interrupt
protection is provided.
: cqchars \ queue -- n
Return the number of characters in the queue.
: cqempty? \ queue -- flag ; TRUE if queue empty
Return true if the queue is empty.
: cqnotempty? \ queue -- flag ; TRUE if queue not empty
Return true if the queue is not empty, i.e. if it contains any
characters.
: cqRoom \ queue -- u
Return the number of free bytes in the queue.
: cqroom? \ +n queue -- flag
Return true if there is enough room in the queue for +n more
characters.
: >cqueue \ char cqueue -- ; spins if full
Put a character into the queue. If the queue is full, the
system waits (blocks) until there is enough space.
: cqueue> \ queue -- char ; spins while queue empty
Remove the next character, waiting if the queue is empty.
When queues are filled and emptied in blocks rather than
character by character, faster operation can be achieved
using these words. You may see additional benefit using the
fast version of CMOVE
.
The extended operations are compiled if the equate
extCQ?
is set non-zero before Cqueues.fth
is compiled.
0 equ extCQ? \ -- flag
If set non-zero here or before Cqueues.fth is compiled,
the extended wordset below will be compiled.
: /tailw \ queue -- len
Number of bytes from the tail to the end.
: /gapw \ queue -- len
Number of bytes from the tail to the head, assuming no wrap.
: +tail \ n queue --
Add n characters to the tail pointer and count.
: $>cq \ caddr len n queue -- caddr' len' queue
Copy n bytes of the the source block into the buffer.
: $>tail \ caddr len queue -- caddr' len' queue
Add block in space between tail and end
: $>gap \ caddr len queue -- caddr' len' queue
Add block in space between tail and head.
: /headr \ queue -- len
Number of bytes from the head to the end.
: /gapr \ queue -- len
Number of bytes from the head to the tail, assuming no wrap.
: -head \ n queue --
Remove n characters from the head pointer and count.
: cq>$ \ caddr len n queue -- caddr' len' queue
Copy n bytes from the queue into the buffer
caddr/len.
: head>$ \ caddr len queue -- caddr' len' queue
Copy queue block in space between head and end
: gap>$ \ caddr len queue -- caddr' len' queue
Add block in space between head and tail.
: cqWrite \ caddr len queue --
Write the given string to the queue.
This word blocks until the operation is complete.
: cqStuff \ caddr len queue -- n
Write as much data from the given string to the queue as
there is room for. Return the number of bytes written.
: cqRead \ caddr len queue --
Read the given string from the queue.
This word blocks until the operation is complete.
: cqExtract \ caddr len queue -- n
Read data from the queue to the buffer. The amount read
is limited by the size of the buffer and the number of
bytes in the queue. The number of bytes read is returned.