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