]> git.proxmox.com Git - mirror_qemu.git/blame - docs/win32-qemu-event.promela
rbd: Fix bugs around -drive parameter "server"
[mirror_qemu.git] / docs / win32-qemu-event.promela
CommitLineData
7c9b2bf6
PB
1/*
2 * This model describes the implementation of QemuEvent in
3 * util/qemu-thread-win32.c.
4 *
5 * Author: Paolo Bonzini <pbonzini@redhat.com>
6 *
7 * This file is in the public domain. If you really want a license,
8 * the WTFPL will do.
9 *
10 * To verify it:
11 * spin -a docs/event.promela
12 * gcc -O2 pan.c -DSAFETY
13 * ./a.out
14 */
15
16bool event;
17int value;
18
19/* Primitives for a Win32 event */
20#define RAW_RESET event = false
21#define RAW_SET event = true
22#define RAW_WAIT do :: event -> break; od
23
24#if 0
25/* Basic sanity checking: test the Win32 event primitives */
26#define RESET RAW_RESET
27#define SET RAW_SET
28#define WAIT RAW_WAIT
29#else
30/* Full model: layer a userspace-only fast path on top of the RAW_*
31 * primitives. SET/RESET/WAIT have exactly the same semantics as
32 * RAW_SET/RAW_RESET/RAW_WAIT, but try to avoid invoking them.
33 */
34#define EV_SET 0
35#define EV_FREE 1
36#define EV_BUSY -1
37
38int state = EV_FREE;
39
40int xchg_result;
41#define SET if :: state != EV_SET -> \
42 atomic { /* xchg_result=xchg(state, EV_SET) */ \
43 xchg_result = state; \
44 state = EV_SET; \
45 } \
46 if :: xchg_result == EV_BUSY -> RAW_SET; \
47 :: else -> skip; \
48 fi; \
49 :: else -> skip; \
50 fi
51
52#define RESET if :: state == EV_SET -> atomic { state = state | EV_FREE; } \
53 :: else -> skip; \
54 fi
55
56int tmp1, tmp2;
57#define WAIT tmp1 = state; \
58 if :: tmp1 != EV_SET -> \
59 if :: tmp1 == EV_FREE -> \
60 RAW_RESET; \
61 atomic { /* tmp2=cas(state, EV_FREE, EV_BUSY) */ \
62 tmp2 = state; \
63 if :: tmp2 == EV_FREE -> state = EV_BUSY; \
64 :: else -> skip; \
65 fi; \
66 } \
67 if :: tmp2 == EV_SET -> tmp1 = EV_SET; \
68 :: else -> tmp1 = EV_BUSY; \
69 fi; \
70 :: else -> skip; \
71 fi; \
72 assert(tmp1 != EV_FREE); \
73 if :: tmp1 == EV_BUSY -> RAW_WAIT; \
74 :: else -> skip; \
75 fi; \
76 :: else -> skip; \
77 fi
78#endif
79
80active proctype waiter()
81{
82 if
83 :: !value ->
84 RESET;
85 if
86 :: !value -> WAIT;
87 :: else -> skip;
88 fi;
89 :: else -> skip;
90 fi;
91 assert(value);
92}
93
94active proctype notifier()
95{
96 value = true;
97 SET;
98}