NAME
ringbuf -- implement the ring buffer
SYNOPSIS
ringbuf [-v] _commands_
DESCRIPTION
Creates a ring buffer of characters of default size 16 characters and applies the
enqueue/dequeue commands from string _commands_. The _commands_ string is understood
as follows:
For each character c in _commands_, in order, either:
* if the character is a "-", dequeue a character from the ring buffer and
print it; print "empty" if there is no character to dequeue;
* if the character is a "+", call each of the ioctl's and print the return
values;
* else enqueue the character c on the ring buffer and print c; print "full"
if c cannot be enqueued because the ring buffer is full. unless the
The following options are available:
-v verbose output
OUTPUT
The output for enqueue must be the line "enq: _X_", where _X_ is the enqueued
character or the word "full". The output for dequeue must be "deq: _X_", where _X_ is
the dequeued character or the word "empty". The output for the ioctl query must be
"ioc: _X_" where _X_ is the white-space separated result of each of the three ioctl calls,
RB_Q_SIZE, RB_IS_EMPTY, RB_IS_FULL and RB_Q_COUNT.
If the input is unacceptable, the program will exit with usage message:
usage: ringbuf [-v] _commands_
HISTORY
Reworked in csc421.171 to unify application and kernel variants.
Introduced in csc421.161 to prepare for the in-kernel ring buffer
Introduced in csc421.151 as a C warm-up.
BUGS
------------------------------------------------------------
NAME
rb_enqueue, rb_dequeue, rb_ioctl - ringbuffer subroutines
LIBRARY
Implemented in ringbuf-sub.c.
SYNOPSIS
#include "ringbuf.h"
#define RB_Q_SIZE 0
#define RB_IS_EMPTY 1
#define RB_IS_FULL 2
#define RB_Q_COUNT 3
int rb_ioctl(int op) ;
int rb_enqueue(int ele) ;
int rb_dequeue(void) ;
DESCRIPTION
rb_enqueue takes a character argument ele and places it in the ringbuffer returning
ele if successful; if the queue is full or other error return -1.
rb_dequeue returns the dequeued element from the queue; if the queue is empty or
other error return -1.
rb_ioctl performs the ioctl p and returns the result:
RB_Q_SIZE: returns the size of the queue (always 16).
RB_IS_EMPTY: return 1 if the queue is empty, 0 otherwise
RB_IS_FULL: return 1 if the queue is full, 0 otherwise
RB_Q_COUNT: return the number of items in the queue
Note that ele is passed as an integer, but it is undefined if it is not in the
range of an unsigned character, 0 through 255.
Note that return character is an integer, but should either be the
integer -1 or in the range of an unsigned character, 0 through 255.
You have been provided with the structure "struct RingBuf". This fields in this structure will be used to implement a ring buffer according the algorithm given here. C does not, in general, assure that variables are initialized. However, static variables can have initializers, and are otherwise zero'ed, as they are allocated from zero'ed pages.
head is the index in ringbuf to where the next character
should be enqueued. If the ring buffer is named rb, then this is
rb.ringbuf[rb.head].If the buffer is not full, place the character to enqueue at index
head then increment
head, taking it mod RINGBUF_SIZE to wrap around to the beginning of the buffer.
If the buffer is full, return -1, and do not enqueue the character, do not increment
head.
tail is the index in ringbuf from where the next character
should be dequeued. If the ring buffer pointer is named rb, then this is
rb.ringbuf[rb.tail].If the buffer is not empty, return the character at index
tail, then increment
tail, taking it mod RINGBUF_SIZE to wrap around to the beginning of the buffer.
If the buffer is empty, return -1, and do not increment
tail.
head != tail, the ring buffer is neither empty nor full. head gives
the "empty space" ready to take a character; tail gives the "full space" ready
to provide a character.
head == tail, the ring buffer might be empty or might be full. You
need to keep track of which of the two situations is the case by maintaining is_full properly.
is_full
is false (zero). In this case head == tail because there is nothing
in the ring buffer.
is_full true (to one) when an enqueue operation causes head
to equal tail.
is_full false (to zero) whenever a character is dequeued — the buffer
cannot be full if something has just been removed.

author: burton rosenberg
created: 08 sep 2015
update: 01 sep 2017