66 "threads (e#s) = threads s" |
66 "threads (e#s) = threads s" |
67 text {* \noindent |
67 text {* \noindent |
68 Functions such as @{text "threads"}, which extract information out of system states, are called |
68 Functions such as @{text "threads"}, which extract information out of system states, are called |
69 {\em observing functions}. A series of observing functions will be defined in the sequel in order to |
69 {\em observing functions}. A series of observing functions will be defined in the sequel in order to |
70 model the protocol. |
70 model the protocol. |
71 Observing function @{text "original_priority"} calculates |
71 Observing function @{text "priority"} calculates |
72 the {\em original priority} of thread @{text "th"} in state @{text "s"}, expressed as |
72 the {\em original priority} of thread @{text "th"} in state @{text "s"}, expressed as |
73 : @{text "original_priority th s" }. The {\em original priority} is the priority |
73 : @{text "priority th s" }. The {\em original priority} is the priority |
74 assigned to a thread when it is created or when it is reset by system call |
74 assigned to a thread when it is created or when it is reset by system call |
75 @{text "Set thread priority"}. |
75 @{text "Set thread priority"}. |
76 *} |
76 *} |
77 |
77 |
78 fun original_priority :: "thread \<Rightarrow> state \<Rightarrow> priority" |
78 fun priority :: "thread \<Rightarrow> state \<Rightarrow> priority" |
79 where |
79 where |
80 -- {* @{text "0"} is assigned to threads which have never been created: *} |
80 -- {* @{text "0"} is assigned to threads which have never been created: *} |
81 "original_priority thread [] = 0" | |
81 "priority thread [] = 0" | |
82 "original_priority thread (Create thread' prio#s) = |
82 "priority thread (Create thread' prio#s) = |
83 (if thread' = thread then prio else original_priority thread s)" | |
83 (if thread' = thread then prio else priority thread s)" | |
84 "original_priority thread (Set thread' prio#s) = |
84 "priority thread (Set thread' prio#s) = |
85 (if thread' = thread then prio else original_priority thread s)" | |
85 (if thread' = thread then prio else priority thread s)" | |
86 "original_priority thread (e#s) = original_priority thread s" |
86 "priority thread (e#s) = priority thread s" |
87 |
87 |
88 text {* |
88 text {* |
89 \noindent |
89 \noindent |
90 In the following, |
90 In the following, |
91 @{text "birthtime th s"} is the time when thread @{text "th"} is created, |
91 @{text "last_set th s"} is the time when thread @{text "th"} is created, |
92 observed from state @{text "s"}. |
92 observed from state @{text "s"}. |
93 The time in the system is measured by the number of events happened so far since the very beginning. |
93 The time in the system is measured by the number of events happened so far since the very beginning. |
94 *} |
94 *} |
95 fun birthtime :: "thread \<Rightarrow> state \<Rightarrow> nat" |
95 fun last_set :: "thread \<Rightarrow> state \<Rightarrow> nat" |
96 where |
96 where |
97 "birthtime thread [] = 0" | |
97 "last_set thread [] = 0" | |
98 "birthtime thread ((Create thread' prio)#s) = |
98 "last_set thread ((Create thread' prio)#s) = |
99 (if (thread = thread') then length s else birthtime thread s)" | |
99 (if (thread = thread') then length s else last_set thread s)" | |
100 "birthtime thread ((Set thread' prio)#s) = |
100 "last_set thread ((Set thread' prio)#s) = |
101 (if (thread = thread') then length s else birthtime thread s)" | |
101 (if (thread = thread') then length s else last_set thread s)" | |
102 "birthtime thread (e#s) = birthtime thread s" |
102 "last_set thread (_#s) = last_set thread s" |
103 |
103 |
104 text {* |
104 text {* |
105 \noindent |
105 \noindent |
106 The {\em precedence} is a notion derived from {\em priority}, where the {\em precedence} of |
106 The {\em precedence} is a notion derived from {\em priority}, where the {\em precedence} of |
107 a thread is the combination of its {\em original priority} and {\em birth time}. The intention is |
107 a thread is the combination of its {\em original priority} and {\em birth time}. The intention is |
108 to discriminate threads with the same priority by giving threads whose priority |
108 to discriminate threads with the same priority by giving threads whose priority |
109 is assigned earlier higher precedences, becasue such threads are more urgent to finish. |
109 is assigned earlier higher precedences, becasue such threads are more urgent to finish. |
110 This explains the following definition: |
110 This explains the following definition: |
111 *} |
111 *} |
112 definition preced :: "thread \<Rightarrow> state \<Rightarrow> precedence" |
112 definition preced :: "thread \<Rightarrow> state \<Rightarrow> precedence" |
113 where "preced thread s \<equiv> Prc (original_priority thread s) (birthtime thread s)" |
113 where "preced thread s \<equiv> Prc (priority thread s) (last_set thread s)" |
114 |
114 |
115 |
115 |
116 text {* |
116 text {* |
117 \noindent |
117 \noindent |
118 A number of important notions are defined here: |
118 A number of important notions are defined here: |
160 cs_depend_def: |
160 cs_depend_def: |
161 "depend (wq::cs \<Rightarrow> thread list) \<equiv> |
161 "depend (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 "dependents 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 depending on |
166 thread @{text "th"} in Resource Allocation Graph @{text "depend wq"}: |
166 thread @{text "th"} in Resource Allocation Graph @{text "depend wq"}: |
167 \end{minipage} |
167 \end{minipage} |
168 *} |
168 *} |
169 cs_dependents_def: |
169 cs_dependants_def: |
170 "dependents (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> (depend 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 |
183 text {* \noindent |
183 text {* \noindent |
184 The following |
184 The following |
185 @{text "cpreced s th"} gives the {\em current precedence} of thread @{text "th"} under |
185 @{text "cpreced s th"} gives the {\em current precedence} of thread @{text "th"} under |
186 state @{text "s"}. The definition of @{text "cpreced"} reflects the basic idea of |
186 state @{text "s"}. The definition of @{text "cpreced"} reflects the basic idea of |
187 Priority Inheritance that the {\em current precedence} of a thread is the precedence |
187 Priority Inheritance that the {\em current precedence} of a thread is the precedence |
188 inherited from the maximum of all its dependents, i.e. the threads which are waiting |
188 inherited from the maximum of all its dependants, i.e. the threads which are waiting |
189 directly or indirectly waiting for some resources from it. If no such thread exits, |
189 directly or indirectly waiting for some resources from it. If no such thread exits, |
190 @{text "th"}'s {\em current precedence} equals its original precedence, i.e. |
190 @{text "th"}'s {\em current precedence} equals its original precedence, i.e. |
191 @{text "preced th s"}. |
191 @{text "preced th s"}. |
192 *} |
192 *} |
193 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence" |
193 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence" |
194 where "cpreced wq s = (\<lambda> th. Max ((\<lambda> th. preced th s) ` ({th} \<union> dependents wq th)))" |
194 where "cpreced wq s = (\<lambda> th. Max ((\<lambda> th. preced th s) ` ({th} \<union> dependants wq th)))" |
195 |
195 |
196 (*<*) |
196 (*<*) |
197 lemma |
197 lemma |
198 cpreced_def2: |
198 cpreced_def2: |
199 "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependents wq th})" |
199 "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants wq th})" |
200 unfolding cpreced_def image_def |
200 unfolding cpreced_def image_def |
201 apply(rule eq_reflection) |
201 apply(rule eq_reflection) |
202 apply(rule_tac f="Max" in arg_cong) |
202 apply(rule_tac f="Max" in arg_cong) |
203 by (auto) |
203 by (auto) |
204 (*>*) |
204 (*>*) |
303 definition cp :: "state \<Rightarrow> thread \<Rightarrow> precedence" |
303 definition cp :: "state \<Rightarrow> thread \<Rightarrow> precedence" |
304 where "cp s \<equiv> cprec_fun (schs s)" |
304 where "cp s \<equiv> cprec_fun (schs s)" |
305 |
305 |
306 text {* \noindent |
306 text {* \noindent |
307 Functions @{text "holding"}, @{text "waiting"}, @{text "depend"} and |
307 Functions @{text "holding"}, @{text "waiting"}, @{text "depend"} and |
308 @{text "dependents"} still have the |
308 @{text "dependants"} still have the |
309 same meaning, but redefined so that they no longer depend on the |
309 same meaning, but redefined so that they no longer depend on the |
310 fictitious {\em waiting queue function} |
310 fictitious {\em waiting queue function} |
311 @{text "wq"}, but on system state @{text "s"}. |
311 @{text "wq"}, but on system state @{text "s"}. |
312 *} |
312 *} |
313 defs (overloaded) |
313 defs (overloaded) |
337 "depend (s::state) = |
337 "depend (s::state) = |
338 {(Th th, Cs cs) | th cs. waiting (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding (wq s) th cs}" |
338 {(Th th, Cs cs) | th cs. waiting (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding (wq s) th cs}" |
339 by (auto simp:s_depend_abv wq_def cs_depend_def) |
339 by (auto simp:s_depend_abv wq_def cs_depend_def) |
340 |
340 |
341 lemma |
341 lemma |
342 s_dependents_def: |
342 s_dependants_def: |
343 "dependents (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (depend (wq s))^+}" |
343 "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (depend (wq s))^+}" |
344 by (auto simp:s_dependents_abv wq_def cs_dependents_def) |
344 by (auto simp:s_dependants_abv wq_def cs_dependants_def) |
345 |
345 |
346 text {* |
346 text {* |
347 The following function @{text "readys"} calculates the set of ready threads. A thread is {\em ready} |
347 The following function @{text "readys"} calculates the set of ready threads. A thread is {\em ready} |
348 for running if it is a live thread and it is not waiting for any critical resource. |
348 for running if it is a live thread and it is not waiting for any critical resource. |
349 *} |
349 *} |