+++ /dev/null
-//#define NUMPROCS 5
-#define NUMPROCS 4
-#define BUFSIZE 4
-#define NR_SUBBUFS 2
-#define SUBBUF_SIZE (BUFSIZE / NR_SUBBUFS)
-
-byte write_off = 0;
-byte read_off = 0;
-byte events_lost = 0;
-byte deliver = 0; // Number of subbuffers delivered
-byte refcount = 0;
-
-byte commit_count[NR_SUBBUFS];
-
-byte buffer_use_count[BUFSIZE];
-
-proctype switcher()
-{
- int prev_off, new_off, tmp_commit;
- int size;
-
-cmpxchg_loop:
- atomic {
- prev_off = write_off;
- size = SUBBUF_SIZE - (prev_off % SUBBUF_SIZE);
- new_off = prev_off + size;
- if
- :: new_off - read_off > BUFSIZE ->
- goto not_needed;
- :: else -> skip
- fi;
- }
- atomic {
- if
- :: prev_off != write_off -> goto cmpxchg_loop
- :: else -> write_off = new_off;
- fi;
- }
-
- atomic {
- tmp_commit = commit_count[(prev_off % BUFSIZE) / SUBBUF_SIZE] + size;
- commit_count[(prev_off % BUFSIZE) / SUBBUF_SIZE] = tmp_commit;
- if
- :: tmp_commit % SUBBUF_SIZE == 0 -> deliver++
- :: else -> skip
- fi;
- }
-not_needed:
- skip;
-}
-
-proctype tracer(byte size)
-{
- int prev_off, new_off, tmp_commit;
- int i;
- int j;
-
-cmpxchg_loop:
- atomic {
- prev_off = write_off;
- new_off = prev_off + size;
- }
- atomic {
- if
- :: new_off - read_off > BUFSIZE -> goto lost
- :: else -> skip
- fi;
- }
- atomic {
- if
- :: prev_off != write_off -> goto cmpxchg_loop
- :: else -> write_off = new_off;
- fi;
- i = 0;
- do
- :: i < size ->
- buffer_use_count[(prev_off + i) % BUFSIZE]
- = buffer_use_count[(prev_off + i) % BUFSIZE] + 1;
- i++
- :: i >= size -> break
- od;
- }
- do
- :: j < BUFSIZE ->
- assert(buffer_use_count[j] < 2);
- j++
- :: j >= BUFSIZE -> break
- od;
-
-
-
- // writing to buffer...
-
- atomic {
- i = 0;
- do
- :: i < size ->
- buffer_use_count[(prev_off + i) % BUFSIZE]
- = buffer_use_count[(prev_off + i) % BUFSIZE] - 1;
- i++
- :: i >= size -> break
- od;
- tmp_commit = commit_count[(prev_off % BUFSIZE) / SUBBUF_SIZE] + size;
- commit_count[(prev_off % BUFSIZE) / SUBBUF_SIZE] = tmp_commit;
- if
- :: tmp_commit % SUBBUF_SIZE == 0 -> deliver++
- :: else -> skip
- fi;
- }
- goto end;
-lost:
- events_lost++;
-end:
- refcount = refcount - 1;
-}
-
-proctype reader()
-{
- int i;
- int j;
- //atomic {
- // do
- // :: (deliver == (NUMPROCS - events_lost) / SUBBUF_SIZE) -> break;
- // od;
- //}
- do
- :: (write_off / SUBBUF_SIZE) - (read_off / SUBBUF_SIZE) > 0 && commit_count[(read_off % BUFSIZE) / SUBBUF_SIZE] % SUBBUF_SIZE == 0 ->
- atomic {
- i = 0;
- do
- :: i < SUBBUF_SIZE ->
- buffer_use_count[(read_off + i) % BUFSIZE]
- = buffer_use_count[(read_off + i) % BUFSIZE] + 1;
- i++
- :: i >= SUBBUF_SIZE -> break
- od;
- }
- j = 0;
- do
- :: j < BUFSIZE ->
- assert(buffer_use_count[j] < 2);
- j++
- :: j >= BUFSIZE -> break
- od;
-
- // reading from buffer...
-
- atomic {
- i = 0;
- do
- :: i < SUBBUF_SIZE ->
- buffer_use_count[(read_off + i) % BUFSIZE]
- = buffer_use_count[(read_off + i) % BUFSIZE] - 1;
- i++
- :: i >= SUBBUF_SIZE -> break
- od;
- read_off = read_off + SUBBUF_SIZE;
- }
- :: read_off >= (NUMPROCS - events_lost) -> break;
- od;
-}
-
-proctype cleaner()
-{
- atomic {
- do
- :: refcount == 0 ->
- run switcher();
- break;
- od;
- }
-}
-
-init {
- int i = 0;
- int j = 0;
- int sum = 0;
- int commit_sum = 0;
-
- atomic {
- i = 0;
- do
- :: i < NR_SUBBUFS ->
- commit_count[i] = 0;
- i++
- :: i >= NR_SUBBUFS -> break
- od;
- i = 0;
- do
- :: i < BUFSIZE ->
- buffer_use_count[i] = 0;
- i++
- :: i >= BUFSIZE -> break
- od;
- run reader();
- run cleaner();
- i = 0;
- do
- :: i < NUMPROCS ->
- refcount = refcount + 1;
- run tracer(1);
- i++
- :: i >= NUMPROCS -> break
- od;
- run switcher();
- }
- atomic {
- assert(write_off - read_off >= 0);
- j = 0;
- commit_sum = 0;
- do
- :: j < NR_SUBBUFS ->
- commit_sum = commit_sum + commit_count[j];
- j++
- :: j >= NR_SUBBUFS -> break
- od;
- assert(commit_sum <= write_off);
- j = 0;
- do
- :: j < BUFSIZE ->
- assert(buffer_use_count[j] < 2);
- j++
- :: j >= BUFSIZE -> break
- od;
-
- //assert(events_lost == 0);
- }
-}