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 buffer is declared in a CSIM program
using the built-in type BUFFER.
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);
Example:
b = 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 buffer must be initialized
via the 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(BUFFER
b, long amt);
Example:
buffer_put(b,
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(BUFFER
b, long amt);
Example:
buffer_get(b,
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,
In some cases, it is necessary to reset
the statistics counters for a specificbuffer.
Prototype:
void reset_buffer(BUFFER
b)
Example:
reset_buffer(b);
Executing this statement does not affect
the state of the buffer or its servers.
The "reset" and the reset_buffers"
statements each call reset_buffer()
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(BUFFER
b, long amt,
double timeout);
Example:
result = buffer_timed_get(b,
5, 100.0);
if(result != TIMED_OUT) . . .
and
Prototype:
long buffer_timed_put(BUFFER
b, long amt,
double timeout);
Example:
result = buffer_timed_put(b,
5, 100.0);
if(result != TIMED_OUT) . . .
The process must check the function
value (result)
to determine whether or not the operation
completed or timed-out. If the value
TIME_OUT is returned, the process did
not obtain any of the requested storage.
If this value is not returned (EVENT_OCCURRED
will in fact be returned), then the
process did obtain the requested storage.
To increase the space (capacity) for
a buffer,
Prototype:
void buffer_add_space(BUFFER
b, long amt);
Example:
buffer_add_space(b,
25);
To remove space (capacity) from a buffer,
Prototype:
void buffer_remove_space(BUFFER
b, long amt);
Example:
buffer_remove_space(b,
2);
To delete a buffer:
Prototype:
void delete_buffer(BUFFER
b);
Example:
delete_buffer(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(BUFFER
b) |
current number
of tokens |
| long buffer_size(BUFFER
b) |
capacity of buffer |
| long buffer_get_total(BUFFER
b) |
total amount
retrieved |
| long buffer_put_total(BUFFER
b) |
total amount
put |
| long buffer_get_count(BUFFER
b) |
number of get's |
| long buffer_put_count(BUFFER
b) |
number of put's |
| double buffer_get_timeQueue(BUFFER
b) |
sum of get-queue
lengths |
| double buffer_put_timeQueue(BUFFER
b) |
sum of get-queue
lengths |
| char* buffer_name(BUFFER
b) |
name of buffer |
| long buffer_get_current_count(BUFFER
b) |
current get-queue
length |
| long buffer_put_current_count(BUFFER
b) |
current put-queue
length |
Prototype:
void status_buffers(BUFFER
b);
Example:
status_buffers(b);
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").