aio_notify.promela 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * This model describes the interaction between ctx->notify_me
  3. * and aio_notify().
  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 simulate it:
  11. * spin -p docs/aio_notify.promela
  12. *
  13. * To verify it:
  14. * spin -a docs/aio_notify.promela
  15. * gcc -O2 pan.c
  16. * ./a.out -a
  17. *
  18. * To verify it (with a bug planted in the model):
  19. * spin -a -DBUG docs/aio_notify.promela
  20. * gcc -O2 pan.c
  21. * ./a.out -a
  22. */
  23. #define MAX 4
  24. #define LAST (1 << (MAX - 1))
  25. #define FINAL ((LAST << 1) - 1)
  26. bool notify_me;
  27. bool event;
  28. int req;
  29. int done;
  30. active proctype waiter()
  31. {
  32. int fetch;
  33. do
  34. :: true -> {
  35. notify_me++;
  36. if
  37. #ifndef BUG
  38. :: (req > 0) -> skip;
  39. #endif
  40. :: else ->
  41. // Wait for a nudge from the other side
  42. do
  43. :: event == 1 -> { event = 0; break; }
  44. od;
  45. fi;
  46. notify_me--;
  47. atomic { fetch = req; req = 0; }
  48. done = done | fetch;
  49. }
  50. od
  51. }
  52. active proctype notifier()
  53. {
  54. int next = 1;
  55. do
  56. :: next <= LAST -> {
  57. // generate a request
  58. req = req | next;
  59. next = next << 1;
  60. // aio_notify
  61. if
  62. :: notify_me == 1 -> event = 1;
  63. :: else -> printf("Skipped event_notifier_set\n"); skip;
  64. fi;
  65. // Test both synchronous and asynchronous delivery
  66. if
  67. :: 1 -> do
  68. :: req == 0 -> break;
  69. od;
  70. :: 1 -> skip;
  71. fi;
  72. }
  73. od;
  74. }
  75. never { /* [] done < FINAL */
  76. accept_init:
  77. do
  78. :: done < FINAL -> skip;
  79. od;
  80. }