PrioGDef.thy
changeset 32 e861aff29655
parent 17 105715a0a807
child 33 9b9f2117561f
equal deleted inserted replaced
31:8f026b608378 32:e861aff29655
    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:
   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   depend :: "'b \<Rightarrow> (node \<times> node) set"
   125   dependents :: "'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
   130   the waiting queue of every critical resource is given by a waiting queue 
   130   the waiting queue of every critical resource is given by a waiting queue 
   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 (*>*)
   266           (|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|))"
   266           (|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|))"
   267 
   267 
   268 lemma cpreced_initial: 
   268 lemma cpreced_initial: 
   269   "cpreced (\<lambda> cs. []) [] = (\<lambda>_. (Prc 0 0))"
   269   "cpreced (\<lambda> cs. []) [] = (\<lambda>_. (Prc 0 0))"
   270 apply(simp add: cpreced_def)
   270 apply(simp add: cpreced_def)
   271 apply(simp add: cs_dependents_def cs_depend_def cs_waiting_def cs_holding_def)
   271 apply(simp add: cs_dependants_def cs_depend_def cs_waiting_def cs_holding_def)
   272 apply(simp add: preced_def)
   272 apply(simp add: preced_def)
   273 done
   273 done
   274 
   274 
   275 lemma sch_old_def:
   275 lemma sch_old_def:
   276   "schs (e#s) = (let ps = schs s in 
   276   "schs (e#s) = (let ps = schs s in 
   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) 
   315   "holding (s::state) \<equiv> holding (wq_fun (schs s))"
   315   "holding (s::state) \<equiv> holding (wq_fun (schs s))"
   316   s_waiting_abv: 
   316   s_waiting_abv: 
   317   "waiting (s::state) \<equiv> waiting (wq_fun (schs s))"
   317   "waiting (s::state) \<equiv> waiting (wq_fun (schs s))"
   318   s_depend_abv: 
   318   s_depend_abv: 
   319   "depend (s::state) \<equiv> depend (wq_fun (schs s))"
   319   "depend (s::state) \<equiv> depend (wq_fun (schs s))"
   320   s_dependents_abv: 
   320   s_dependants_abv: 
   321   "dependents (s::state) \<equiv> dependents (wq_fun (schs s))"
   321   "dependants (s::state) \<equiv> dependants (wq_fun (schs s))"
   322 
   322 
   323 
   323 
   324 text {* 
   324 text {* 
   325   The following lemma can be proved easily:
   325   The following lemma can be proved easily:
   326   *}
   326   *}
   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   *}