After a Buffer Reload

After a buffer reload, the thread that caused the reload is awake (thread A), as well as all threads that were woken up. The thread that caused the reload has the lock, so it will go first. The order of the other threads is nondeterministic, though. Additionally, if thread A finds a sync point match, it is allowed to execute and reenter compactWait, so the number of threads that can run might actually stay the same and not decrease.

In some cases, I’ve found that a thread that has been woken up after a buffer update advances the indices, but it really shouldn’t. In others, though, they clearly need to be advanced. I haven’t yet found the rule that governs when the indices have to be changed and when not.

Here’s an example. Assume the schedule contains these events, where dashes mark a buffer reload:

1 1
1 2
1 3
1 1
---
1 1
1 2
1 3
1 1

Further assume that the threads initially run in the order 3, 2, 1. This is what happens:

  1. 3 enters, does not advance. Waits at index 2…
  2. 2 enters, does not advance. Waits at index 1…
  3. 1 enters, does not advance. Executes.
  4. 1 enters, advances (index=1). Wake up 2. Waits at 3…
  5. …2 wakes up, executes.
  6. 2 enters, advances (index=2). Wake up 3. Waits for new buffer…
  7. …3 wakes up, executes.
  8. 3 enters, advances (index=3). Wake up 1. Waits for new buffer…
  9. …1 wakes up, executes.
  10. 1 enters, advances (index=4). Reload buffer, reset indices (index=0). Executes.
  11. Note: Threads 1, 2, and 3 are all running nondeterministically.
  12. …2 wakes up after reload, advances (index=1). Executes.
  13. Note: Still, threads 1, 2, and 3 are all running nondeterministically.
  14. 1 enters, advances (index=2). Waits at 3…
  15. Note: Threads 2 and 3 still running nondeterministically.
  16. …3 wakes up after reload, advances (index=3). Index 2 was skipped! Wake up 1. Waits for new buffer…
  17. …1 wakes up, executes. Assertions violated, sync point “1 1” executed, but “1 3” was expected.
  18. The confusing thing is that in step 12, thread 2 clearly has to advance the indices, yet in step 16, thread 3 clearly may not advance them. It has something to do with whether the previous thread executed immediately or not (for thread 2, the previous thread did; for thread 3, it did not).

    I guess I’ll try to sleep over it again.

    Share

About Mathias

Software development engineer. Principal developer of DrJava. Recent Ph.D. graduate from the Department of Computer Science at Rice University.
This entry was posted in Concurrent Unit Testing. Bookmark the permalink.

Leave a Reply