@@ -122,17 +122,18 @@ <h3>The Problem</h3>
122122 </ p >
123123 < p >
124124 < strong > Challenge:</ strong > How to prevent deadlock when all philosophers
125- simultaneously grab their left fork?
125+ simultaneously grab their left fork? This would create a circular wait condition.
126126 </ p >
127127 < p >
128- < strong > Solution:</ strong > Asymmetric fork acquisition - odd philosophers grab
129- right fork first, even philosophers grab left fork first.
128+ < strong > Solution:</ strong > Asymmetric fork acquisition strategy - odd-numbered philosophers grab
129+ their right fork first, even-numbered philosophers grab their left fork first.
130+ This breaks the symmetry and prevents circular deadlock.
130131 </ p >
131132 </ div >
132133
133134 < div class ="legend ">
134135 < div class ="legend-item ">
135- < strong > →→ </ strong > Solid Arrow< br >
136+ < strong > →</ strong > Solid Arrow< br >
136137 Synchronous call (request/release fork)
137138 </ div >
138139 < div class ="legend-item ">
@@ -143,6 +144,10 @@ <h3>The Problem</h3>
143144 < strong > Timestamps</ strong > < br >
144145 Virtual time progression
145146 </ div >
147+ < div class ="legend-item ">
148+ < strong > Self-loops</ strong > < br >
149+ Philosopher internal state changes
150+ </ div >
146151 </ div >
147152
148153 < div class ="diagram-container ">
@@ -168,94 +173,6 @@ <h3>The Problem</h3>
168173 Note over philosopher_1,fork_1: t=150ms
169174 fork_1-> > philosopher_1: {:fork_granted, :fork_1}
170175 Note over fork_1,philosopher_1: t=150ms
171- philosopher_1-> > philosopher_1: {:mumble, "I'm full!"}
172- Note over philosopher_1,philosopher_1: t=225ms
173- philosopher_1-> > fork_0: {:release_fork, :philosopher_1}
174- Note over philosopher_1,fork_0: t=225ms
175- philosopher_1-> > fork_1: {:release_fork, :philosopher_1}
176- Note over philosopher_1,fork_1: t=225ms
177- philosopher_0-> > philosopher_0: {:start_hungry, :fork_0, :fork_1}
178- Note over philosopher_0,philosopher_0: t=300ms
179- philosopher_1-> > philosopher_1: {:start_hungry, :fork_0, :fork_1}
180- Note over philosopher_1,philosopher_1: t=300ms
181- philosopher_0-> > fork_0: {:request_fork, :philosopher_0}
182- Note over philosopher_0,fork_0: t=300ms
183- philosopher_1-> > fork_0: {:request_fork, :philosopher_1}
184- Note over philosopher_1,fork_0: t=300ms
185- fork_0-> > philosopher_0: {:fork_granted, :fork_0}
186- Note over fork_0,philosopher_0: t=300ms
187- fork_0-> > philosopher_1: {:fork_denied, :fork_0}
188- Note over fork_0,philosopher_1: t=300ms
189- philosopher_0-> > fork_1: {:request_fork, :philosopher_0}
190- Note over philosopher_0,fork_1: t=300ms
191- fork_1-> > philosopher_0: {:fork_granted, :fork_1}
192- Note over fork_1,philosopher_0: t=300ms
193- philosopher_0-> > philosopher_0: {:mumble, "I'm full!"}
194- Note over philosopher_0,philosopher_0: t=375ms
195- philosopher_0-> > fork_0: {:release_fork, :philosopher_0}
196- Note over philosopher_0,fork_0: t=375ms
197- philosopher_0-> > fork_1: {:release_fork, :philosopher_0}
198- Note over philosopher_0,fork_1: t=375ms
199- philosopher_1-> > philosopher_1: {:start_hungry, :fork_0, :fork_1}
200- Note over philosopher_1,philosopher_1: t=450ms
201- philosopher_0-> > philosopher_0: {:start_hungry, :fork_0, :fork_1}
202- Note over philosopher_0,philosopher_0: t=450ms
203- philosopher_0-> > fork_0: {:request_fork, :philosopher_0}
204- Note over philosopher_0,fork_0: t=450ms
205- philosopher_1-> > fork_0: {:request_fork, :philosopher_1}
206- Note over philosopher_1,fork_0: t=450ms
207- fork_0-> > philosopher_0: {:fork_granted, :fork_0}
208- Note over fork_0,philosopher_0: t=450ms
209- fork_0-> > philosopher_1: {:fork_denied, :fork_0}
210- Note over fork_0,philosopher_1: t=450ms
211- philosopher_0-> > fork_1: {:request_fork, :philosopher_0}
212- Note over philosopher_0,fork_1: t=450ms
213- fork_1-> > philosopher_0: {:fork_granted, :fork_1}
214- Note over fork_1,philosopher_0: t=450ms
215- philosopher_0-> > philosopher_0: {:mumble, "I'm full!"}
216- Note over philosopher_0,philosopher_0: t=525ms
217- philosopher_0-> > fork_0: {:release_fork, :philosopher_0}
218- Note over philosopher_0,fork_0: t=525ms
219- philosopher_0-> > fork_1: {:release_fork, :philosopher_0}
220- Note over philosopher_0,fork_1: t=525ms
221- philosopher_0-> > philosopher_0: {:start_hungry, :fork_0, :fork_1}
222- Note over philosopher_0,philosopher_0: t=600ms
223- philosopher_1-> > philosopher_1: {:start_hungry, :fork_0, :fork_1}
224- Note over philosopher_1,philosopher_1: t=600ms
225- philosopher_0-> > fork_0: {:request_fork, :philosopher_0}
226- Note over philosopher_0,fork_0: t=600ms
227- philosopher_1-> > fork_0: {:request_fork, :philosopher_1}
228- Note over philosopher_1,fork_0: t=600ms
229- fork_0-> > philosopher_0: {:fork_granted, :fork_0}
230- Note over fork_0,philosopher_0: t=600ms
231- fork_0-> > philosopher_1: {:fork_denied, :fork_0}
232- Note over fork_0,philosopher_1: t=600ms
233- philosopher_0-> > fork_1: {:request_fork, :philosopher_0}
234- Note over philosopher_0,fork_1: t=600ms
235- fork_1-> > philosopher_0: {:fork_granted, :fork_1}
236- Note over fork_1,philosopher_0: t=600ms
237- philosopher_0-> > philosopher_0: {:mumble, "I'm full!"}
238- Note over philosopher_0,philosopher_0: t=675ms
239- philosopher_0-> > fork_0: {:release_fork, :philosopher_0}
240- Note over philosopher_0,fork_0: t=675ms
241- philosopher_0-> > fork_1: {:release_fork, :philosopher_0}
242- Note over philosopher_0,fork_1: t=675ms
243- philosopher_0-> > philosopher_0: {:start_hungry, :fork_0, :fork_1}
244- Note over philosopher_0,philosopher_0: t=750ms
245- philosopher_0-> > fork_0: {:request_fork, :philosopher_0}
246- Note over philosopher_0,fork_0: t=750ms
247- philosopher_1-> > philosopher_1: {:start_hungry, :fork_0, :fork_1}
248- Note over philosopher_1,philosopher_1: t=750ms
249- fork_0-> > philosopher_0: {:fork_granted, :fork_0}
250- Note over fork_0,philosopher_0: t=750ms
251- philosopher_0-> > fork_1: {:request_fork, :philosopher_0}
252- Note over philosopher_0,fork_1: t=750ms
253- philosopher_1-> > fork_0: {:request_fork, :philosopher_1}
254- Note over philosopher_1,fork_0: t=750ms
255- fork_0-> > philosopher_1: {:fork_denied, :fork_0}
256- Note over fork_0,philosopher_1: t=750ms
257- fork_1-> > philosopher_0: {:fork_granted, :fork_1}
258- Note over fork_1,philosopher_0: t=750ms
259176 </ div >
260177 </ div >
261178
@@ -274,9 +191,9 @@ <h3>Simulation Source Code</h3>
274191 < div class ="explanation " style ="margin-top: 20px; ">
275192 < h3 > What the Diagram Shows</ h3 >
276193 < ul >
277- < li > Each philosopher sends synchronous < code > :request </ code > messages to forks</ li >
278- < li > Forks reply with < code > :granted </ code > or < code > :denied </ code > </ li >
279- < li > After eating, philosophers send < code > :release </ code > to both forks</ li >
194+ < li > Each philosopher sends synchronous < code > :request_fork </ code > messages to forks</ li >
195+ < li > Forks reply with < code > :fork_granted </ code > or < code > :fork_denied </ code > </ li >
196+ < li > After eating, philosophers send < code > :release_fork </ code > to both forks</ li >
280197 < li > The timeline shows how virtual time advances instantly in tests</ li >
281198 < li > No deadlocks occur due to asymmetric fork acquisition</ li >
282199 </ ul >
0 commit comments