|
A CSIM buffer is a resource
which can store (hold) a number of tokens.
The primary operations for a buffer are
put,
which places a number of tokens into the
buffer, and get,
which removes a number of tokens from
the buffer. A buffer has a maximum capacity
for holding tokens. A get
operation stalls if there are too few
tokens in the buffer, and a put
operation stalls if there is not enough
space (unused capacity) in the buffer.
A buffer consists of
a counter (indicating the number of tokens
in the buffer), and two queues: a put-queue,
for processes waiting to complete a put
operation and a get-queue, for processes
waiting to complete a get operation.
Usage and queueing statistics
are automatically maintained for each
buffer. These are "printed"
whenever a report
or report_buffers
statement is executed (see section
19.2 "CSIM Report Output"
for details about the reports that are
generated).
A pointer to a dynamic
buffer object is as follows:
Dynamic
Example: buffer
*b;
Before a buffer can
be used, it must be initialized by calling
the buffer function.
Prototype:
buffer::buffer(char
*name, long size);
Static Example:
buffer bs("bs",
10);
Dynamic Example:
b = new buffer("b",
10);
A newly created buffer
is empty. Buffers should be declared with
global variables in the sim (main) process,
prior to beginning the simulation part
of the model. A dynamic buffer must be
initialized via the new
buffer statement before it can
be used in any other statement.
Tokens can be added
to a buffer using the put operation.
Prototype:
void buffer::put(long
amt);
Dynamic Example:
b->put(5);
The number of tokens
being put (the amount) is compared with
the space remaining in the buffer (the
maximum size minus the current amount).
If the available space is less than or
equal to space remaining, the amount of
the put is added to the current amount
and the process doing the buffer_put continues.
If the amount of the put exceeds the space
remaining, the process is placed in the
put-queue and is then suspended. When
some other process (or processes) removes
(gets) tokens, the highest priority process
in the put-queue is checked; if its put
request can be accommodated, the buffer_put
is done and the process resumes at the
statement following the buffer_put statement.
If other processes in the put-queue can
be accommodated, they too are processed
and allowed to proceed.
Tokens can be removed
a buffer using the buffer-get statement.
Prototype:
void buffer::get(long
amt);
Dynamic Example:
b->get(4);
The number of tokens
being requested in a get (the amount)
is compared to the number in the buffer.
If the amount is less than or equal to
the number in the buffer, the amount is
subtracted and the process doing the buffer_get
proceeds. If not, the process doing the
buffer_get is placed in the get-queue
and then suspended. When another process
(or processes) puts (adds) tokens to the
buffer, the highest priority process in
the get-queue is checked; if its get request
can be satisfied, the buffer_get is done,
and the process resumes at the statement
following the buffer_get. If other processes
in the get-queue can be accommodated,
they too are processed and allowed to
proceed.
Reports for buffers
are most often produced by calling the
report function which reports for all
CSIM objects. Reports can be produced
for all existing buffers by calling report_buffers
function. The report for a buffer gives
the name of the buffer,
| BUFFER
SUMMARY |
| buffer name |
get size |
get amt |
get qlen |
get resp |
put count |
put amt |
put qlen |
put resp |
put count |
| buff |
20 |
2.4 |
0.00000 |
0.00000 |
32 |
3.5 |
1.54545 |
0.60714 |
28 |
In some cases, it is
necessary to reset the statistics counters
for a specificbuffer.
Prototype:
void buffer:: reset(void)
Example:
b->reset();
Executing this statement
does not affect the state of the buffer
or its servers. The "reset"
and the reset_buffers" statements
each call buffer::reset () for all buffers
in the model.
Sometimes, processes
cannot wait indefinitely to either get
tokens form or putting tokens into a buffer.
Prototype:
long buffer::timed_get(long
amt,
double timeout);
Dynamic Example:
result = b->timed_get(5,
100.0);
if(result != TIMED_OUT) . . .
and
Prototype:
long buffer::timed_put(long
amt,
double timeout);
Dynaimc Example:
result = b->timed_put(5,
100.0);
if(result != TIMED_OUT) . . .
The process must check
the function value (result)
to determine whether or not the operation
time-out or completed. If the value TIME_OUT
is returned, the process did not get or
put the amount. If this value is not returned
(EVENT_OCCURRED will in fact be returned),
then the process did complete successfully.
To increase the space
(capacity) for a buffer,
Prototype:
void buffer::add_space(long
amt);
Dynamic Example:
b->add_space(25);
To remove space (capacity)
from a buffer,
Prototype:
void buffer::remove_space(long
amt);
Dynamic Example:
b->remove_space(2);
To delete a buffer:
Dynamic
Example: delete
b
Deleting a buffer is
an extreme action and should be done only
when necessary.
These functions each
return a statistic or counter value which
describes some aspect of the operation
of a buffer:
| Prototype: |
Function Value: |
| long buffer::current() |
current number
of tokens |
| long buffer::size() |
capacity of buffer |
| long buffer::get_total() |
total amount retrieved |
| long buffer::put_total() |
total amount put |
| long buffer::get_count() |
number of get's |
| long buffer::put_count() |
number of put's |
| double buffer::get_timeQueue() |
sum of get-queue
lengths |
| double buffer::put_timeQueue()
|
sum of get-queue
lengths |
| char* buffer::name() |
name of buffer |
| long buffer::get_current_count() |
current get-queue
length |
| long buffer::put_current_count() |
current put-queue
length |
Prototype:
void buffer_status(void);
Example:
status_buffers();
The
report will be written to the default
output location or to that specified by
set_output_file
(see
section 21.6, "Output File Selection").
Next
Section
|