
A Benchmark Test for Systems Implementation Languages
-----------------------------------------------------


This benchmark is designed to be a machine and language independent
test of Systems Implementation Languages. The test itself simulates
part of a light weight kernel of a multi-tasking operating system. It
spends its time packing and unpacking small messages and passing them
between simulated tasks and devices under the control of a scheduler.

Each simulated task has a task control block (TCB) which contains
the fields:

    link       a pointer to another tcb or nil.
    id         the identifier (a small integer) of the task.
    pri        the priority (a positive integer) of the task.
    wkq        list of packets on the work queue.
    state      a three bit value giving the state of the task
               xx1 means the work queue is not empty
               x1x means the task suspended itself awaiting a packet
               1xx means that the task is not permitted to run.
    fn         the function called by the scheduler when transfers
               control to this task.
    v1         v1 and v2 are simulated machine registers that are
    v2         saved and restored by the scheduler.

Communication between tasks is by means of packets that have the 
following fields:

    link       a pointer to the next packet or nil.
    id         the id of the task or device that sent the packet.
    kind       kind, a1 and a2 encode the message contained in the 
    a1         packet.
    a2

There are some globally accessible variables. These are:

    tasktab    a vector of tasks giving a mapping between
               task identifiers and TCBs. Its zeroth element
               contains the upperbound of the table.
    tasklist   is the list of TCBs in decreasing priority order.
    tcb        is a pointer to the TCB of the currently running task.
    taskid     is the identifier of the currently running task.
    v1         v1 and v2 are simulated machine registers that must
    v2         be saved and restored during scheduling.

There are 6 tasks in the simulation. In increasing priority order
they are:

0:  idle       the idle task which counts how often it is activated
               ending the simulation when a given limit is reached.
               Normally it just releases either task 4 (deva) or
               task 5 (devb) under the control of a machine independent
               random number generator.

1:  work       a task that packs characters into packets and sends them
               alternately to task 2 (handlera) and task 3 (handlerb).

2:  handlera   a task that receives packets from task 1 (work) and sends
               the characters they contain to task 4 (deva) one at a time.

3:  handlerb   a task that receives packets from task 1 (work) and sends
               the characters they contain to task 5 (devb) one at a time.

4:  deva       a task that simulates a single character device. On
               receiving a packet it suspends itself using holdself. When
               released by the idle task it returns the packet to handlera.

5:  devb       a task that simulates a single character device. On
               receiving a packet it suspends itself using holdself. When
               released by the idle task it returns the packet to handlerb.

The random number generator used by the idle task to choose whether to
release task 4 (deva) or task 5 (devb) is based in the CRC algorithm often
used for checksum in floopy disk hardware. The implementation involves
shift and exclusive or operations. The test also expects to be able to
hold a function in a field of a data structure, as is done in the fn field
of a TCB. The test also does some list processing in the scheduler and in
the handling of packets, and there is also some character handling.

Originally the program was constrained to be compiled as two separate
modules, but this has been relaxed for systems where separate compilation
does not cause a significant runtime overhead.

This benchmark was originally coded in bcpl in about 1980 and has been
translated into several other languages. It has recently been slightly
modified to give it two variants: bench.b and bench100.b. The first is
almost identical to the original test while second that does 100 times
more work. This was found necessary as modern day computers is now so
fast. The two variants differ only in one or two lines near the
beginning.

Measurements on the BCPL Cintcode versions give the following
execution counts:

Bench      executes    6,177,550  Cintcode instructions.
Bench100   executes  617,379,834  Cintcode instructions.


Debugging

So that it is possible to check that an implementation is correct it
is possible to turn on tracing. When on, the identifier of a task (0-5)
is output every time the scheduler transfers control to it, and every
time a device receives a packet, the character it contained (A-Z) is
output.  When bench is run with tracing on the output should start as
follows:

bench mark starting, Count=10000

starting

444333246A4442235E33321666B4442421555F3332321555G3
31555H331666C441555M331555N3332421555O31666D441555
P3155311666I441666J444235U33321555V3332421666K4415
55W31555X3155311666L441666Q4411666R444235C33321555
D3332421555E31666S441555F31666T441666Y4415531666Z4
44235K33321666A441555L3332421666B441555M31555N3166
6G441553111666H444235S33321555T3332421666I441666J4
41666O441666P4442321555U331555V331555A331666Q44155
5B3332421666R441666W441555C31555D31666X44423332166
6Y441555I331666Z441666E441666F4442421666G441555J33
...

and it should end as follows:

...
666J4442321666K41555E331666L416641555F333246Q44421
555G331666R4442321666S41555H331666T4166411555M3315
55N333246Y44421666Z4442321555O331555P331666A41666B
41555U3316641555V333246G44421555W331555X331666H444
2321555C331555D3332421555E331666I441666J441555F331
666O441555K331555L3332321666P4442421
finished
qpkt count = 23246  holdcount = 9297
these results are correct
end of run
        
Test Results

These appear in the file src/doc/results and should typically show
the person making the test, the processor and operating system details,
the language and compiler details, the size in bytes of the compiled
code, the CPU execution time in seconds and the date of the test. An exxaple
entry is as follows:

Language:      BCPL -> Cintcode
Test:          bench100
Processor:     275MHz DEC Alpha
O/S:           OSF1 V3.2 41
Date:          28 Nov 96
Tester:        M. Richards
Size:          1164
CPU Time:      42.632

Language:      BCPL -> DEC Alpha native code
Test:          bench100
Processor:     275MHz DEC Alpha
O/S:           OSF1 V3.2 41
Date:          26 Nov 96
Tester:        M. Richards
Size:          1164
CPU Time:      8.1




Martin Richards
27 November 1996
***********************************************************************
Computer Laboratory                   http://www.cl.cam.ac.uk/users/mr/
New Museums Site                      mr@cl.cam.ac.uk
Pembroke Street                       tel: 01223 334633
Cambridge CB2 3QG                     fax: 01223 334678
***********************************************************************


