119 *} |
119 *} |
120 |
120 |
121 consts |
121 consts |
122 holding :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
122 holding :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
123 waiting :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
123 waiting :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
124 depend :: "'b \<Rightarrow> (node \<times> node) set" |
124 RAG :: "'b \<Rightarrow> (node \<times> node) set" |
125 dependants :: "'b \<Rightarrow> thread \<Rightarrow> thread set" |
125 dependants :: "'b \<Rightarrow> thread \<Rightarrow> thread set" |
126 |
126 |
127 text {* |
127 text {* |
128 \noindent |
128 \noindent |
129 In the definition of the following several functions, it is supposed that |
129 In the definition of the following several functions, it is supposed that |
151 *} |
151 *} |
152 cs_waiting_def: |
152 cs_waiting_def: |
153 "waiting wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread \<noteq> hd (wq cs))" |
153 "waiting wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread \<noteq> hd (wq cs))" |
154 -- {* |
154 -- {* |
155 \begin{minipage}{0.9\textwidth} |
155 \begin{minipage}{0.9\textwidth} |
156 @{text "depend wq"} represents the Resource Allocation Graph of the system under the waiting |
156 @{text "RAG wq"} represents the Resource Allocation Graph of the system under the waiting |
157 queue function @{text "wq"}. |
157 queue function @{text "wq"}. |
158 \end{minipage} |
158 \end{minipage} |
159 *} |
159 *} |
160 cs_depend_def: |
160 cs_RAG_def: |
161 "depend (wq::cs \<Rightarrow> thread list) \<equiv> |
161 "RAG (wq::cs \<Rightarrow> thread list) \<equiv> |
162 {(Th th, Cs cs) | th cs. waiting wq th cs} \<union> {(Cs cs, Th th) | cs th. holding wq th cs}" |
162 {(Th th, Cs cs) | th cs. waiting wq th cs} \<union> {(Cs cs, Th th) | cs th. holding wq th cs}" |
163 -- {* |
163 -- {* |
164 \begin{minipage}{0.9\textwidth} |
164 \begin{minipage}{0.9\textwidth} |
165 The following @{text "dependants wq th"} represents the set of threads which are depending on |
165 The following @{text "dependants wq th"} represents the set of threads which are RAGing on |
166 thread @{text "th"} in Resource Allocation Graph @{text "depend wq"}: |
166 thread @{text "th"} in Resource Allocation Graph @{text "RAG wq"}: |
167 \end{minipage} |
167 \end{minipage} |
168 *} |
168 *} |
169 cs_dependants_def: |
169 cs_dependants_def: |
170 "dependants (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (depend wq)^+}" |
170 "dependants (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (RAG wq)^+}" |
171 |
171 |
172 |
172 |
173 text {* |
173 text {* |
174 The data structure used by the operating system for scheduling is referred to as |
174 The data structure used by the operating system for scheduling is referred to as |
175 {\em schedule state}. It is represented as a record consisting of |
175 {\em schedule state}. It is represented as a record consisting of |
241 thread in waiting to take over the released resource @{text "cs"}. In our representation, |
241 thread in waiting to take over the released resource @{text "cs"}. In our representation, |
242 this amounts to rearrange elements in waiting queue, so that one of them is put at the head. |
242 this amounts to rearrange elements in waiting queue, so that one of them is put at the head. |
243 \item For other happening event, the schedule state just does not change. |
243 \item For other happening event, the schedule state just does not change. |
244 \end{enumerate} |
244 \end{enumerate} |
245 \item @{text "ncp"} is new precedence function, it is calculated from the newly updated waiting queue |
245 \item @{text "ncp"} is new precedence function, it is calculated from the newly updated waiting queue |
246 function. The dependency of precedence function on waiting queue function is the reason to |
246 function. The RAGency of precedence function on waiting queue function is the reason to |
247 put them in the same record so that they can evolve together. |
247 put them in the same record so that they can evolve together. |
248 \end{enumerate} |
248 \end{enumerate} |
249 \end{minipage} |
249 \end{minipage} |
250 *} |
250 *} |
251 "schs (Create th prio # s) = |
251 "schs (Create th prio # s) = |
267 (|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|))" |
267 (|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|))" |
268 |
268 |
269 lemma cpreced_initial: |
269 lemma cpreced_initial: |
270 "cpreced (\<lambda> cs. []) [] = (\<lambda>_. (Prc 0 0))" |
270 "cpreced (\<lambda> cs. []) [] = (\<lambda>_. (Prc 0 0))" |
271 apply(simp add: cpreced_def) |
271 apply(simp add: cpreced_def) |
272 apply(simp add: cs_dependants_def cs_depend_def cs_waiting_def cs_holding_def) |
272 apply(simp add: cs_dependants_def cs_RAG_def cs_waiting_def cs_holding_def) |
273 apply(simp add: preced_def) |
273 apply(simp add: preced_def) |
274 done |
274 done |
275 |
275 |
276 lemma sch_old_def: |
276 lemma sch_old_def: |
277 "schs (e#s) = (let ps = schs s in |
277 "schs (e#s) = (let ps = schs s in |
303 *} |
303 *} |
304 definition cp :: "state \<Rightarrow> thread \<Rightarrow> precedence" |
304 definition cp :: "state \<Rightarrow> thread \<Rightarrow> precedence" |
305 where "cp s \<equiv> cprec_fun (schs s)" |
305 where "cp s \<equiv> cprec_fun (schs s)" |
306 |
306 |
307 text {* \noindent |
307 text {* \noindent |
308 Functions @{text "holding"}, @{text "waiting"}, @{text "depend"} and |
308 Functions @{text "holding"}, @{text "waiting"}, @{text "RAG"} and |
309 @{text "dependants"} still have the |
309 @{text "dependants"} still have the |
310 same meaning, but redefined so that they no longer depend on the |
310 same meaning, but redefined so that they no longer RAG on the |
311 fictitious {\em waiting queue function} |
311 fictitious {\em waiting queue function} |
312 @{text "wq"}, but on system state @{text "s"}. |
312 @{text "wq"}, but on system state @{text "s"}. |
313 *} |
313 *} |
314 defs (overloaded) |
314 defs (overloaded) |
315 s_holding_abv: |
315 s_holding_abv: |
316 "holding (s::state) \<equiv> holding (wq_fun (schs s))" |
316 "holding (s::state) \<equiv> holding (wq_fun (schs s))" |
317 s_waiting_abv: |
317 s_waiting_abv: |
318 "waiting (s::state) \<equiv> waiting (wq_fun (schs s))" |
318 "waiting (s::state) \<equiv> waiting (wq_fun (schs s))" |
319 s_depend_abv: |
319 s_RAG_abv: |
320 "depend (s::state) \<equiv> depend (wq_fun (schs s))" |
320 "RAG (s::state) \<equiv> RAG (wq_fun (schs s))" |
321 s_dependants_abv: |
321 s_dependants_abv: |
322 "dependants (s::state) \<equiv> dependants (wq_fun (schs s))" |
322 "dependants (s::state) \<equiv> dependants (wq_fun (schs s))" |
323 |
323 |
324 |
324 |
325 text {* |
325 text {* |
332 |
332 |
333 lemma s_waiting_def: |
333 lemma s_waiting_def: |
334 "waiting (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th \<noteq> hd (wq_fun (schs s) cs))" |
334 "waiting (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th \<noteq> hd (wq_fun (schs s) cs))" |
335 by (auto simp:s_waiting_abv wq_def cs_waiting_def) |
335 by (auto simp:s_waiting_abv wq_def cs_waiting_def) |
336 |
336 |
337 lemma s_depend_def: |
337 lemma s_RAG_def: |
338 "depend (s::state) = |
338 "RAG (s::state) = |
339 {(Th th, Cs cs) | th cs. waiting (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding (wq s) th cs}" |
339 {(Th th, Cs cs) | th cs. waiting (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding (wq s) th cs}" |
340 by (auto simp:s_depend_abv wq_def cs_depend_def) |
340 by (auto simp:s_RAG_abv wq_def cs_RAG_def) |
341 |
341 |
342 lemma |
342 lemma |
343 s_dependants_def: |
343 s_dependants_def: |
344 "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (depend (wq s))^+}" |
344 "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (RAG (wq s))^+}" |
345 by (auto simp:s_dependants_abv wq_def cs_dependants_def) |
345 by (auto simp:s_dependants_abv wq_def cs_dependants_def) |
346 |
346 |
347 text {* |
347 text {* |
348 The following function @{text "readys"} calculates the set of ready threads. A thread is {\em ready} |
348 The following function @{text "readys"} calculates the set of ready threads. A thread is {\em ready} |
349 for running if it is a live thread and it is not waiting for any critical resource. |
349 for running if it is a live thread and it is not waiting for any critical resource. |
364 *} |
364 *} |
365 definition holdents :: "state \<Rightarrow> thread \<Rightarrow> cs set" |
365 definition holdents :: "state \<Rightarrow> thread \<Rightarrow> cs set" |
366 where "holdents s th \<equiv> {cs . holding s th cs}" |
366 where "holdents s th \<equiv> {cs . holding s th cs}" |
367 |
367 |
368 lemma holdents_test: |
368 lemma holdents_test: |
369 "holdents s th = {cs . (Cs cs, Th th) \<in> depend s}" |
369 "holdents s th = {cs . (Cs cs, Th th) \<in> RAG s}" |
370 unfolding holdents_def |
370 unfolding holdents_def |
371 unfolding s_depend_def |
371 unfolding s_RAG_def |
372 unfolding s_holding_abv |
372 unfolding s_holding_abv |
373 unfolding wq_def |
373 unfolding wq_def |
374 by (simp) |
374 by (simp) |
375 |
375 |
376 text {* \noindent |
376 text {* \noindent |
401 the request does not form a loop in the current RAG. The latter condition |
401 the request does not form a loop in the current RAG. The latter condition |
402 is set up to avoid deadlock. The condition also reflects our assumption all threads are |
402 is set up to avoid deadlock. The condition also reflects our assumption all threads are |
403 carefully programmed so that deadlock can not happen: |
403 carefully programmed so that deadlock can not happen: |
404 \end{minipage} |
404 \end{minipage} |
405 *} |
405 *} |
406 thread_P: "\<lbrakk>thread \<in> runing s; (Cs cs, Th thread) \<notin> (depend s)^+\<rbrakk> \<Longrightarrow> |
406 thread_P: "\<lbrakk>thread \<in> runing s; (Cs cs, Th thread) \<notin> (RAG s)^+\<rbrakk> \<Longrightarrow> |
407 step s (P thread cs)" | |
407 step s (P thread cs)" | |
408 -- {* |
408 -- {* |
409 \begin{minipage}{0.9\textwidth} |
409 \begin{minipage}{0.9\textwidth} |
410 A thread can release a critical resource @{text "cs"} |
410 A thread can release a critical resource @{text "cs"} |
411 if it is running and holding that resource: |
411 if it is running and holding that resource: |