prio/Paper/Paper.thy
changeset 342 a40a35d1bc91
parent 341 eb2fc3ac934d
child 343 1687f868dd5e
equal deleted inserted replaced
341:eb2fc3ac934d 342:a40a35d1bc91
    51   preempted. Priorities allow scheduling of threads that need to
    51   preempted. Priorities allow scheduling of threads that need to
    52   finish their work within deadlines.  Unfortunately, both features
    52   finish their work within deadlines.  Unfortunately, both features
    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 the thread itself cannot
    57   be blocked by any thread with lower priority. Alas, in a naive
    57   be blocked indefinitely by any thread with lower priority. Alas, in a naive
    58   implementation of resource locking 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 $H$ also 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
   166   {\bf Contributions:} There have been earlier formal investigations
   166   {\bf Contributions:} There have been earlier formal investigations
   167   into PIP \cite{Faria08,Jahier09,Wellings07}, but they employ model
   167   into PIP \cite{Faria08,Jahier09,Wellings07}, but they employ model
   168   checking techniques. This paper presents a formalised and
   168   checking techniques. This paper presents a formalised and
   169   mechanically checked proof for the correctness of PIP (to our
   169   mechanically checked proof for the correctness of PIP (to our
   170   knowledge the first one). 
   170   knowledge the first one). 
   171   %; the earlier informal proof by Sha et
       
   172   %al.~\cite{Sha90} is flawed).  
       
   173   In contrast to model checking, our
   171   In contrast to model checking, our
   174   formalisation provides insight into why PIP is correct and allows us
   172   formalisation provides insight into why PIP is correct and allows us
   175   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
   176   efficient implementation.  For example, we found by ``playing'' with the formalisation
   174   efficient implementation.  For example, we found by ``playing'' with the formalisation
   177   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
   178   resource is released is irrelevant for PIP being correct---a fact
   176   resource is released is irrelevant for PIP being correct---a fact
   179   that has not been mentioned in the literature.
   177   that has not been mentioned in the literature. This is important
       
   178   for an efficient implementation, because we can give the lock to the
       
   179   thread with the highest priority so that it terminates more quickly.
   180 *}
   180 *}
   181 
   181 
   182 section {* Formal Model of the Priority Inheritance Protocol *}
   182 section {* Formal Model of the Priority Inheritance Protocol *}
   183 
   183 
   184 text {*
   184 text {*
   185   The Priority Inheritance Protocol, short PIP, is a scheduling
   185   The Priority Inheritance Protocol, short PIP, is a scheduling
   186   algorithm for a single-processor system.\footnote{We shall come back
   186   algorithm for a single-processor system.\footnote{We shall come back
   187   later to the case of PIP on multi-processor systems.} Our model of
   187   later to the case of PIP on multi-processor systems.} 
   188   PIP is based on Paulson's inductive approach to protocol
   188   Following good experience in earlier work \cite{Wang09},  
   189   verification \cite{Paulson98}, where the \emph{state} of a system is
   189   our model of PIP is based on Paulson's inductive approach to protocol
   190   given by a list of events that happened so far.  \emph{Events} of PIP fall
   190   verification \cite{Paulson98}. In this approach a \emph{state} of a system is
       
   191   given by a list of events that happened so far (with new events prepended to the list). 
       
   192   \emph{Events} of PIP fall
   191   into five categories defined as the datatype:
   193   into five categories defined as the datatype:
   192 
   194 
   193   \begin{isabelle}\ \ \ \ \ %%%
   195   \begin{isabelle}\ \ \ \ \ %%%
   194   \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l}
   196   \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l}
   195   \isacommand{datatype} event 
   197   \isacommand{datatype} event 
   367   but also @{text "th\<^isub>3"}, 
   369   but also @{text "th\<^isub>3"}, 
   368   which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which
   370   which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which
   369   in turn needs to wait for @{text "th\<^isub>0"} to finish). If there is a circle of dependencies 
   371   in turn needs to wait for @{text "th\<^isub>0"} to finish). If there is a circle of dependencies 
   370   in a RAG, then clearly
   372   in a RAG, then clearly
   371   we have a deadlock. Therefore when a thread requests a resource,
   373   we have a deadlock. Therefore when a thread requests a resource,
   372   we must ensure that the resulting RAG is not circular. 
   374   we must ensure that the resulting RAG is not circular. In practice, the 
       
   375   programmer has to ensure this.
       
   376 
       
   377 
       
   378   {\bf define detached}
       
   379 
   373 
   380 
   374   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   381   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   375   state @{text s}. It is defined as
   382   state @{text s}. It is defined as
   376 
   383 
   377   \begin{isabelle}\ \ \ \ \ %%%
   384   \begin{isabelle}\ \ \ \ \ %%%
   378   @{thm cpreced_def2}\hfill\numbered{cpreced}
   385   @{thm cpreced_def2}\hfill\numbered{cpreced}
   379   \end{isabelle}
   386   \end{isabelle}
   380 
   387 
   381   \noindent
   388   \noindent
   382   where the dependants of @{text th} are given by the waiting queue function.
   389   where the dependants of @{text th} are given by the waiting queue function.
   383   While the precedence @{term prec} of a thread is determined by the programmer 
   390   While the precedence @{term prec} of a thread is determined statically 
   384   (for example when the thread is
   391   (for example when the thread is
   385   created), the point of the current precedence is to let the scheduler increase this
   392   created), the point of the current precedence is to let the scheduler increase this
   386   precedence, if needed according to PIP. Therefore the current precedence of @{text th} is
   393   precedence, if needed according to PIP. Therefore the current precedence of @{text th} is
   387   given as the maximum of the precedence @{text th} has in state @{text s} \emph{and} all 
   394   given as the maximum of the precedence @{text th} has in state @{text s} \emph{and} all 
   388   threads that are dependants of @{text th}. Since the notion @{term "dependants"} is
   395   threads that are dependants of @{text th}. Since the notion @{term "dependants"} is
   565   \end{center}
   572   \end{center}
   566 
   573 
   567   \noindent
   574   \noindent
   568   If a thread wants to lock a resource, then the thread needs to be
   575   If a thread wants to lock a resource, then the thread needs to be
   569   running and also we have to make sure that the resource lock does
   576   running and also we have to make sure that the resource lock does
   570   not lead to a cycle in the RAG. In practice, ensuring the latter is
   577   not lead to a cycle in the RAG. In practice, ensuring the latter
   571   the responsibility of the programmer.  In our formal
   578   is the responsibility of the programmer.  In our formal
   572   model we brush aside these problematic cases in order to be able to make
   579   model we brush aside these problematic cases in order to be able to make
   573   some meaningful statements about PIP.\footnote{This situation is
   580   some meaningful statements about PIP.\footnote{This situation is
   574   similar to the infamous \emph{occurs check} in Prolog: In order to say
   581   similar to the infamous \emph{occurs check} in Prolog: In order to say
   575   anything meaningful about unification, one needs to perform an occurs
   582   anything meaningful about unification, one needs to perform an occurs
   576   check. But in practice the occurs check is omitted and the
   583   check. But in practice the occurs check is omitted and the
   577   responsibility for avoiding problems rests with the programmer.}
   584   responsibility for avoiding problems rests with the programmer.}
       
   585 
   578  
   586  
   579   \begin{center}
   587   \begin{center}
   580   @{thm[mode=Rule] thread_P[where thread=th]}
   588   @{thm[mode=Rule] thread_P[where thread=th]}
   581   \end{center}
   589   \end{center}
   582  
   590  
   636   only one lock, can cause indefinite Priority Inversion for one of the
   644   only one lock, can cause indefinite Priority Inversion for one of the
   637   high-priority threads, invalidating their two bounds.
   645   high-priority threads, invalidating their two bounds.
   638 
   646 
   639   Even when fixed, their proof idea does not seem to go through for
   647   Even when fixed, their proof idea does not seem to go through for
   640   us, because of the way we have set up our formal model of PIP.  One
   648   us, because of the way we have set up our formal model of PIP.  One
   641   reason is that we allow critical sections to intersect
   649   reason is that we allow critical sections, which start with a @{text P}-event
       
   650   and finish with a corresponding @{text V}-event, to arbitrarily overlap
   642   (something Sha et al.~explicitly exclude).  Therefore we have
   651   (something Sha et al.~explicitly exclude).  Therefore we have
   643   designed a different correctness criterion for PIP. The idea behind
   652   designed a different correctness criterion for PIP. The idea behind
   644   our criterion is as follows: for all states @{text s}, we know the
   653   our criterion is as follows: for all states @{text s}, we know the
   645   corresponding thread @{text th} with the highest precedence; we show
   654   corresponding thread @{text th} with the highest precedence; we show
   646   that in every future state (denoted by @{text "s' @ s"}) in which
   655   that in every future state (denoted by @{text "s' @ s"}) in which
   656   s"}, the thread @{text th} and the events happening in @{text
   665   s"}, the thread @{text th} and the events happening in @{text
   657   s'}. We list them next:
   666   s'}. We list them next:
   658 
   667 
   659   \begin{quote}
   668   \begin{quote}
   660   {\bf Assumptions on the states {\boldmath@{text s}} and 
   669   {\bf Assumptions on the states {\boldmath@{text s}} and 
   661   {\boldmath@{text "s' @ s"}:}} In order to make 
   670   {\boldmath@{text "s' @ s"}:}} We need to require that @{text "s"} and 
   662   any meaningful statement, we need to require that @{text "s"} and 
   671   @{text "s' @ s"} are valid states:
   663   @{text "s' @ s"} are valid states, namely
       
   664   \begin{isabelle}\ \ \ \ \ %%%
   672   \begin{isabelle}\ \ \ \ \ %%%
   665   \begin{tabular}{l}
   673   \begin{tabular}{l}
   666   @{term "vt s"}\\
   674   @{term "vt s"}\\
   667   @{term "vt (s' @ s)"} 
   675   @{term "vt (s' @ s)"} 
   668   \end{tabular}
   676   \end{tabular}
   958 (*>*)
   966 (*>*)
   959 
   967 
   960 section {* Properties for an Implementation\label{implement} *}
   968 section {* Properties for an Implementation\label{implement} *}
   961 
   969 
   962 text {*
   970 text {*
   963   While a formal correctness proof for our model of PIP is certainly
   971   While our formalised proof gives us confidence about the correctness of our model of PIP, 
   964   attractive (especially in light of the flawed proof by Sha et
   972   we found that the formalisation can even help us with efficiently implementing it.
   965   al.~\cite{Sha90}), we found that the formalisation can even help us
       
   966   with efficiently implementing PIP.
       
   967 
   973 
   968   For example Baker complained that calculating the current precedence
   974   For example Baker complained that calculating the current precedence
   969   in PIP is quite ``heavy weight'' in Linux (see the Introduction).
   975   in PIP is quite ``heavy weight'' in Linux (see the Introduction).
   970   In our model of PIP the current precedence of a thread in a state @{text s}
   976   In our model of PIP the current precedence of a thread in a state @{text s}
   971   depends on all its dependants---a ``global'' transitive notion,
   977   depends on all its dependants---a ``global'' transitive notion,
  1066   @{term "s \<equiv> Set th prio#s'"} are both valid. We can show that
  1072   @{term "s \<equiv> Set th prio#s'"} are both valid. We can show that
  1067 
  1073 
  1068   \begin{isabelle}\ \ \ \ \ %%%
  1074   \begin{isabelle}\ \ \ \ \ %%%
  1069   \begin{tabular}{@ {}l}
  1075   \begin{tabular}{@ {}l}
  1070   @{thm[mode=IfThen] eq_dep}, and\\
  1076   @{thm[mode=IfThen] eq_dep}, and\\
  1071   @{thm[mode=IfThen] eq_cp}
  1077   @{thm[mode=IfThen] eq_cp_pre}
  1072   \end{tabular}
  1078   \end{tabular}
  1073   \end{isabelle}
  1079   \end{isabelle}
  1074 
  1080 
  1075   \noindent
  1081   \noindent
  1076   The first property is again telling us we do not need to change the @{text RAG}. The second
  1082   The first property is again telling us we do not need to change the @{text RAG}. 
  1077   however states that only threads that are \emph{not} dependants of @{text th} have their
  1083   The second shows that the @{term cp}-values of all threads other than @{text th} 
  1078   current precedence unchanged. For the others we have to recalculate the current
  1084   are unchanged. The reason is that @{text th} is running; therefore it is not in 
  1079   precedence. To do this we can start from @{term "th"} 
  1085   the @{term dependants} relation of any thread. This in turn means that the 
  1080   and follow the @{term "depend"}-edges to recompute  using Lemma~\ref{childrenlem} 
  1086   change of its priority cannot affect the threads.
  1081   the @{term "cp"} of every 
  1087 
  1082   thread encountered on the way. Since the @{term "depend"}
  1088   %The second
  1083   is assumed to be loop free, this procedure will always stop. The following two lemmas show, however, 
  1089   %however states that only threads that are \emph{not} dependants of @{text th} have their
  1084   that this procedure can actually stop often earlier without having to consider all
  1090   %current precedence unchanged. For the others we have to recalculate the current
  1085   dependants.
  1091   %precedence. To do this we can start from @{term "th"} 
  1086 
  1092   %and follow the @{term "depend"}-edges to recompute  using Lemma~\ref{childrenlem} 
  1087   \begin{isabelle}\ \ \ \ \ %%%
  1093   %the @{term "cp"} of every 
  1088   \begin{tabular}{@ {}l}
  1094   %thread encountered on the way. Since the @{term "depend"}
  1089   @{thm[mode=IfThen] eq_up_self}\\
  1095   %is assumed to be loop free, this procedure will always stop. The following two lemmas show, however, 
  1090   @{text "If"} @{thm (prem 1) eq_up}, @{thm (prem 2) eq_up} and @{thm (prem 3) eq_up}\\
  1096   %that this procedure can actually stop often earlier without having to consider all
  1091   @{text "then"} @{thm (concl) eq_up}.
  1097   %dependants.
  1092   \end{tabular}
  1098   %
  1093   \end{isabelle}
  1099   %\begin{isabelle}\ \ \ \ \ %%%
  1094 
  1100   %\begin{tabular}{@ {}l}
  1095   \noindent
  1101   %@{thm[mode=IfThen] eq_up_self}\\
  1096   The first lemma states that if the current precedence of @{text th} is unchanged,
  1102   %@{text "If"} @{thm (prem 1) eq_up}, @{thm (prem 2) eq_up} and @{thm (prem 3) eq_up}\\
  1097   then the procedure can stop immediately (all dependent threads have their @{term cp}-value unchanged).
  1103   %@{text "then"} @{thm (concl) eq_up}.
  1098   The second states that if an intermediate @{term cp}-value does not change, then
  1104   %\end{tabular}
  1099   the procedure can also stop, because none of its dependent threads will
  1105   %\end{isabelle}
  1100   have their current precedence changed.
  1106   %
       
  1107   %\noindent
       
  1108   %The first lemma states that if the current precedence of @{text th} is unchanged,
       
  1109   %then the procedure can stop immediately (all dependent threads have their @{term cp}-value unchanged).
       
  1110   %The second states that if an intermediate @{term cp}-value does not change, then
       
  1111   %the procedure can also stop, because none of its dependent threads will
       
  1112   %have their current precedence changed.
  1101   \smallskip
  1113   \smallskip
  1102   *}
  1114   *}
  1103 (*<*)
  1115 (*<*)
  1104 end
  1116 end
  1105 context step_v_cps_nt
  1117 context step_v_cps_nt
  1151 (*>*)
  1163 (*>*)
  1152 text {*
  1164 text {*
  1153   \noindent
  1165   \noindent
  1154   \colorbox{mygrey}{@{term "P th cs"}:} We assume that @{text s'} and 
  1166   \colorbox{mygrey}{@{term "P th cs"}:} We assume that @{text s'} and 
  1155   @{term "s \<equiv> P th cs#s'"} are both valid. We again have to analyse two subcases, namely
  1167   @{term "s \<equiv> P th cs#s'"} are both valid. We again have to analyse two subcases, namely
  1156   the one where @{text cs} is locked, and where it is not. We treat the second case
  1168   the one where @{text cs} is not locked, and one where it is. We treat the former case
  1157   first by showing that
  1169   first by showing that
  1158   
  1170   
  1159   \begin{isabelle}\ \ \ \ \ %%%
  1171   \begin{isabelle}\ \ \ \ \ %%%
  1160   \begin{tabular}{@ {}l}
  1172   \begin{tabular}{@ {}l}
  1161   @{thm depend_s}\\
  1173   @{thm depend_s}\\
  1208   make the notions in the correctness proof by Sha et al.~\cite{Sha90}
  1220   make the notions in the correctness proof by Sha et al.~\cite{Sha90}
  1209   precise so that they can be processed by a theorem prover. The reason is
  1221   precise so that they can be processed by a theorem prover. The reason is
  1210   that a mechanically checked proof avoids the flaws that crept into their
  1222   that a mechanically checked proof avoids the flaws that crept into their
  1211   informal reasoning. We achieved this goal: The correctness of PIP now
  1223   informal reasoning. We achieved this goal: The correctness of PIP now
  1212   only hinges on the assumptions behind our formal model. The reasoning, which is
  1224   only hinges on the assumptions behind our formal model. The reasoning, which is
  1213   sometimes quite intricate and tedious, has been checked beyond any
  1225   sometimes quite intricate and tedious, has been checked by Isabelle/HOL. 
  1214   reasonable doubt by Isabelle/HOL. We can also confirm that Paulson's
  1226   We can also confirm that Paulson's
  1215   inductive method for protocol verification~\cite{Paulson98} is quite
  1227   inductive method for protocol verification~\cite{Paulson98} is quite
  1216   suitable for our formal model and proof. The traditional application
  1228   suitable for our formal model and proof. The traditional application
  1217   area of this method is security protocols.  The only other
  1229   area of this method is security protocols. 
  1218   application of Paulson's method we know of outside this area is
       
  1219   \cite{Wang09}.
       
  1220 
  1230 
  1221   The second goal of our formalisation is to provide a specification for actually
  1231   The second goal of our formalisation is to provide a specification for actually
  1222   implementing PIP. Textbooks, for example \cite[Section 5.6.5]{Vahalia96},
  1232   implementing PIP. Textbooks, for example \cite[Section 5.6.5]{Vahalia96},
  1223   explain how to use various implementations of PIP and abstractly
  1233   explain how to use various implementations of PIP and abstractly
  1224   discuss their properties, but surprisingly lack most details important for a
  1234   discuss their properties, but surprisingly lack most details important for a
  1234   the next thread which takes over a lock is irrelevant for the correctness
  1244   the next thread which takes over a lock is irrelevant for the correctness
  1235   of PIP. Earlier model checking approaches which verified particular implementations
  1245   of PIP. Earlier model checking approaches which verified particular implementations
  1236   of PIP \cite{Faria08,Jahier09,Wellings07} cannot
  1246   of PIP \cite{Faria08,Jahier09,Wellings07} cannot
  1237   provide this kind of ``deep understanding'' about the principles behind 
  1247   provide this kind of ``deep understanding'' about the principles behind 
  1238   PIP and its correctness.
  1248   PIP and its correctness.
       
  1249 
       
  1250   {\bf rewrite the following slightly}
  1239 
  1251 
  1240   PIP is a scheduling algorithm for single-processor systems. We are
  1252   PIP is a scheduling algorithm for single-processor systems. We are
  1241   now living in a multi-processor world. So the question naturally
  1253   now living in a multi-processor world. So the question naturally
  1242   arises whether PIP has any relevance in such a world beyond
  1254   arises whether PIP has any relevance in such a world beyond
  1243   teaching. Priority Inversion certainly occurs also in
  1255   teaching. Priority Inversion certainly occurs also in
  1258   slave processes. However, a formal investigation of this idea is beyond
  1270   slave processes. However, a formal investigation of this idea is beyond
  1259   the scope of this paper.  We are not aware of any proofs in this
  1271   the scope of this paper.  We are not aware of any proofs in this
  1260   area, not even informal or flawed ones.
  1272   area, not even informal or flawed ones.
  1261 
  1273 
  1262   The most closely related work to ours is the formal verification in
  1274   The most closely related work to ours is the formal verification in
  1263   PVS of the Priority Ceiling Protocol done by Dutertre 
  1275   PVS of the Priority Ceiling Protocol done by Dutertre
  1264   \cite{dutertre99b}---another solution to the Priority Inversion 
  1276   \cite{dutertre99b}---another solution to the Priority Inversion
  1265   problem, which however needs
  1277   problem, which however needs static analysis of programs in order to
  1266   static analysis of programs in order to avoid it.
  1278   avoid it. {\bf mention model-checking approaches}
  1267   His formalisation consists of 407 lemmas and 2500 lines of (PVS) code.  Our formalisation
  1279 
       
  1280   Our formalisation
  1268   consists of around 210 lemmas and overall 6950 lines of readable Isabelle/Isar
  1281   consists of around 210 lemmas and overall 6950 lines of readable Isabelle/Isar
  1269   code with a few apply-scripts interspersed. The formal model of PIP
  1282   code with a few apply-scripts interspersed. The formal model of PIP
  1270   is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary
  1283   is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary
  1271   definitions and proofs span over 770 lines of code. The properties relevant
  1284   definitions and proofs span over 770 lines of code. The properties relevant
  1272   for an implementation require 2000 lines. The code of our formalisation 
  1285   for an implementation require 2000 lines. The code of our formalisation 
  1273   can be downloaded from
  1286   can be downloaded from
  1274   \url{http://www.inf.kcl.ac.uk/staff/urbanc/pip.html}.
  1287   \url{http://www.inf.kcl.ac.uk/staff/urbanc/pip.html}.
  1275 
  1288 
       
  1289   {\bf say:
       
  1290   So this paper is a good witness for one
       
  1291 of the major reasons to be interested in machine checked reasoning:
       
  1292 gaining deeper understanding of the subject matter.
       
  1293   }
       
  1294 
       
  1295 
  1276   \bibliographystyle{plain}
  1296   \bibliographystyle{plain}
  1277   \bibliography{root}
  1297   \bibliography{root}
  1278 *}
  1298 *}
  1279 
  1299 
  1280 
  1300