NAME
queue - list management for the task library
SYNOPSIS
#include <task.h>
enum qmodetype { EMODE, WMODE, ZMODE };
class qhead: public object {
public:
// exported constructor
qhead(qmodetype mode=WMODE, int size=10000);
// exported virtual functions
virtual objtype o_type();
virtual int pending();
virtual void print(int, int=0);
// exported misc functions
qhead* cut();
object* get();
int putback(object*);
int rdcount();
int rdmax();
qmodetype rdmode();
void setmode(qmodetype);
void setmax(int);
void splice(qtail*);
qtail* tail();
};
class qtail: public object {
public:
// exported constructor
qtail(qmodetype mode=WMODE, int size=10000);
// exported virtual functions
virtual objtype o_type();
virtual int pending();
virtual void print(int, int = 0);
// exported misc functions
qtail* cut();
qhead* head();
int put(object*);
int rdmax();
qmodetype rdmode();
int rdspace();
void setmode(qmodetype);
void setmax(int);
void splice(qhead*);
};
DESCRIPTION
The task system provides a general queue mechanism, where a
queue is a first-in first-out list of objects derived from
class object (see task(3C++)). No direct access is provided
to a queue itself, but access is instead via the member
functions of the cooperating classes qhead and qtail. Class
qhead provides access to the head of the queue, primarily
for removing the item at the head of the list. Class qtail
provides access to the tail of the queue, primarily for
adding a new item to the end of the queue.
To create a queue, first create a qhead object, call member
function qhead::tail() to get access to the associated
qtail. Example:
qhead qh; // create a queue
qtail *qtp = qh.tail(); // retrieve the qtail
Alternatively, the qtail object could be created first,
using member function qtail::head() to get access to the
associated qhead. Here is an example using only heap
objects:
qtail *qtp = new qtail; // create a queue
qhead *qhp = qtp->head(); // retrieve the qhead
The constructors for these classes have two optional argu-
ments, the queue mode, and the queue maximum size. The
queue mode does not affect the normal operation of the
queue, but only specifies what happens when an operation is
attempted on a pending queue. This is further described
below. The queue size is the maximum number of items
allowed to be on the queue. This is useful for modeling
real-world queues which have a maximum size. The size
defaults to 10,000 items, but may be reset at any time via
the member function setmax(). No space is preallocated for
the items on a queue.
Once a queue has been created, you may append objects to it
with member function qtail::put(), and retrieve the object
at the head of the queue with member function qhead::get().
Like all classes derived from class object, queues have a
definition of whether they are ready or pending, and the
definitions are different for the head and tail of the
queue. A qtail is pending when it is full; that is, when it
already has its maximum number of objects. A qhead is pend-
ing when it is empty.
Each of qhead and qtail have a mode, set by the mode parame-
ter of the constructor. The mode may be modified at any
time by member function setmode(); the mode need not be the
same for the head and tail of the same queue. The mode must
be one of these:
WMODE
wait mode: Adding to a full qtail or removing from an
empty qhead suspends the requesting task. This mode is
set if neither of the other modes is specied.
ZMODE
zero mode: Adding to a full qtail or removing from an
empty qhead returns a zero result.
EMODE
error mode: Adding to a full qtail or removing from an
empty qhead calls task_error().
Queues may be cut and spliced, allowing the insertion of
filters or other tasks into queue processing. This is
explained in more detail under the cut() and splice() member
functions.
Class qhead
qhead qh(m, s);
Constructs a qhead object and its associated queue.
The queue has mode m and maximum size s. The conse-
quences of the mode and size parameters are discussed
above. Member function tail() returns a pointer to the
qtail object associated with the queue.
objtype ot = qh.o_type();
This virtual function returns the kind of the object.
For a qhead, the object kind is QHEAD.
int ispending = qh.pending();
This virtual function returns non-zero (true) if the
associated queue is empty, and zero (false) otherwise.
qh.print(how);
Prints data about the associated queue on stdout (not
cout). If the first int parameter, how, has the VER-
BOSE bit set, prints information about all the objects
on the queue. The second argument is for internal use
and defaults to zero.
qhead *qhp = qh.cut();
Creates a new qhead attached to the original queue, and
returns a pointer to it. Modifies the original qhead
(qh) to point to a new empty queue. Use qh.tail() to
retrieve the qtail associated with this new queue. qhp
will point to the original qhead, and the original
qtail will still be associated with the original queue.
In other words, we have the following situation:
qhp->get()
Retrieves the first item on the original queue.
qhp->tail()->put(op)
Appends an object to the original queue.
qh.get()
Returns the first item on the new queue, once
something is put there.
qh.tail()->put(op)
Appends an object to the new queue.
This technique may be used to insert a filter into an
existing queue without requiring any change to code
using the original head and tail of that queue. The
filter will use qhp->get() to retrieve objects that
were placed on the queue by putting to the original
qtail. The filter will use the equivalent of
qhp->tail()->put(op) to put objects on the new queue
which will be retrieved by code referencing the origi-
nal qhead. Existing code putting and getting from the
original queue will result in those object passing
through the filter. The queue may be restored by using
qhead::splice(). There are cut and splice functions
associated with qtail, but you must use a pair of func-
tions from the same object, either a qhead or a qtail.
object *op = qh.get();
If the queue associated with qh is not empty, removes
the object at the head of the queue and returns a
pointer to it. If the queue is empty, the behavior
depends on the mode of qh. If the mode is WMODE, the
task calling get() is suspended until a object is put
onto the queue. If the mode is ZMODE, returns a null
pointer immediately. If the mode is EMODE, causes a
run time error, and object::task_error() is called.
int ok = qh.putback(op);
If the queue associated with qt is not full, puts the
object pointed to by op at the head of the queue and
returns the value 1 (true). A queue may be used like a
stack by using only the qhead and the functions put-
back() and get(). If the queue is full, the behavior
depends on the mode of qh. If the mode is WMODE, the
task calling putback() is suspended until the queue
becomes no longer full. If the mode is ZMODE, returns
a zero value immediately. If the mode is EMODE, causes
a run time error, and object::task_error() is called.
int i = qh.rdcount();
Returns the number of objects currently in the associ-
ated queue.
int i = qh.rdmax();
Returns the (current) maximum number of objects allow-
able in the associated queue.
qmodetype qm = qh.rdmode();
Returns the current mode of qh: WMODE, EMODE, or
ZMODE.
qh.setmode(qm);
Sets the mode of qh to qm, which may be one of WMODE,
EMODE, or ZMODE.
qh.setmax(max);
Sets the maximum number of items allowed on the associ-
ated queue to max. It is legal to set the maximum
below the current number of objects on the queue. In
this case, the queue is considered full until enough
objects have been removed to bring the count below the
maximum.
qhp->splice(qtp);
Reverses the previous qhead::cut() operation, where qhp
was the pointer returned by the cut(), and qtp points
to the qtail object associated with qhp. Recall that
these head and tail pointers were associated with dif-
ferent queues. The splice() operation merges the two
queues, and deletes the qhead and qtail objects pointed
to by qhp and qtp. In the merged queue, any objects on
the qtp queue are placed before any objects on the qhp
queue. This restored queue again becomes associated
with the original qhead and qtail objects that were
cut(). If merging the queues causes a full queue to
become not full, or an empty queue to become not empty,
any tasks waiting for that condition will be alerted
(made runnable). See task(3C++).
qtail *qtp = qh.tail();
Returns a pointer to the qtail object associated with
the queue, creating the qtail if it does not already
exist.
Class qtail
qtail qt(m, s);
Constructs a qtail object and its associated queue.
The queue has mode m and maximum size s. The conse-
quences of the mode and size parameters are discussed
above. Member function head() returns a pointer to the
qhead object associated with the queue.
objtype ot = qt.o_type();
This virtual function returns the kind of the object.
For a qtail, the object kind is QTAIL.
int ispending = qt.pending();
This virtual function returns non-zero (true) if the
associated queue is full, and zero (false) otherwise.
qt.print(how);
Prints data about the associated queue on stdout (not
cout). If the first int parameter, how, has the VER-
BOSE bit set, prints information about all the objects
on the queue. The second argument is for internal use
and defaults to zero.
qtail *qtp = qt.cut();
Creates a new qtail attached to the original queue, and
returns a pointer to it. Modifies the original qtail
(qt) to point to a new empty queue. Use qt.head() to
retrieve the qhead associated with this new queue. qtp
will point to the original qtail, and the original
qhead will still be associated with the original queue.
In other words, we have the following situation:
qt.head()->get()
Retrieves the first item on the original queue.
That is, the original qhead still retrieves items
from the original queue.
qtp->put(op)
Appends an object to the original queue.
qt.head()->get()
Returns the first item on the new queue, once
something is put there.
qt.put(op)
Appends an object to the new queue.
This technique may be used to insert a filter into an
existing queue without requiring any change to code
using the original head and tail of that queue. The
filter will use the equivalent of qtp->head()->get() to
retrieve objects that were placed on the new queue by
putting to the original qtail. The filter will use
qtp->put(op) to put objects on the original queue which
will be retrieved by code referencing the original
qhead. Existing code putting and getting from the ori-
ginal queue will result in those object passing through
the filter. The queue may be restored by using
qtail::splice(). There are cut and splice functions
associated with qhead, but you must use a pair of func-
tions from the same object, either a qhead or a qtail.
qhead *qtp = qt.head();
Returns a pointer to the qhead object associated with
the queue, creating the qhead if it does not already
exist.
int ok = qt.put(op);
If the queue associated with qt is not full, appends
the object pointed to by op to the queue and returns
the value 1 (true). If the queue is full, the behavior
depends on the mode of qt. If the mode is WMODE, the
task calling put() is suspended until the queue becomes
no longer full. If the mode is ZMODE, returns a zero
value immediately. If the mode is EMODE, causes a run
time error, and object::task_error() is called.
int i = qt.rdmax();
Returns the (current) maximum number of objects
allowable in the associated queue.
qmodetype qm = qt.rdmode();
Returns the current mode of qt: WMODE, EMODE, or
ZMODE.
int i = qt.rdspace();
Returns the number of objects which may be appended to
the associated queue before it becomes full.
qt.setmode(qm);
Sets the mode of qt to qm, which may be one of WMODE,
EMODE, or ZMODE.
qt.setmax(max);
Sets the maximum number of items allowed on the associ-
ated queue to max. It is legal to set the maximum
below the current number of objects on the queue. In
this case, the queue is considered full until enough
objects have been removed to bring the count below the
maximum.
qtp->splice(qhp);
Reverses the previous qtail::cut() operation, where qtp
was the pointer returned by the cut(), and qhp points
to the qhead object associated with qtp. Recall that
these head and tail pointers were associated with dif-
ferent queues. The splice() operation merges the two
queues, and deletes the qhead and qtail objects pointed
to by qhp and qtp. In the merged queue, any objects on
the qtp queue are placed before any objects on the qhp
queue. This restored queue again becomes associated
with the original qhead and qtail objects that were
cut(). If merging the queues causes a full queue to
become not full, or an empty queue to become not empty,
any tasks waiting for that condition will be alerted
(made runnable). See task(3C++).
DIAGNOSTICS
See task(3C++).
SEE ALSO
TASK.INTRO(3C++), interrupt(3C++), task(3C++), tasksim(3C++)
C++ Library Reference Manual,
Chapter 2, "Coroutine Library."
|
Закладки на сайте Проследить за страницей |
Created 1996-2025 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |