Each ``block'' is one of the following. Each one operates starting at
the current position. Before the first block runs, current position is
address 0 in the simulated process's address space.
size is number of bytes in this process, as chosen by the main program.
(See ``Hints and Implementation Details'' section for explanation of what the
percentages in the following list mean, in case they're unclear.)
- 60% of the time, linearly access n memory locations (0 <= n <= (size/2)).
- 20% of the time, loop m times linearly accessing n memory
locations (0 <= n <= (size/8)) (2 <= m <= 6).
- 20% of the time, jump to n locations away from current location
(-(size/16) <= n <= (size/16)).
Before performing the action for each block (linear access, loop or jump),
it should print out a one-line message, containing PID, action-type, and
action parameters.
Treat all math on memory addresses as being modulo the size of the process
space. For example, within each block's run, if a linear or loop would
overflow the end of memory, have it continue back at the front, as if memory
was a circular list. (For example, if current position is 80, and size is
100, and the value of n randomly chosen for a linear access is 35; then
the addresses accessed should be 80,81,...,98,99,0,1,...,13,14.)