prio/Paper/Paper.thy
changeset 339 b3add51e2e0f
parent 337 f9d54f49c808
child 341 eb2fc3ac934d
equal deleted inserted replaced
338:e7504bfdbd50 339:b3add51e2e0f
    53   can interact in subtle ways leading to a problem, called
    53   can interact in subtle ways leading to a problem, called
    54   \emph{Priority Inversion}. Suppose three threads having priorities
    54   \emph{Priority Inversion}. Suppose three threads having priorities
    55   $H$(igh), $M$(edium) and $L$(ow). We would expect that the thread
    55   $H$(igh), $M$(edium) and $L$(ow). We would expect that the thread
    56   $H$ blocks any other thread with lower priority and itself cannot
    56   $H$ blocks any other thread with lower priority and itself cannot
    57   be blocked by any thread with lower priority. Alas, in a naive
    57   be blocked by any thread with lower priority. Alas, in a naive
    58   implementation of resource looking and priorities this property can
    58   implementation of resource locking and priorities this property can
    59   be violated. Even worse, $H$ can be delayed indefinitely by
    59   be violated. Even worse, $H$ can be delayed indefinitely by
    60   threads with lower priorities. For this let $L$ be in the
    60   threads with lower priorities. For this let $L$ be in the
    61   possession of a lock for a resource that also $H$ needs. $H$ must
    61   possession of a lock for a resource that $H$ also needs. $H$ must
    62   therefore wait for $L$ to exit the critical section and release this
    62   therefore wait for $L$ to exit the critical section and release this
    63   lock. The problem is that $L$ might in turn be blocked by any
    63   lock. The problem is that $L$ might in turn be blocked by any
    64   thread with priority $M$, and so $H$ sits there potentially waiting
    64   thread with priority $M$, and so $H$ sits there potentially waiting
    65   indefinitely. Since $H$ is blocked by threads with lower
    65   indefinitely. Since $H$ is blocked by threads with lower
    66   priorities, the problem is called Priority Inversion. It was first
    66   priorities, the problem is called Priority Inversion. It was first
    74   Once the spacecraft landed, the software shut down at irregular
    74   Once the spacecraft landed, the software shut down at irregular
    75   intervals leading to loss of project time as normal operation of the
    75   intervals leading to loss of project time as normal operation of the
    76   craft could only resume the next day (the mission and data already
    76   craft could only resume the next day (the mission and data already
    77   collected were fortunately not lost, because of a clever system
    77   collected were fortunately not lost, because of a clever system
    78   design).  The reason for the shutdowns was that the scheduling
    78   design).  The reason for the shutdowns was that the scheduling
    79   software fell victim of Priority Inversion: a low priority thread
    79   software fell victim to Priority Inversion: a low priority thread
    80   locking a resource prevented a high priority thread from running in
    80   locking a resource prevented a high priority thread from running in
    81   time leading to a system reset. Once the problem was found, it was
    81   time, leading to a system reset. Once the problem was found, it was
    82   rectified by enabling the \emph{Priority Inheritance Protocol} (PIP)
    82   rectified by enabling the \emph{Priority Inheritance Protocol} (PIP)
    83   \cite{Sha90}\footnote{Sha et al.~call it the \emph{Basic Priority
    83   \cite{Sha90}\footnote{Sha et al.~call it the \emph{Basic Priority
    84   Inheritance Protocol} \cite{Sha90} and others sometimes also call it
    84   Inheritance Protocol} \cite{Sha90} and others sometimes also call it
    85   \emph{Priority Boosting}.} in the scheduling software.
    85   \emph{Priority Boosting}.} in the scheduling software.
    86 
    86 
   112   \it{}``Priority inheritance is neither efficient nor reliable. Implementations
   112   \it{}``Priority inheritance is neither efficient nor reliable. Implementations
   113   are either incomplete (and unreliable) or surprisingly complex and intrusive.''
   113   are either incomplete (and unreliable) or surprisingly complex and intrusive.''
   114   \end{quote}
   114   \end{quote}
   115 
   115 
   116   \noindent
   116   \noindent
   117   He suggests to avoid PIP altogether by not allowing critical
   117   He suggests avoiding PIP altogether by not allowing critical
   118   sections to be preempted. Unfortunately, this solution does not
   118   sections to be preempted. Unfortunately, this solution does not
   119   help in real-time systems with hard deadlines for high-priority 
   119   help in real-time systems with hard deadlines for high-priority 
   120   threads.
   120   threads.
   121 
   121 
   122   In our opinion, there is clearly a need for investigating correct
   122   In our opinion, there is clearly a need for investigating correct
   134   range of events, including priority changes and interruptions of
   134   range of events, including priority changes and interruptions of
   135   wait operations.''
   135   wait operations.''
   136   \end{quote}
   136   \end{quote}
   137 
   137 
   138   \noindent
   138   \noindent
   139   The criticism by Yodaiken, Baker and others suggests to us to look
   139   The criticism by Yodaiken, Baker and others suggests another look
   140   again at PIP from a more abstract level (but still concrete enough
   140   at PIP from a more abstract level (but still concrete enough
   141   to inform an implementation), and makes PIP an ideal candidate for a
   141   to inform an implementation), and makes PIP a good candidate for a
   142   formal verification. One reason, of course, is that the original
   142   formal verification. An additional reason is that the original
   143   presentation of PIP~\cite{Sha90}, despite being informally
   143   presentation of PIP~\cite{Sha90}, despite being informally
   144   ``proved'' correct, is actually \emph{flawed}. 
   144   ``proved'' correct, is actually \emph{flawed}. 
   145 
   145 
   146   Yodaiken \cite{Yodaiken02} points to a subtlety that had been
   146   Yodaiken \cite{Yodaiken02} points to a subtlety that had been
   147   overlooked in the informal proof by Sha et al. They specify in
   147   overlooked in the informal proof by Sha et al. They specify in
   153   simplistic.  Consider the case where the low priority thread $L$
   153   simplistic.  Consider the case where the low priority thread $L$
   154   locks \emph{two} resources, and two high-priority threads $H$ and
   154   locks \emph{two} resources, and two high-priority threads $H$ and
   155   $H'$ each wait for one of them.  If $L$ releases one resource
   155   $H'$ each wait for one of them.  If $L$ releases one resource
   156   so that $H$, say, can proceed, then we still have Priority Inversion
   156   so that $H$, say, can proceed, then we still have Priority Inversion
   157   with $H'$ (which waits for the other resource). The correct
   157   with $H'$ (which waits for the other resource). The correct
   158   behaviour for $L$ is to revert to the highest remaining priority of
   158   behaviour for $L$ is to switch to the highest remaining priority of
   159   the threads that it blocks. The advantage of formalising the
   159   the threads that it blocks. The advantage of formalising the
   160   correctness of a high-level specification of PIP in a theorem prover
   160   correctness of a high-level specification of PIP in a theorem prover
   161   is that such issues clearly show up and cannot be overlooked as in
   161   is that such issues clearly show up and cannot be overlooked as in
   162   informal reasoning (since we have to analyse all possible behaviours
   162   informal reasoning (since we have to analyse all possible behaviours
   163   of threads, i.e.~\emph{traces}, that could possibly happen).\medskip
   163   of threads, i.e.~\emph{traces}, that could possibly happen).\medskip
   171   al.~\cite{Sha90} is flawed).  In contrast to model checking, our
   171   al.~\cite{Sha90} is flawed).  In contrast to model checking, our
   172   formalisation provides insight into why PIP is correct and allows us
   172   formalisation provides insight into why PIP is correct and allows us
   173   to prove stronger properties that, as we will show, can inform an
   173   to prove stronger properties that, as we will show, can inform an
   174   efficient implementation.  For example, we found by ``playing'' with the formalisation
   174   efficient implementation.  For example, we found by ``playing'' with the formalisation
   175   that the choice of the next thread to take over a lock when a
   175   that the choice of the next thread to take over a lock when a
   176   resource is released is irrelevant for PIP being correct. Something
   176   resource is released is irrelevant for PIP being correct---a fact
   177   which has not been mentioned in the relevant literature.
   177   that has not been mentioned in the relevant literature.
   178 *}
   178 *}
   179 
   179 
   180 section {* Formal Model of the Priority Inheritance Protocol *}
   180 section {* Formal Model of the Priority Inheritance Protocol *}
   181 
   181 
   182 text {*
   182 text {*
   510   \end{tabular}
   510   \end{tabular}
   511   \end{isabelle}
   511   \end{isabelle}
   512 
   512 
   513   \noindent
   513   \noindent
   514   With these abbreviations in place we can introduce 
   514   With these abbreviations in place we can introduce 
   515   the notion of threads being @{term readys} in a state (i.e.~threads
   515   the notion of a thread being @{term ready} in a state (i.e.~threads
   516   that do not wait for any resource) and the running thread.
   516   that do not wait for any resource) and the running thread.
   517 
   517 
   518   \begin{isabelle}\ \ \ \ \ %%%
   518   \begin{isabelle}\ \ \ \ \ %%%
   519   \begin{tabular}{@ {}l}
   519   \begin{tabular}{@ {}l}
   520   @{thm readys_def}\\
   520   @{thm readys_def}\\
   536   @{thm holdents_def}
   536   @{thm holdents_def}
   537   \end{isabelle}
   537   \end{isabelle}
   538 
   538 
   539   Finally we can define what a \emph{valid state} is in our model of PIP. For
   539   Finally we can define what a \emph{valid state} is in our model of PIP. For
   540   example we cannot expect to be able to exit a thread, if it was not
   540   example we cannot expect to be able to exit a thread, if it was not
   541   created yet. This would cause havoc  in any scheduler. 
   541   created yet. 
   542   These validity constraints on states are characterised by the
   542   These validity constraints on states are characterised by the
   543   inductive predicate @{term "step"} and @{term vt}. We first give five inference rules
   543   inductive predicate @{term "step"} and @{term vt}. We first give five inference rules
   544   for @{term step} relating a state and an event that can happen next.
   544   for @{term step} relating a state and an event that can happen next.
   545 
   545 
   546   \begin{center}
   546   \begin{center}
   625   of time, then indefinite Priority Inversion cannot occur---the high-priority
   625   of time, then indefinite Priority Inversion cannot occur---the high-priority
   626   thread is guaranteed to run eventually. The assumption is that
   626   thread is guaranteed to run eventually. The assumption is that
   627   programmers must ensure that threads are programmed in this way.  However, even
   627   programmers must ensure that threads are programmed in this way.  However, even
   628   taking this assumption into account, the correctness properties of
   628   taking this assumption into account, the correctness properties of
   629   Sha et al.~are
   629   Sha et al.~are
   630   \emph{not} true for their version of PIP---despide being ``proved''. As Yodaiken
   630   \emph{not} true for their version of PIP---despite being ``proved''. As Yodaiken
   631   \cite{Yodaiken02} pointed out: If a low-priority thread possesses
   631   \cite{Yodaiken02} pointed out: If a low-priority thread possesses
   632   locks to two resources for which two high-priority threads are
   632   locks to two resources for which two high-priority threads are
   633   waiting for, then lowering the priority prematurely after giving up
   633   waiting for, then lowering the priority prematurely after giving up
   634   only one lock, can cause indefinite Priority Inversion for one of the
   634   only one lock, can cause indefinite Priority Inversion for one of the
   635   high-priority threads, invalidating their two bounds.
   635   high-priority threads, invalidating their two bounds.
   732   However, we are able to combine their two separate bounds into a
   732   However, we are able to combine their two separate bounds into a
   733   single theorem improving their bound.
   733   single theorem improving their bound.
   734 
   734 
   735   In what follows we will describe properties of PIP that allow us to prove 
   735   In what follows we will describe properties of PIP that allow us to prove 
   736   Theorem~\ref{mainthm} and, when instructive, briefly describe our argument. 
   736   Theorem~\ref{mainthm} and, when instructive, briefly describe our argument. 
   737   It is relatively easily to see that
   737   It is relatively easy to see that
   738 
   738 
   739   \begin{isabelle}\ \ \ \ \ %%%
   739   \begin{isabelle}\ \ \ \ \ %%%
   740   \begin{tabular}{@ {}l}
   740   \begin{tabular}{@ {}l}
   741   @{text "running s \<subseteq> ready s \<subseteq> threads s"}\\
   741   @{text "running s \<subseteq> ready s \<subseteq> threads s"}\\
   742   @{thm[mode=IfThen]  finite_threads}
   742   @{thm[mode=IfThen]  finite_threads}
   774   \hspace{5mm}@{text "if"}~@{thm (prem 2) range_in}~@{text "then"}~@{thm (concl) range_in}.
   774   \hspace{5mm}@{text "if"}~@{thm (prem 2) range_in}~@{text "then"}~@{thm (concl) range_in}.
   775   \end{tabular}
   775   \end{tabular}
   776   \end{isabelle}
   776   \end{isabelle}
   777 
   777 
   778   \noindent
   778   \noindent
   779   The acyclicity property follow from how we restricted the events in
   779   The acyclicity property follows from how we restricted the events in
   780   @{text step}; similarly the finiteness and well-foundedness property.
   780   @{text step}; similarly the finiteness and well-foundedness property.
   781   The last two properties establish that every thread in a @{text "RAG"}
   781   The last two properties establish that every thread in a @{text "RAG"}
   782   (either holding or waiting for a resource) is a live thread.
   782   (either holding or waiting for a resource) is a live thread.
   783 
   783 
   784   The key lemma in our proof of Theorem~\ref{mainthm} is as follows:
   784   The key lemma in our proof of Theorem~\ref{mainthm} is as follows:
   785 
   785 
   786   \begin{lemma}\label{mainlem}
   786   \begin{lemma}\label{mainlem}
   787   Given the assumptions about states @{text "s"} and @{text "s' @ s"},
   787   Given the assumptions about states @{text "s"} and @{text "s' @ s"},
   788   the thread @{text th} and the events in @{text "s'"},
   788   the thread @{text th} and the events in @{text "s'"},
   789   if @{term "th' \<in> treads (s' @ s)"}, @{text "th' \<noteq> th"} and @{text "detached (s' @ s) th'"}\\
   789   if @{term "th' \<in> threads (s' @ s)"}, @{text "th' \<noteq> th"} and @{text "detached (s' @ s) th'"}\\
   790   then @{text "th' \<notin> running (s' @ s)"}.
   790   then @{text "th' \<notin> running (s' @ s)"}.
   791   \end{lemma}
   791   \end{lemma}
   792 
   792 
   793   \noindent
   793   \noindent
   794   The point of this lemma is that a thread different from @{text th} (which has the highest
   794   The point of this lemma is that a thread different from @{text th} (which has the highest
   976   @{thm children_def2}
   976   @{thm children_def2}
   977   \end{tabular}
   977   \end{tabular}
   978   \end{isabelle}
   978   \end{isabelle}
   979 
   979 
   980   \noindent
   980   \noindent
   981   where a child is a thread that is only one ``hop'' away from the tread
   981   where a child is a thread that is only one ``hop'' away from the thread
   982   @{text th} in the @{term RAG} (and waiting for @{text th} to release
   982   @{text th} in the @{term RAG} (and waiting for @{text th} to release
   983   a resource). We can prove the following lemma.
   983   a resource). We can prove the following lemma.
   984 
   984 
   985   \begin{lemma}\label{childrenlem}
   985   \begin{lemma}\label{childrenlem}
   986   @{text "If"} @{thm (prem 1) cp_rec} @{text "then"}
   986   @{text "If"} @{thm (prem 1) cp_rec} @{text "then"}
  1188 text {*
  1188 text {*
  1189   \noindent
  1189   \noindent
  1190   As can be seen, a pleasing byproduct of our formalisation is that the properties in
  1190   As can be seen, a pleasing byproduct of our formalisation is that the properties in
  1191   this section closely inform an implementation of PIP, namely whether the
  1191   this section closely inform an implementation of PIP, namely whether the
  1192   @{text RAG} needs to be reconfigured or current precedences need to
  1192   @{text RAG} needs to be reconfigured or current precedences need to
  1193   by recalculated for an event. This information is provided by the lemmas we proved.
  1193   be recalculated for an event. This information is provided by the lemmas we proved.
  1194 *}
  1194 *}
  1195 
  1195 
  1196 section {* Conclusion *}
  1196 section {* Conclusion *}
  1197 
  1197 
  1198 text {* 
  1198 text {* 
  1267   code with a few apply-scripts interspersed. The formal model of PIP
  1267   code with a few apply-scripts interspersed. The formal model of PIP
  1268   is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary
  1268   is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary
  1269   definitions and proofs span over 770 lines of code. The properties relevant
  1269   definitions and proofs span over 770 lines of code. The properties relevant
  1270   for an implementation require 2000 lines. The code of our formalisation 
  1270   for an implementation require 2000 lines. The code of our formalisation 
  1271   can be downloaded from
  1271   can be downloaded from
  1272   \url{http://www.dcs.kcl.ac.uk/staff/urbanc/pip.html}.
  1272   \url{http://www.inf.kcl.ac.uk/staff/urbanc/pip.html}.
  1273 
  1273 
  1274   \bibliographystyle{plain}
  1274   \bibliographystyle{plain}
  1275   \bibliography{root}
  1275   \bibliography{root}
  1276 *}
  1276 *}
  1277 
  1277