161 The thread at the head of this list is designated as the thread which is current |
161 The thread at the head of this list is designated as the thread which is current |
162 holding the resrouce, which is slightly different from tradition where |
162 holding the resrouce, which is slightly different from tradition where |
163 all threads in the waiting queue are considered as waiting for the resource. |
163 all threads in the waiting queue are considered as waiting for the resource. |
164 *} |
164 *} |
165 |
165 |
|
166 (* |
166 consts |
167 consts |
167 holding :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
168 holding :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
168 waiting :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
169 waiting :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
169 RAG :: "'b \<Rightarrow> (node \<times> node) set" |
170 RAG :: "'b \<Rightarrow> (node \<times> node) set" |
170 dependants :: "'b \<Rightarrow> thread \<Rightarrow> thread set" |
171 dependants :: "'b \<Rightarrow> thread \<Rightarrow> thread set" |
171 |
172 *) |
172 defs (overloaded) |
173 |
|
174 definition |
173 -- {* |
175 -- {* |
174 \begin{minipage}{0.9\textwidth} |
176 \begin{minipage}{0.9\textwidth} |
175 This meaning of @{text "wq"} is reflected in the following definition of @{text "holding wq th cs"}, |
177 This meaning of @{text "wq"} is reflected in the following definition of |
176 where @{text "holding wq th cs"} means thread @{text "th"} is holding the critical |
178 @{text "holding wq th cs"}, where @{text "holding wq th cs"} means thread |
177 resource @{text "cs"}. This decision is based on @{text "wq"}. |
179 @{text "th"} is holding the critical resource @{text "cs"}. This decision |
178 \end{minipage} |
180 is based on @{text "wq"}. |
179 *} |
181 \end{minipage} |
180 |
182 *} |
181 cs_holding_def: |
183 |
182 "holding wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread = hd (wq cs))" |
184 cs_holding_raw: |
|
185 "holding_raw wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread = hd (wq cs))" |
|
186 |
|
187 |
|
188 definition |
183 -- {* |
189 -- {* |
184 \begin{minipage}{0.9\textwidth} |
190 \begin{minipage}{0.9\textwidth} |
185 In accordance with the definition of @{text "holding wq th cs"}, |
191 In accordance with the definition of @{text "holding wq th cs"}, a thread |
186 a thread @{text "th"} is considered waiting for @{text "cs"} if |
192 @{text "th"} is considered waiting for @{text "cs"} if it is in the {\em |
187 it is in the {\em waiting queue} of critical resource @{text "cs"}, but not at the head. |
193 waiting queue} of critical resource @{text "cs"}, but not at the head. |
188 This is reflected in the definition of @{text "waiting wq th cs"} as follows: |
194 This is reflected in the definition of @{text "waiting wq th cs"} as |
189 \end{minipage} |
195 follows: |
190 *} |
196 \end{minipage} |
191 cs_waiting_def: |
197 *} |
192 "waiting wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread \<noteq> hd (wq cs))" |
198 |
|
199 cs_waiting_raw: |
|
200 "waiting_raw wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread \<noteq> hd (wq cs))" |
|
201 |
|
202 definition |
193 -- {* |
203 -- {* |
194 \begin{minipage}{0.9\textwidth} |
204 \begin{minipage}{0.9\textwidth} |
195 @{text "RAG wq"} generates RAG (a binary relations on @{text "node"}) |
205 @{text "RAG wq"} generates RAG (a binary relations on @{text "node"}) out |
196 out of waiting queues of the system (represented by the @{text "wq"} argument): |
206 of waiting queues of the system (represented by the @{text "wq"} |
197 \end{minipage} |
207 argument): \end{minipage} |
198 *} |
208 *} |
199 cs_RAG_def: |
209 |
200 "RAG (wq::cs \<Rightarrow> thread list) \<equiv> |
210 cs_RAG_raw: |
201 {(Th th, Cs cs) | th cs. waiting wq th cs} \<union> {(Cs cs, Th th) | cs th. holding wq th cs}" |
211 "RAG_raw (wq::cs \<Rightarrow> thread list) \<equiv> |
|
212 {(Th th, Cs cs) | th cs. waiting_raw wq th cs} \<union> {(Cs cs, Th th) | cs th. holding_raw wq th cs}" |
|
213 |
|
214 definition |
202 -- {* |
215 -- {* |
203 \begin{minipage}{0.9\textwidth} |
216 \begin{minipage}{0.9\textwidth} |
204 The following @{text "dependants wq th"} represents the set of threads which are RAGing on |
217 The following @{text "dependants wq th"} represents the set of threads |
205 thread @{text "th"} in Resource Allocation Graph @{text "RAG wq"}. |
218 which are RAGing on thread @{text "th"} in Resource Allocation Graph |
206 Here, "RAGing" means waiting directly or indirectly on the critical resource. |
219 @{text "RAG wq"}. Here, "RAGing" means waiting directly or indirectly on |
207 \end{minipage} |
220 the critical resource. |
208 *} |
221 \end{minipage} |
|
222 *} |
|
223 |
209 cs_dependants_def: |
224 cs_dependants_def: |
210 "dependants (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (RAG wq)^+}" |
225 "dependants_raw (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (RAG_raw wq)^+}" |
211 |
226 |
212 |
227 text {* |
213 text {* \noindent |
228 \noindent The following @{text "cpreced s th"} gives the {\em current |
214 The following |
229 precedence} of thread @{text "th"} under state @{text "s"}. The definition |
215 @{text "cpreced s th"} gives the {\em current precedence} of thread @{text "th"} under |
230 of @{text "cpreced"} reflects the basic idea of Priority Inheritance that |
216 state @{text "s"}. The definition of @{text "cpreced"} reflects the basic idea of |
231 the {\em current precedence} of a thread is the precedence inherited from |
217 Priority Inheritance that the {\em current precedence} of a thread is the precedence |
232 the maximum of all its dependants, i.e. the threads which are waiting |
218 inherited from the maximum of all its dependants, i.e. the threads which are waiting |
233 directly or indirectly waiting for some resources from it. If no such |
219 directly or indirectly waiting for some resources from it. If no such thread exits, |
234 thread exits, @{text "th"}'s {\em current precedence} equals its original |
220 @{text "th"}'s {\em current precedence} equals its original precedence, i.e. |
235 precedence, i.e. @{text "preced th s"}. |
221 @{text "preced th s"}. |
236 *} |
222 *} |
|
223 |
237 |
224 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence" |
238 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence" |
225 where "cpreced wq s = (\<lambda>th. Max ((\<lambda>th'. preced th' s) ` ({th} \<union> dependants wq th)))" |
239 where "cpreced wq s = (\<lambda>th. Max ((\<lambda>th'. preced th' s) ` ({th} \<union> dependants_raw wq th)))" |
226 |
240 |
227 text {* |
241 text {* |
228 Notice that the current precedence (@{text "cpreced"}) of one thread @{text "th"} can be boosted |
242 Notice that the current precedence (@{text "cpreced"}) of one thread |
229 (becoming larger than its own precedence) by those threads in |
243 @{text "th"} can be boosted (becoming larger than its own precedence) by |
230 the @{text "dependants wq th"}-set. If one thread get boosted, we say |
244 those threads in the @{text "dependants wq th"}-set. If one thread get |
231 it inherits the priority (or, more precisely, the precedence) of |
245 boosted, we say it inherits the priority (or, more precisely, the |
232 its dependants. This is how the word "Inheritance" in |
246 precedence) of its dependants. This is how the word "Inheritance" in |
233 Priority Inheritance Protocol comes. |
247 Priority Inheritance Protocol comes. |
234 *} |
248 *} |
235 |
249 |
236 (*<*) |
250 (*<*) |
237 lemma |
251 lemma |
238 cpreced_def2: |
252 cpreced_def2: |
239 "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants wq th})" |
253 "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants_raw wq th})" |
240 unfolding cpreced_def image_def |
254 unfolding cpreced_def image_def |
241 apply(rule eq_reflection) |
255 apply(rule eq_reflection) |
242 apply(rule_tac f="Max" in arg_cong) |
256 apply(rule_tac f="Max" in arg_cong) |
243 by (auto) |
257 by (auto) |
244 (*>*) |
258 (*>*) |
245 |
259 |
246 |
260 |
247 text {* \noindent |
261 text {* |
248 Assuming @{text "qs"} be the waiting queue of a critical resource, |
262 |
249 the following abbreviation "release qs" is the waiting queue after the thread |
263 \noindent Assuming @{text "qs"} be the waiting queue of a critical |
250 holding the resource (which is thread at the head of @{text "qs"}) released |
264 resource, the following abbreviation "release qs" is the waiting queue |
251 the resource: |
265 after the thread holding the resource (which is thread at the head of |
252 *} |
266 @{text "qs"}) released the resource: |
|
267 *} |
|
268 |
253 abbreviation |
269 abbreviation |
254 "release qs \<equiv> case qs of |
270 "release qs \<equiv> case qs of |
255 [] => [] |
271 [] => [] |
256 | (_#qs') => (SOME q. distinct q \<and> set q = set qs')" |
272 | (_#qs') => (SOME q. distinct q \<and> set q = set qs')" |
257 text {* \noindent |
273 |
258 It can be seen from the definition that the thread at the head of @{text "qs"} is removed |
274 text {* |
259 from the return value, and the value @{term "q"} is an reordering of @{text "qs'"}, the |
275 \noindent It can be seen from the definition that the thread at the head |
260 tail of @{text "qs"}. Through this reordering, one of the waiting threads (those in @{text "qs'"} } |
276 of @{text "qs"} is removed from the return value, and the value @{term |
261 is chosen nondeterministically to be the head of the new queue @{text "q"}. |
277 "q"} is an reordering of @{text "qs'"}, the tail of @{text "qs"}. Through |
262 Therefore, this thread is the one who takes over the resource. This is a little better different |
278 this reordering, one of the waiting threads (those in @{text "qs'"} } is |
263 from common sense that the thread who comes the earliest should take over. |
279 chosen nondeterministically to be the head of the new queue @{text "q"}. |
264 The intention of this definition is to show that the choice of which thread to take over the |
280 Therefore, this thread is the one who takes over the resource. This is a |
265 release resource does not affect the correctness of the PIP protocol. |
281 little better different from common sense that the thread who comes the |
266 *} |
282 earliest should take over. The intention of this definition is to show |
267 |
283 that the choice of which thread to take over the release resource does not |
268 text {* |
284 affect the correctness of the PIP protocol. |
269 The data structure used by the operating system for scheduling is referred to as |
285 *} |
270 {\em schedule state}. It is represented as a record consisting of |
286 |
271 a function assigning waiting queue to resources |
287 text {* |
272 (to be used as the @{text "wq"} argument in @{text "holding"}, @{text "waiting"} |
288 The data structure used by the operating system for scheduling is referred |
273 and @{text "RAG"}, etc) and a function assigning precedence to threads: |
289 to as {\em schedule state}. It is represented as a record consisting of a |
|
290 function assigning waiting queue to resources (to be used as the @{text |
|
291 "wq"} argument in @{text "holding"}, @{text "waiting"} and @{text "RAG"}, |
|
292 etc) and a function assigning precedence to threads: |
274 *} |
293 *} |
275 |
294 |
276 record schedule_state = |
295 record schedule_state = |
277 wq_fun :: "cs \<Rightarrow> thread list" -- {* The function assigning waiting queue. *} |
296 wq_fun :: "cs \<Rightarrow> thread list" -- {* The function assigning waiting queue. *} |
278 cprec_fun :: "thread \<Rightarrow> precedence" -- {* The function assigning precedence. *} |
297 cprec_fun :: "thread \<Rightarrow> precedence" -- {* The function assigning precedence. *} |
279 |
298 |
280 text {* \noindent |
299 text {* |
281 The following two abbreviations (@{text "all_unlocked"} and @{text "initial_cprec"}) |
300 \noindent The following two abbreviations (@{text "all_unlocked"} and |
282 are used to set the initial values of the @{text "wq_fun"} @{text "cprec_fun"} fields |
301 @{text "initial_cprec"}) are used to set the initial values of the @{text |
283 respectively of the @{text "schedule_state"} record by the following function @{text "sch"}, |
302 "wq_fun"} @{text "cprec_fun"} fields respectively of the @{text |
284 which is used to calculate the system's {\em schedule state}. |
303 "schedule_state"} record by the following function @{text "sch"}, which is |
285 |
304 used to calculate the system's {\em schedule state}. |
286 Since there is no thread at the very beginning to make request, all critical resources |
305 |
287 are free (or unlocked). This status is represented by the abbreviation |
306 Since there is no thread at the very beginning to make request, all |
288 @{text "all_unlocked"}. |
307 critical resources are free (or unlocked). This status is represented by |
289 *} |
308 the abbreviation @{text "all_unlocked"}. |
|
309 *} |
|
310 |
290 abbreviation |
311 abbreviation |
291 "all_unlocked \<equiv> \<lambda>_::cs. ([]::thread list)" |
312 "all_unlocked \<equiv> \<lambda>_::cs. ([]::thread list)" |
292 |
313 |
293 |
314 |
294 text {* \noindent |
315 text {* \noindent |
411 @{text "dependants"} still have the |
432 @{text "dependants"} still have the |
412 same meaning, but redefined so that they no longer RAG on the |
433 same meaning, but redefined so that they no longer RAG on the |
413 fictitious {\em waiting queue function} |
434 fictitious {\em waiting queue function} |
414 @{text "wq"}, but on system state @{text "s"}. |
435 @{text "wq"}, but on system state @{text "s"}. |
415 *} |
436 *} |
416 defs (overloaded) |
437 |
|
438 |
|
439 definition |
417 s_holding_abv: |
440 s_holding_abv: |
418 "holding (s::state) \<equiv> holding (wq_fun (schs s))" |
441 "holding (s::state) \<equiv> holding_raw (wq_fun (schs s))" |
|
442 |
|
443 definition |
419 s_waiting_abv: |
444 s_waiting_abv: |
420 "waiting (s::state) \<equiv> waiting (wq_fun (schs s))" |
445 "waiting (s::state) \<equiv> waiting_raw (wq_fun (schs s))" |
|
446 |
|
447 definition |
421 s_RAG_abv: |
448 s_RAG_abv: |
422 "RAG (s::state) \<equiv> RAG (wq_fun (schs s))" |
449 "RAG (s::state) \<equiv> RAG_raw (wq_fun (schs s))" |
|
450 |
|
451 definition |
423 s_dependants_abv: |
452 s_dependants_abv: |
424 "dependants (s::state) \<equiv> dependants (wq_fun (schs s))" |
453 "dependants (s::state) \<equiv> dependants_raw (wq_fun (schs s))" |
425 |
454 |
426 |
455 |
427 text {* |
456 text {* |
428 The following lemma can be proved easily, and the meaning is obvious. |
457 The following lemma can be proved easily, and the meaning is obvious. |
429 *} |
458 *} |
|
459 |
430 lemma |
460 lemma |
431 s_holding_def: |
461 s_holding_def: |
432 "holding (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th = hd (wq_fun (schs s) cs))" |
462 "holding (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th = hd (wq_fun (schs s) cs))" |
433 by (auto simp:s_holding_abv wq_def cs_holding_def) |
463 by (auto simp:s_holding_abv wq_def cs_holding_raw) |
434 |
464 |
435 lemma s_waiting_def: |
465 lemma s_waiting_def: |
436 "waiting (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th \<noteq> hd (wq_fun (schs s) cs))" |
466 "waiting (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th \<noteq> hd (wq_fun (schs s) cs))" |
437 by (auto simp:s_waiting_abv wq_def cs_waiting_def) |
467 by (auto simp:s_waiting_abv wq_def cs_waiting_raw) |
438 |
468 |
439 lemma s_RAG_def: |
469 lemma s_RAG_def: |
440 "RAG (s::state) = |
470 "RAG (s::state) = |
441 {(Th th, Cs cs) | th cs. waiting (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding (wq s) th cs}" |
471 {(Th th, Cs cs) | th cs. waiting_raw (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding_raw (wq s) th cs}" |
442 by (auto simp:s_RAG_abv wq_def cs_RAG_def) |
472 by (auto simp:s_RAG_abv wq_def cs_RAG_raw) |
443 |
473 |
444 lemma |
474 lemma |
445 s_dependants_def: |
475 s_dependants_def: |
446 "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (RAG (wq s))^+}" |
476 "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (RAG_raw (wq s))^+}" |
447 by (auto simp:s_dependants_abv wq_def cs_dependants_def) |
477 by (auto simp:s_dependants_abv wq_def cs_dependants_def) |
448 |
478 |
449 text {* |
479 text {* |
450 The following function @{text "readys"} calculates the set of ready threads. A thread is {\em ready} |
480 The following function @{text "readys"} calculates the set of ready |
451 for running if it is a live thread and it is not waiting for any critical resource. |
481 threads. A thread is {\em ready} for running if it is a live thread and it |
452 *} |
482 is not waiting for any critical resource. |
|
483 *} |
|
484 |
453 definition readys :: "state \<Rightarrow> thread set" |
485 definition readys :: "state \<Rightarrow> thread set" |
454 where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waiting s th cs)}" |
486 where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waiting s th cs)}" |
455 |
487 |
456 text {* \noindent |
488 text {* |
457 The following function @{text "runing"} calculates the set of running thread, which is the ready |
489 \noindent The following function @{text "runing"} calculates the set of |
458 thread with the highest precedence. |
490 running thread, which is the ready thread with the highest precedence. |
459 *} |
491 *} |
|
492 |
460 definition runing :: "state \<Rightarrow> thread set" |
493 definition runing :: "state \<Rightarrow> thread set" |
461 where "runing s \<equiv> {th . th \<in> readys s \<and> cp s th = Max ((cp s) ` (readys s))}" |
494 where "runing s \<equiv> {th . th \<in> readys s \<and> cp s th = Max ((cp s) ` (readys s))}" |
462 |
495 |
463 text {* \noindent |
496 text {* |
464 Notice that the definition of @{text "running"} reflects the preemptive scheduling strategy, |
497 \noindent Notice that the definition of @{text "running"} reflects the |
465 because, if the @{text "running"}-thread (the one in @{text "runing"} set) |
498 preemptive scheduling strategy, because, if the @{text "running"}-thread |
466 lowered its precedence by resetting its own priority to a lower |
499 (the one in @{text "runing"} set) lowered its precedence by resetting its |
467 one, it will lose its status of being the max in @{text "ready"}-set and be superseded. |
500 own priority to a lower one, it will lose its status of being the max in |
468 *} |
501 @{text "ready"}-set and be superseded. |
469 |
502 *} |
470 text {* \noindent |
503 |
471 The following function @{text "holdents s th"} returns the set of resources held by thread |
504 text {* |
472 @{text "th"} in state @{text "s"}. |
505 \noindent The following function @{text "holdents s th"} returns the set |
473 *} |
506 of resources held by thread @{text "th"} in state @{text "s"}. *} |
474 definition holdents :: "state \<Rightarrow> thread \<Rightarrow> cs set" |
507 |
|
508 |
|
509 definition holdents :: "state \<Rightarrow> thread \<Rightarrow> cs set" |
475 where "holdents s th \<equiv> {cs . holding s th cs}" |
510 where "holdents s th \<equiv> {cs . holding s th cs}" |
476 |
511 |
477 lemma holdents_test: |
512 lemma holdents_test: |
478 "holdents s th = {cs . (Cs cs, Th th) \<in> RAG s}" |
513 "holdents s th = {cs . (Cs cs, Th th) \<in> RAG s}" |
479 unfolding holdents_def |
514 unfolding holdents_def |