xref: /openbmc/qemu/docs/spin/aio_notify.promela (revision 63cb5578)
1*ac06724aSPaolo Bonzini/*
2*ac06724aSPaolo Bonzini * This model describes the interaction between ctx->notify_me
3*ac06724aSPaolo Bonzini * and aio_notify().
4*ac06724aSPaolo Bonzini *
5*ac06724aSPaolo Bonzini * Author: Paolo Bonzini <pbonzini@redhat.com>
6*ac06724aSPaolo Bonzini *
7*ac06724aSPaolo Bonzini * This file is in the public domain.  If you really want a license,
8*ac06724aSPaolo Bonzini * the WTFPL will do.
9*ac06724aSPaolo Bonzini *
10*ac06724aSPaolo Bonzini * To simulate it:
11*ac06724aSPaolo Bonzini *     spin -p docs/aio_notify.promela
12*ac06724aSPaolo Bonzini *
13*ac06724aSPaolo Bonzini * To verify it:
14*ac06724aSPaolo Bonzini *     spin -a docs/aio_notify.promela
15*ac06724aSPaolo Bonzini *     gcc -O2 pan.c
16*ac06724aSPaolo Bonzini *     ./a.out -a
17*ac06724aSPaolo Bonzini *
18*ac06724aSPaolo Bonzini * To verify it (with a bug planted in the model):
19*ac06724aSPaolo Bonzini *     spin -a -DBUG docs/aio_notify.promela
20*ac06724aSPaolo Bonzini *     gcc -O2 pan.c
21*ac06724aSPaolo Bonzini *     ./a.out -a
22*ac06724aSPaolo Bonzini */
23*ac06724aSPaolo Bonzini
24*ac06724aSPaolo Bonzini#define MAX   4
25*ac06724aSPaolo Bonzini#define LAST  (1 << (MAX - 1))
26*ac06724aSPaolo Bonzini#define FINAL ((LAST << 1) - 1)
27*ac06724aSPaolo Bonzini
28*ac06724aSPaolo Bonzinibool notify_me;
29*ac06724aSPaolo Bonzinibool event;
30*ac06724aSPaolo Bonzini
31*ac06724aSPaolo Bonziniint req;
32*ac06724aSPaolo Bonziniint done;
33*ac06724aSPaolo Bonzini
34*ac06724aSPaolo Bonziniactive proctype waiter()
35*ac06724aSPaolo Bonzini{
36*ac06724aSPaolo Bonzini    int fetch;
37*ac06724aSPaolo Bonzini
38*ac06724aSPaolo Bonzini    do
39*ac06724aSPaolo Bonzini        :: true -> {
40*ac06724aSPaolo Bonzini            notify_me++;
41*ac06724aSPaolo Bonzini
42*ac06724aSPaolo Bonzini            if
43*ac06724aSPaolo Bonzini#ifndef BUG
44*ac06724aSPaolo Bonzini                :: (req > 0) -> skip;
45*ac06724aSPaolo Bonzini#endif
46*ac06724aSPaolo Bonzini                :: else ->
47*ac06724aSPaolo Bonzini                    // Wait for a nudge from the other side
48*ac06724aSPaolo Bonzini                    do
49*ac06724aSPaolo Bonzini                        :: event == 1 -> { event = 0; break; }
50*ac06724aSPaolo Bonzini                    od;
51*ac06724aSPaolo Bonzini            fi;
52*ac06724aSPaolo Bonzini
53*ac06724aSPaolo Bonzini            notify_me--;
54*ac06724aSPaolo Bonzini
55*ac06724aSPaolo Bonzini            atomic { fetch = req; req = 0; }
56*ac06724aSPaolo Bonzini            done = done | fetch;
57*ac06724aSPaolo Bonzini        }
58*ac06724aSPaolo Bonzini    od
59*ac06724aSPaolo Bonzini}
60*ac06724aSPaolo Bonzini
61*ac06724aSPaolo Bonziniactive proctype notifier()
62*ac06724aSPaolo Bonzini{
63*ac06724aSPaolo Bonzini    int next = 1;
64*ac06724aSPaolo Bonzini
65*ac06724aSPaolo Bonzini    do
66*ac06724aSPaolo Bonzini        :: next <= LAST -> {
67*ac06724aSPaolo Bonzini            // generate a request
68*ac06724aSPaolo Bonzini            req = req | next;
69*ac06724aSPaolo Bonzini            next = next << 1;
70*ac06724aSPaolo Bonzini
71*ac06724aSPaolo Bonzini            // aio_notify
72*ac06724aSPaolo Bonzini            if
73*ac06724aSPaolo Bonzini                :: notify_me == 1 -> event = 1;
74*ac06724aSPaolo Bonzini                :: else           -> printf("Skipped event_notifier_set\n"); skip;
75*ac06724aSPaolo Bonzini            fi;
76*ac06724aSPaolo Bonzini
77*ac06724aSPaolo Bonzini            // Test both synchronous and asynchronous delivery
78*ac06724aSPaolo Bonzini            if
79*ac06724aSPaolo Bonzini                :: 1 -> do
80*ac06724aSPaolo Bonzini                            :: req == 0 -> break;
81*ac06724aSPaolo Bonzini                        od;
82*ac06724aSPaolo Bonzini                :: 1 -> skip;
83*ac06724aSPaolo Bonzini            fi;
84*ac06724aSPaolo Bonzini        }
85*ac06724aSPaolo Bonzini    od;
86*ac06724aSPaolo Bonzini}
87*ac06724aSPaolo Bonzini
88*ac06724aSPaolo Bonzininever { /* [] done < FINAL */
89*ac06724aSPaolo Bonziniaccept_init:
90*ac06724aSPaolo Bonzini        do
91*ac06724aSPaolo Bonzini        :: done < FINAL -> skip;
92*ac06724aSPaolo Bonzini        od;
93*ac06724aSPaolo Bonzini}
94