1 digraph thread_states {
11 // Legitimate transitions
13 dead
-> alive [
label=
"reused" ]
;
15 running
-> wait_join [
label=
"wait for another\nthread termination" ]
;
16 wait_join
-> running [
label=
"target thread\nterminates" ]
;
18 running
-> zombie [
label=
"non-detached thread\nterminates" ]
;
19 zombie
-> dead [
label=
"join completed" ]
;
20 running
-> dead [
label=
"detached thread\nterminates" ]
;
22 running
-> wait_mutex [
label=
"wait for mutex\nacquisition" ]
;
23 wait_mutex
-> running [
label=
"mutex\nacquired" ]
;
24 wait_mutex
-> running [
label=
"mutex\ngiven up" ]
;
26 running
-> wait_condvar [
label=
"wait for condition variable" ]
;
27 wait_condvar
-> running [
label=
"woken" ]
;
29 // How to handle bad actions
30 wait_mutex
-> zombie [
style=
dotted, label=
"thread dies\nwaiting" ]
;
31 wait_mutex
-> dead [
style=
dotted, label=
"thread dies\nwaiting" ]
;
32 wait_mutex
-> wait_condvar [
style=
dotted, label=
"waiting for\nmultiple objects" ]
;
33 wait_mutex
-> wait_join [
style=
dotted, label=
"waiting for\nmultiple objects" ]
;
35 wait_condvar
-> zombie [
style=
dotted, label=
"thread dies\nwaiting" ]
;
36 wait_condvar
-> dead [
style=
dotted, label=
"thread dies\nwaiting" ]
;
37 wait_condvar
-> wait_mutex [
style=
dotted, label=
"waiting for\nmultiple objects" ]
;
38 wait_condvar
-> wait_join [
style=
dotted, label=
"waiting for\nmultiple objects" ]
;
40 wait_join
-> zombie [
style=
dotted, label=
"thread dies\nwaiting" ]
;
41 wait_join
-> dead [
style=
dotted, label=
"thread dies\nwaiting" ]
;
42 wait_join
-> wait_condvar [
style=
dotted, label=
"waiting for\nmultiple objects" ]
;
43 wait_join
-> wait_mutex [
style=
dotted, label=
"waiting for\nmultiple objects" ]
;
45 zombie
-> running [
style=
dotted, label=
"unholy\nresurrection" ]
;
46 dead
-> running [
style=
dotted, label=
"unholy\nresurrection" ]
;