Journal/Paper.thy
changeset 191 fdba35b422a0
parent 190 312497c6d6b9
child 192 f933a8ad24e5
equal deleted inserted replaced
190:312497c6d6b9 191:fdba35b422a0
    76   priorities this property can be violated. For this let $L$ be in the
    76   priorities this property can be violated. For this let $L$ be in the
    77   possession of a lock for a resource that $H$ also needs. $H$ must
    77   possession of a lock for a resource that $H$ also needs. $H$ must
    78   therefore wait for $L$ to exit the critical section and release this
    78   therefore wait for $L$ to exit the critical section and release this
    79   lock. The problem is that $L$ might in turn be blocked by any thread
    79   lock. The problem is that $L$ might in turn be blocked by any thread
    80   with priority $M$, and so $H$ sits there potentially waiting
    80   with priority $M$, and so $H$ sits there potentially waiting
    81   indefinitely. Since $H$ is blocked by threads with lower priorities,
    81   indefinitely (consider the case where threads with propority $M$
    82   the problem is called Priority Inversion. It was first described in
    82   continously need to be processed). Since $H$ is blocked by threads
    83   \cite{Lampson80} in the context of the Mesa programming language
    83   with lower priorities, the problem is called Priority Inversion. It
    84   designed for concurrent programming.
    84   was first described in \cite{Lampson80} in the context of the Mesa
       
    85   programming language designed for concurrent programming.
    85  
    86  
    86   If the problem of Priority Inversion is ignored, real-time systems
    87   If the problem of Priority Inversion is ignored, real-time systems
    87   can become unpredictable and resulting bugs can be hard to diagnose.
    88   can become unpredictable and resulting bugs can be hard to diagnose.
    88   The classic example where this happened is the software that
    89   The classic example where this happened is the software that
    89   controlled the Mars Pathfinder mission in 1997 \cite{Reeves98}.  On
    90   controlled the Mars Pathfinder mission in 1997 \cite{Reeves98}.  On
   319   \begin{isabelle}\ \ \ \ \ %%%
   320   \begin{isabelle}\ \ \ \ \ %%%
   320   \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l}
   321   \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l}
   321   \isacommand{datatype} event 
   322   \isacommand{datatype} event 
   322   & @{text "="} & @{term "Create thread priority\<iota>"}\\
   323   & @{text "="} & @{term "Create thread priority\<iota>"}\\
   323   & @{text "|"} & @{term "Exit thread"} \\
   324   & @{text "|"} & @{term "Exit thread"} \\
   324   & @{text "|"} & @{term "Set thread priority\<iota>"} & {\rm reset of the priority for} @{text thread}\\
   325   & @{text "|"} & @{term "Set thread priority\<iota>"} & 
       
   326   @{text thread} {\rm resets its own priority} \\
   325   & @{text "|"} & @{term "P thread cs"} & {\rm request of resource} @{text "cs"} {\rm by} @{text "thread"}\\
   327   & @{text "|"} & @{term "P thread cs"} & {\rm request of resource} @{text "cs"} {\rm by} @{text "thread"}\\
   326   & @{text "|"} & @{term "V thread cs"} & {\rm release of resource} @{text "cs"} {\rm by} @{text "thread"}
   328   & @{text "|"} & @{term "V thread cs"} & {\rm release of resource} @{text "cs"} {\rm by} @{text "thread"}
   327   \end{tabular}}
   329   \end{tabular}}
   328   \end{isabelle}
   330   \end{isabelle}
   329 
   331 
   410     @{thm (rhs) actor.simps(3)}\\
   412     @{thm (rhs) actor.simps(3)}\\
   411   \end{tabular}}
   413   \end{tabular}}
   412   \end{isabelle}
   414   \end{isabelle}
   413 
   415 
   414   \noindent
   416   \noindent
   415   This allows us to define what actions a set of threads @{text ths} might
   417   This allows us to filter out the actions a set of threads @{text ths} 
   416   perform in a list of events @{text s}, namely
   418   perform in a list of events @{text s}, namely
   417 
   419 
   418   \begin{isabelle}\ \ \ \ \ %%%
   420   \begin{isabelle}\ \ \ \ \ %%%
   419   @{thm actions_of_def[where ?s="s" and ?ths="ths", THEN eq_reflection]}.
   421   @{thm actions_of_def[where ?s="s" and ?ths="ths", THEN eq_reflection]}.
   420   \end{isabelle}
   422   \end{isabelle}
   435   \begin{isabelle}\ \ \ \ \ %%%
   437   \begin{isabelle}\ \ \ \ \ %%%
   436   @{abbrev "preceds ths s"}
   438   @{abbrev "preceds ths s"}
   437   \end{isabelle}
   439   \end{isabelle}
   438 
   440 
   439   \noindent
   441   \noindent
   440   for the set of precedences of threads @{text ths} in state @{text s}.
   442   for the precedences of a set of threads @{text ths} in state @{text s}.
   441   The point of precedences is to schedule threads not according to priorities (because what should
   443   The point of precedences is to schedule threads not according to priorities (because what should
   442   we do in case two threads have the same priority), but according to precedences. 
   444   we do in case two threads have the same priority), but according to precedences. 
   443   Precedences allow us to always discriminate between two threads with equal priority by 
   445   Precedences allow us to always discriminate between two threads with equal priority by 
   444   taking into account the time when the priority was last set. We order precedences so 
   446   taking into account the time when the priority was last set. We order precedences so 
   445   that threads with the same priority get a higher precedence if their priority has been 
   447   that threads with the same priority get a higher precedence if their priority has been 
   482   @{thm waiting_raw_def[where thread="th"]}
   484   @{thm waiting_raw_def[where thread="th"]}
   483   \end{tabular}
   485   \end{tabular}
   484   \end{isabelle}
   486   \end{isabelle}
   485 
   487 
   486   \noindent
   488   \noindent
   487   In this definition we assume @{text "set"} converts a list into a set.
   489   In this definition we assume that @{text "set"} converts a list into a set.
   488   Note that in the first definition the condition about @{text "th \<in> set (wq cs)"} does not follow
   490   Note that in the first definition the condition about @{text "th \<in> set (wq cs)"} does not follow
   489   from @{text "th = hd (set (wq cs))"}, since the head of an empty list is undefined in Isabelle/HOL. 
   491   from @{text "th = hd (set (wq cs))"}, since the head of an empty list is undefined in Isabelle/HOL. 
   490   At the beginning, that is in the state where no thread is created yet, 
   492   At the beginning, that is in the state where no thread is created yet, 
   491   the waiting queue function will be the function that returns the
   493   the waiting queue function will be the function that returns the
   492   empty list for every resource.
   494   empty list for every resource.
   621   resource that is locked already, then the thread is blocked and
   623   resource that is locked already, then the thread is blocked and
   622   cannot ask for another resource.  Clearly, also every resource can
   624   cannot ask for another resource.  Clearly, also every resource can
   623   only have at most one outgoing holding edge---indicating that the
   625   only have at most one outgoing holding edge---indicating that the
   624   resource is locked. So if the @{text "RAG"} is well-founded and
   626   resource is locked. So if the @{text "RAG"} is well-founded and
   625   finite, we can always start at a thread waiting for a resource and
   627   finite, we can always start at a thread waiting for a resource and
   626   ``chase'' outgoing arrows leading to a single root of a tree.
   628   ``chase'' outgoing arrows leading to a single root of a tree,
       
   629   which must be a ready thread.
   627   
   630   
   628   The use of relations for representing @{text RAG}s allows us to
   631   The use of relations for representing @{text RAG}s allows us to
   629   conveniently define the \emph{Thread Dependants Graph} (TDG):
   632   conveniently define the \emph{Thread Dependants Graph} (TDG):
   630 
   633 
   631   \begin{isabelle}\ \ \ \ \ %%%
   634   \begin{isabelle}\ \ \ \ \ %%%
   632   @{thm tG_raw_def}\\
   635   @{thm tG_raw_def}\\
   633   \mbox{}\hfill\numbered{dependants}
   636   \mbox{}\hfill\numbered{dependants}
   634   \end{isabelle}
   637   \end{isabelle}
   635 
   638 
   636   \noindent This definition represents all threads in a @{text RAG} that wait
   639   \noindent This definition is the relation that one thread is waiting for
   637   for a thread to release a resource, but the corresponding 
   640   another to release a resource, but the corresponding 
   638   resource is ``hidden''. 
   641   resource is ``hidden''. 
   639   In Figure~\ref{RAGgraph} this means the @{text TDG} connects @{text "th\<^sub>0"} with
   642   In Figure~\ref{RAGgraph} this means the @{text TDG} connects 
   640   @{text "th\<^sub>1"} and @{text "th\<^sub>2"}, which both wait for
   643   @{text "th\<^sub>1"} and @{text "th\<^sub>2"} to @{text "th\<^sub>0"}, which both wait for
   641   resource @{text "cs\<^sub>1"}; and @{text "th\<^sub>2"} with @{text "th\<^sub>3"}, which
   644   resource @{text "cs\<^sub>1"} to be released; and @{text "th\<^sub>3"} to @{text "th\<^sub>2"}, which
   642   cannot make any progress unless @{text "th\<^sub>2"} makes progress. 
   645   cannot make any progress unless @{text "th\<^sub>2"} makes progress. 
   643   Similarly for the other threads.
   646   Similarly for the other threads.
   644   If
   647   If
   645   there is a circle of dependencies in a @{text RAG} (and thus @{text TDG}), then clearly we have a
   648   there is a circle of dependencies in a @{text RAG} (and thus @{text TDG}), then clearly we have a
   646   deadlock. Therefore when a thread requests a resource, we must
   649   deadlock. Therefore when a thread requests a resource, we must
   647   ensure that the resulting @{text RAG} and @{text TDG} are not circular. In practice, the
   650   ensure that the resulting @{text RAG} and @{text TDG} are not circular. In practice, the
   648   programmer has to ensure this. Our model will enforce that critical 
   651   programmer has to ensure this. Our model will enforce that critical 
   649   resources can only be requested provided no circularity can arise.
   652   resources can only be requested provided no circularity can arise (but 
       
   653   they can overlap, see Fig~\ref{overlap}).
   650 
   654 
   651   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   655   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   652   state @{text s}. It is defined as
   656   state @{text s}. It is defined as
   653 
   657 
   654   \begin{isabelle}\ \ \ \ \ %%%
   658   \begin{isabelle}\ \ \ \ \ %%%
   660   While the precedence @{term prec} of any
   664   While the precedence @{term prec} of any
   661   thread is determined statically (for example when the thread is
   665   thread is determined statically (for example when the thread is
   662   created), the point of the current precedence is to dynamically
   666   created), the point of the current precedence is to dynamically
   663   increase this precedence, if needed according to PIP. Therefore the
   667   increase this precedence, if needed according to PIP. Therefore the
   664   current precedence of @{text th} is given as the maximum of the
   668   current precedence of @{text th} is given as the maximum of the
   665   precedence of @{text th} \emph{and} all threads in its subtree. Since the notion of current precedence is defined as the 
   669   precedences of all threads in its subtree (which includes by definition 
       
   670   @{text th} itself). Since the notion of current precedence is defined as the 
   666   transitive closure of the dependent
   671   transitive closure of the dependent
   667   threads in the @{text TDG}, we deal correctly with the problem in the informal
   672   threads in the @{text TDG}, we deal correctly with the problem in the informal
   668   algorithm by Sha et al.~\cite{Sha90} where a priority of a thread is
   673   algorithm by Sha et al.~\cite{Sha90} where a priority of a thread is
   669   lowered prematurely (see Introduction). We again introduce an abbreviation for current
   674   lowered prematurely (see Introduction). We again introduce an abbreviation for current
   670   precedeces of a set of threads, written @{text "cprecs wq s ths"}.
   675   precedeces of a set of threads, written @{text "cprecs wq s ths"}.
   872 
   877 
   873   \begin{center}
   878   \begin{center}
   874   @{thm[mode=Rule] thread_set[where thread=th]}
   879   @{thm[mode=Rule] thread_set[where thread=th]}
   875   \end{center}
   880   \end{center}
   876 
   881 
   877   \noindent If a thread wants to lock a resource, then the thread
   882   \noindent This is because the @{text Set} event is for a thread to change
       
   883   its \emph{own} priority---therefore it must be running.
       
   884 
       
   885   If a thread wants to lock a resource, then the thread
   878   needs to be running and also we have to make sure that the resource
   886   needs to be running and also we have to make sure that the resource
   879   lock does not lead to a cycle in the RAG (the prurpose of the second
   887   lock does not lead to a cycle in the RAG (the prurpose of the second
   880   premise in the rule below). In practice, ensuring the latter is the
   888   premise in the rule below). In practice, ensuring the latter is the
   881   responsibility of the programmer.  In our formal model we brush
   889   responsibility of the programmer.  In our formal model we brush
   882   aside these problematic cases in order to be able to make some
   890   aside these problematic cases in order to be able to make some
   916   \end{tabular}
   924   \end{tabular}
   917   \end{center}
   925   \end{center}
   918 
   926 
   919   \noindent
   927   \noindent
   920   This completes our formal model of PIP. In the next section we present
   928   This completes our formal model of PIP. In the next section we present
   921   a series of desirable properties derived from our model of PIP. This can
   929   a series of desirable properties derived from this model of PIP. This can
   922   be regarded as a validation of the correctness of our model.
   930   be regarded as a validation of the correctness of our model.
   923 *}
   931 *}
   924 
   932 
   925 (*
   933 (*
   926 section {* Preliminaries *}
   934 section {* Preliminaries *}
  1021   highest precedence; we show that in every future state (denoted by
  1029   highest precedence; we show that in every future state (denoted by
  1022   @{text "s' @ s"}) in which @{text th} is still alive, either @{text
  1030   @{text "s' @ s"}) in which @{text th} is still alive, either @{text
  1023   th} is running or it is blocked by a thread that was alive in the
  1031   th} is running or it is blocked by a thread that was alive in the
  1024   state @{text s} and was waiting for or in the possession of a lock
  1032   state @{text s} and was waiting for or in the possession of a lock
  1025   in @{text s}. Since in @{text s}, as in every state, the set of
  1033   in @{text s}. Since in @{text s}, as in every state, the set of
  1026   alive threads is finite, @{text th} can only be blocked a finite
  1034   alive threads is finite, @{text th} can only be blocked by a finite
  1027   number of threads.  We will actually prove a
  1035   number of threads.  We will actually prove a
  1028   stronger statement where we also provide the current precedence of
  1036   stronger statement where we also provide the current precedence of
  1029   the blocking thread. 
  1037   the blocking thread. 
  1030 
  1038 
  1031   However, the theorem we are going to prove hinges upon a number of
  1039   However, the theorem we are going to prove hinges upon a number of
  1057   \end{tabular}
  1065   \end{tabular}
  1058   \end{isabelle}
  1066   \end{isabelle}
  1059   \end{quote}
  1067   \end{quote}
  1060   
  1068   
  1061   \begin{quote}
  1069   \begin{quote}
  1062   {\bf Assumptions on the events in {\boldmath@{text "s'"}:}} We want to prove that @{text th} cannot
  1070   {\bf Assumptions on the events in {\boldmath@{text "s'"}:}} 
  1063   be blocked indefinitely. Of course this can happen if threads with higher priority
  1071   %We want to prove that @{text th} cannot
  1064   than @{text th} are continuously created in @{text s'}. Therefore we have to assume that  
  1072   %be blocked indefinitely. Of course this can happen if threads with higher priority
       
  1073   %than @{text th} are continuously created in @{text s'}. 
       
  1074   To make sure @{text th} has the highest precedence we have to assume that  
  1065   events in @{text s'} can only create (respectively set) threads with equal or lower 
  1075   events in @{text s'} can only create (respectively set) threads with equal or lower 
  1066   priority than @{text prio} of @{text th}. We also need to assume that the
  1076   priority than @{text prio} of @{text th}. For the same reason, we also need to assume that the
  1067   priority of @{text "th"} does not get reset and all other reset priorities are either
  1077   priority of @{text "th"} does not get reset and all other reset priorities are either
  1068   less or equal. Moreover, we assume  that @{text th} does
  1078   less or equal. Moreover, we assume  that @{text th} does
  1069   not get ``exited'' in @{text "s'"}. This can be ensured by assuming the following three implications. 
  1079   not get ``exited'' in @{text "s'"}. This can be ensured by assuming the following three implications. 
  1070   \begin{isabelle}\ \ \ \ \ %%%
  1080   \begin{isabelle}\ \ \ \ \ %%%
  1071   \begin{tabular}{l}
  1081   \begin{tabular}{l}
  1149 
  1159 
  1150   \begin{lemma}\label{notdetached}
  1160   \begin{lemma}\label{notdetached}
  1151   If @{term "th' \<in> running (s' @ s)"} and @{term "th \<noteq> th'"} then @{term "\<not>detached s th'"}.
  1161   If @{term "th' \<in> running (s' @ s)"} and @{term "th \<noteq> th'"} then @{term "\<not>detached s th'"}.
  1152   \end{lemma}
  1162   \end{lemma}
  1153 
  1163 
  1154   \begin{proof} Let us assume @{text "th'"} is detached in state
  1164   \begin{proof} Let us assume otherwise, that is @{text "th'"} is detached in state
  1155   @{text "s"}, then, according to the definition of detached, @{text
  1165   @{text "s"}, then, according to the definition of detached, @{text
  1156   "th’"} does not hold or wait for any resource. Hence the @{text
  1166   "th’"} does not hold or wait for any resource. Hence the @{text
  1157   cp}-value of @{text "th'"} in @{text s} is not boosted, that is
  1167   cp}-value of @{text "th'"} in @{text s} is not boosted, that is
  1158   @{term "cp s th' = prec th' s"}, and is therefore lower than the
  1168   @{term "cp s th' = prec th' s"}, and is therefore lower than the
  1159   precedence (as well as the @{text "cp"}-value) of @{term "th"}. This
  1169   precedence (as well as the @{text "cp"}-value) of @{term "th"}. This
  1589   Like in the work by Sha et al.~our result in Thm 1 does not yet
  1599   Like in the work by Sha et al.~our result in Thm 1 does not yet
  1590   guarantee the absence of indefinite Priority Inversion. For this we
  1600   guarantee the absence of indefinite Priority Inversion. For this we
  1591   further need the property that every thread gives up its resources
  1601   further need the property that every thread gives up its resources
  1592   after a finite amount of time. We found that this property is not so
  1602   after a finite amount of time. We found that this property is not so
  1593   straightforward to formalise in our model. There are mainly two
  1603   straightforward to formalise in our model. There are mainly two
  1594   reasons for this: First, we do not specify what ``running'' the code
  1604   reasons for this: First, we do not specify what ``running the code''
  1595   of a thread means, for example by giving an operational semantics
  1605   of a thread means, for example by giving an operational semantics
  1596   for machine instructions. Therefore we cannot characterise what are
  1606   for machine instructions. Therefore we cannot characterise what are
  1597   ``good'' programs that contain for every locking request for a
  1607   ``good'' programs that contain for every locking request for a
  1598   resource also a corresponding unlocking request.  Second, we need to
  1608   resource also a corresponding unlocking request.  Second, we need to
  1599   distinghish between a thread that ``just'' locks a resource for a
  1609   distinghish between a thread that ``just'' locks a resource for a
  1616 
  1626 
  1617   What we will establish in this section is that there can only be a
  1627   What we will establish in this section is that there can only be a
  1618   finite number of states after state @{term s} in which the thread
  1628   finite number of states after state @{term s} in which the thread
  1619   @{term th} is blocked (recall for this that a state is a list of
  1629   @{term th} is blocked (recall for this that a state is a list of
  1620   events).  For this finiteness bound to exist, Sha et al.~informally
  1630   events).  For this finiteness bound to exist, Sha et al.~informally
  1621   make two assumtions: first, there is a finite pool of threads
  1631   make two assumptions: first, there is a finite pool of threads
  1622   (active or hibernating) and second, each of them giving up its
  1632   (active or hibernating) and second, each of them giving up its
  1623   resources after a finite amount of time.  However, we do not have
  1633   resources after a finite amount of time.  However, we do not have
  1624   this concept of active or hibernating threads in our model.  In fact
  1634   this concept of active or hibernating threads in our model.  In fact
  1625   we can dispence with the first assumption altogether and allow that
  1635   we can dispence with the first assumption altogether and allow that
  1626   in our model we can create new threads or exit existing threads
  1636   in our model we can create new threads or exit existing threads