prio/Paper/Paper.thy
changeset 332 5faa1b59e870
parent 331 c5442db6a5cb
child 333 813e7257c7c3
equal deleted inserted replaced
331:c5442db6a5cb 332:5faa1b59e870
   111 
   111 
   112   In our opinion, there is clearly a need for investigating correct
   112   In our opinion, there is clearly a need for investigating correct
   113   algorithms for PIP. A few specifications for PIP exist (in English)
   113   algorithms for PIP. A few specifications for PIP exist (in English)
   114   and also a few high-level descriptions of implementations (e.g.~in
   114   and also a few high-level descriptions of implementations (e.g.~in
   115   the textbook \cite[Section 5.6.5]{Vahalia96}), but they help little
   115   the textbook \cite[Section 5.6.5]{Vahalia96}), but they help little
   116   with actual implementations. That this is a problem in practise is
   116   with actual implementations. That this is a problem in practice is
   117   proved by an email from Baker, who wrote on 13 July 2009 on the Linux
   117   proved by an email from Baker, who wrote on 13 July 2009 on the Linux
   118   Kernel mailing list:
   118   Kernel mailing list:
   119 
   119 
   120   \begin{quote}
   120   \begin{quote}
   121   \it{}``I observed in the kernel code (to my disgust), the Linux PIP
   121   \it{}``I observed in the kernel code (to my disgust), the Linux PIP
   352   release a resource. This means we need to include threads that transitively
   352   release a resource. This means we need to include threads that transitively
   353   wait for a resource being released (in the picture above this means the dependants
   353   wait for a resource being released (in the picture above this means the dependants
   354   of @{text "th\<^isub>0"} are @{text "th\<^isub>1"} and @{text "th\<^isub>2"}, which wait for resource @{text "cs\<^isub>1"}, 
   354   of @{text "th\<^isub>0"} are @{text "th\<^isub>1"} and @{text "th\<^isub>2"}, which wait for resource @{text "cs\<^isub>1"}, 
   355   but also @{text "th\<^isub>3"}, 
   355   but also @{text "th\<^isub>3"}, 
   356   which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which
   356   which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which
   357   in turn needs to wait for @{text "th\<^isub>0"} to finish). If there is a circle in a RAG, then clearly
   357   in turn needs to wait for @{text "th\<^isub>0"} to finish). If there is a circle of dependencies 
       
   358   in a RAG, then clearly
   358   we have a deadlock. Therefore when a thread requests a resource,
   359   we have a deadlock. Therefore when a thread requests a resource,
   359   we must ensure that the resulting RAG is not circular. 
   360   we must ensure that the resulting RAG is not circular. 
   360 
   361 
   361   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   362   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   362   state @{text s}. It is defined as
   363   state @{text s}. It is defined as
   389   \noindent
   390   \noindent
   390   The first function is a waiting queue function (that is, it takes a
   391   The first function is a waiting queue function (that is, it takes a
   391   resource @{text "cs"} and returns the corresponding list of threads
   392   resource @{text "cs"} and returns the corresponding list of threads
   392   that lock, respectively wait for, it); the second is a function that
   393   that lock, respectively wait for, it); the second is a function that
   393   takes a thread and returns its current precedence (see
   394   takes a thread and returns its current precedence (see
   394   \eqref{cpreced}). We assume the usual getter and setter methods for
   395   the definition in \eqref{cpreced}). We assume the usual getter and setter methods for
   395   such records.
   396   such records.
   396 
   397 
   397   In the initial state, the scheduler starts with all resources unlocked (the corresponding 
   398   In the initial state, the scheduler starts with all resources unlocked (the corresponding 
   398   function is defined in \eqref{allunlocked}) and the
   399   function is defined in \eqref{allunlocked}) and the
   399   current precedence of every thread is initialised with @{term "Prc 0 0"}; that means 
   400   current precedence of every thread is initialised with @{term "Prc 0 0"}; that means 
   400   \mbox{@{abbrev initial_cprec}}. Therefore
   401   \mbox{@{abbrev initial_cprec}}. Therefore
   401   we have for the initial state
   402   we have for the initial shedule state
   402 
   403 
   403   \begin{isabelle}\ \ \ \ \ %%%
   404   \begin{isabelle}\ \ \ \ \ %%%
   404   \begin{tabular}{@ {}l}
   405   \begin{tabular}{@ {}l}
   405   @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ 
   406   @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ 
   406   \hspace{5mm}@{term "(|wq_fun = all_unlocked, cprec_fun = (\<lambda>_::thread. Prc 0 0)|)"}
   407   \hspace{5mm}@{term "(|wq_fun = all_unlocked, cprec_fun = (\<lambda>_::thread. Prc 0 0)|)"}
   510   @{thm runing_def}\\
   511   @{thm runing_def}\\
   511   \end{tabular}
   512   \end{tabular}
   512   \end{isabelle}
   513   \end{isabelle}
   513 
   514 
   514   \noindent
   515   \noindent
   515   In this definition @{term "DUMMY ` DUMMY"} stands for the image of a set under a function.
   516   In the second definition @{term "DUMMY ` DUMMY"} stands for the image of a set under a function.
   516   Note that in the initial state, that is where the list of events is empty, the set 
   517   Note that in the initial state, that is where the list of events is empty, the set 
   517   @{term threads} is empty and therefore there is neither a thread ready nor running.
   518   @{term threads} is empty and therefore there is neither a thread ready nor running.
   518   If there is one or more threads ready, then there can only be \emph{one} thread
   519   If there is one or more threads ready, then there can only be \emph{one} thread
   519   running, namely the one whose current precedence is equal to the maximum of all ready 
   520   running, namely the one whose current precedence is equal to the maximum of all ready 
   520   threads. We use sets to capture both possibilities.
   521   threads. We use sets to capture both possibilities.
   525   @{thm holdents_def}
   526   @{thm holdents_def}
   526   \end{isabelle}
   527   \end{isabelle}
   527 
   528 
   528   Finally we can define what a \emph{valid state} is in our model of PIP. For
   529   Finally we can define what a \emph{valid state} is in our model of PIP. For
   529   example we cannot expect to be able to exit a thread, if it was not
   530   example we cannot expect to be able to exit a thread, if it was not
   530   created yet. These validity constraints on states are characterised by the
   531   created yet. This would cause havoc  in any scheduler. 
       
   532   These validity constraints on states are characterised by the
   531   inductive predicate @{term "step"} and @{term vt}. We first give five inference rules
   533   inductive predicate @{term "step"} and @{term vt}. We first give five inference rules
   532   for @{term step} relating a state and an event that can happen next.
   534   for @{term step} relating a state and an event that can happen next.
   533 
   535 
   534   \begin{center}
   536   \begin{center}
   535   \begin{tabular}{c}
   537   \begin{tabular}{c}
   599 text {* 
   601 text {* 
   600   Sha et al.~state their first correctness criterion for PIP in terms
   602   Sha et al.~state their first correctness criterion for PIP in terms
   601   of the number of low-priority threads \cite[Theorem 3]{Sha90}: if
   603   of the number of low-priority threads \cite[Theorem 3]{Sha90}: if
   602   there are @{text n} low-priority threads, then a blocked job with
   604   there are @{text n} low-priority threads, then a blocked job with
   603   high priority can only be blocked @{text n} times.
   605   high priority can only be blocked @{text n} times.
   604   Their second correctness criterion is stated
   606   Their second correctness criterion is given
   605   in terms of the number of critical resources \cite[Theorem 6]{Sha90}: if there are
   607   in terms of the number of critical resources \cite[Theorem 6]{Sha90}: if there are
   606   @{text m} critical resources, then a blocked job with high priority
   608   @{text m} critical resources, then a blocked job with high priority
   607   can only be blocked @{text m} times. Both results on their own, strictly speaking, do
   609   can only be blocked @{text m} times. Both results on their own, strictly speaking, do
   608   \emph{not} prevent indefinite, or unbounded, Priority Inversion,
   610   \emph{not} prevent indefinite, or unbounded, Priority Inversion,
   609   because if a low-priority thread does not give up its critical
   611   because if a low-priority thread does not give up its critical
   610   resource (the one the high-priority thread is waiting for), then the
   612   resource (the one the high-priority thread is waiting for), then the
   611   high-priority thread can never run.  The argument of Sha et al.~is
   613   high-priority thread can never run.  The argument of Sha et al.~is
   612   that \emph{if} threads release locked resources in a finite amount
   614   that \emph{if} threads release locked resources in a finite amount
   613   of time, then indefinite Priority Inversion cannot occur---the high-priority
   615   of time, then indefinite Priority Inversion cannot occur---the high-priority
   614   thread is guaranteed to run eventually. The assumption is that
   616   thread is guaranteed to run eventually. The assumption is that
   615   programmers always ensure that this is the case.  However, even
   617   programmers must ensure that threads are programmed in this way.  However, even
   616   taking this assumption into account, their correctness properties are
   618   taking this assumption into account, the correctness properties of
   617   \emph{not} true for their version of PIP. As Yodaiken
   619   Sha et al.~are
       
   620   \emph{not} true for their version of PIP---despide being ``proved''. As Yodaiken
   618   \cite{Yodaiken02} pointed out: If a low-priority thread possesses
   621   \cite{Yodaiken02} pointed out: If a low-priority thread possesses
   619   locks to two resources for which two high-priority threads are
   622   locks to two resources for which two high-priority threads are
   620   waiting for, then lowering the priority prematurely after giving up
   623   waiting for, then lowering the priority prematurely after giving up
   621   only one lock, can cause indefinite Priority Inversion for one of the
   624   only one lock, can cause indefinite Priority Inversion for one of the
   622   high-priority threads, invalidating their two bounds.
   625   high-priority threads, invalidating their two bounds.
   623 
   626 
   624   Even when fixed, their proof idea does not seem to go through for
   627   Even when fixed, their proof idea does not seem to go through for
   625   us, because of the way we have set up our formal model of PIP.  The
   628   us, because of the way we have set up our formal model of PIP.  One
   626   reason is that we allow that critical sections can intersect
   629   reason is that we allow that critical sections can intersect
   627   (something Sha et al.~explicitly exclude).  Therefore we have a 
   630   (something Sha et al.~explicitly exclude).  Therefore we have designed a 
   628   different correctness criterion for PIP. The idea behind our
   631   different correctness criterion for PIP. The idea behind our
   629   criterion is as follows: for all states @{text
   632   criterion is as follows: for all states @{text
   630   s}, we know the corresponding thread @{text th} with the highest
   633   s}, we know the corresponding thread @{text th} with the highest
   631   precedence; we show that in every future state (denoted by @{text
   634   precedence; we show that in every future state (denoted by @{text
   632   "s' @ s"}) in which @{text th} is still alive, either @{text th} is
   635   "s' @ s"}) in which @{text th} is still alive, either @{text th} is
   680   \end{tabular}
   683   \end{tabular}
   681   \end{isabelle}
   684   \end{isabelle}
   682   \end{quote}
   685   \end{quote}
   683 
   686 
   684   \noindent
   687   \noindent
       
   688   The locale mechanism of Isabelle helps us to manage conveniently such assumptions~\cite{Haftmann08}.
   685   Under these assumptions we will prove the following correctness property:
   689   Under these assumptions we will prove the following correctness property:
   686 
   690 
   687   \begin{theorem}\label{mainthm}
   691   \begin{theorem}\label{mainthm}
   688   Given the assumptions about states @{text "s"} and @{text "s' @ s"},
   692   Given the assumptions about states @{text "s"} and @{text "s' @ s"},
   689   the thread @{text th} and the events in @{text "s'"},
   693   the thread @{text th} and the events in @{text "s'"},
   697   highest precedence in the state @{text s}, can only be blocked in
   701   highest precedence in the state @{text s}, can only be blocked in
   698   the state @{text "s' @ s"} by a thread @{text th'} that already
   702   the state @{text "s' @ s"} by a thread @{text th'} that already
   699   existed in @{text s} and requested or had a lock on at least 
   703   existed in @{text s} and requested or had a lock on at least 
   700   one resource---that means the thread was not \emph{detached} in @{text s}. 
   704   one resource---that means the thread was not \emph{detached} in @{text s}. 
   701   As we shall see shortly, that means there are only finitely 
   705   As we shall see shortly, that means there are only finitely 
   702   many threads that can block @{text th} and then need to run
   706   many threads that can block @{text th} in this way and then they 
   703   with the same current precedence as @{text th}.
   707   need to run with the same current precedence as @{text th}.
   704 
   708 
   705   Like in the argument by Sha et al.~our
   709   Like in the argument by Sha et al.~our
   706   finite bound does not guarantee absence of indefinite Priority
   710   finite bound does not guarantee absence of indefinite Priority
   707   Inversion. For this we further have to assume that every thread
   711   Inversion. For this we further have to assume that every thread
   708   gives up its resources (that means get detached) after a finite amount of time. We found that
   712   gives up its resources after a finite amount of time. We found that
   709   this assumption is awkward to formalise in our model. Therefore we
   713   this assumption is awkward to formalise in our model. Therefore we
   710   leave it out and let the programmer assume the responsibility to
   714   leave it out and let the programmer assume the responsibility to
   711   program threads in such a benign manner (in addition to causing no 
   715   program threads in such a benign manner (in addition to causing no 
   712   circularity in the @{text RAG}). In this detail, we do not
   716   circularity in the @{text RAG}). In this detail, we do not
   713   make any progress in comparison with the work by Sha et al.
   717   make any progress in comparison with the work by Sha et al.
   714   However, we are able to combine their two separate bounds into a
   718   However, we are able to combine their two separate bounds into a
   715   single theorem. 
   719   single theorem improving their bound.
   716 
   720 
   717   In what follows we will describe properties of PIP that allow us to prove 
   721   In what follows we will describe properties of PIP that allow us to prove 
   718   Theorem~\ref{mainthm} and, when instructive, briefly describe our argument. 
   722   Theorem~\ref{mainthm} and, when instructive, briefly describe our argument. 
   719   It is relatively easily to see that
   723   It is relatively easily to see that
   720 
   724 
   724   @{thm[mode=IfThen]  finite_threads}
   728   @{thm[mode=IfThen]  finite_threads}
   725   \end{tabular}
   729   \end{tabular}
   726   \end{isabelle}
   730   \end{isabelle}
   727 
   731 
   728   \noindent
   732   \noindent
   729   whereby the second property is by induction of @{term vt}. The next three
   733   The second property is by induction of @{term vt}. The next three
   730   properties are 
   734   properties are 
   731 
   735 
   732   \begin{isabelle}\ \ \ \ \ %%%
   736   \begin{isabelle}\ \ \ \ \ %%%
   733   \begin{tabular}{@ {}l}
   737   \begin{tabular}{@ {}l}
   734   @{thm[mode=IfThen] waiting_unique[of _ _ "cs\<^isub>1" "cs\<^isub>2"]}\\
   738   @{thm[mode=IfThen] waiting_unique[of _ _ "cs\<^isub>1" "cs\<^isub>2"]}\\
   772   then @{text "th' \<notin> running (s' @ s)"}.
   776   then @{text "th' \<notin> running (s' @ s)"}.
   773   \end{lemma}
   777   \end{lemma}
   774 
   778 
   775   \noindent
   779   \noindent
   776   The point of this lemma is that a thread different from @{text th} (which has the highest
   780   The point of this lemma is that a thread different from @{text th} (which has the highest
   777   precedence in @{text s}) not holding any resource cannot be running 
   781   precedence in @{text s}) and not holding any resource, cannot be running 
   778   in the state @{text "s' @ s"}.
   782   in the state @{text "s' @ s"}.
   779 
   783 
   780   \begin{proof}
   784   \begin{proof}
   781   Since thread @{text "th'"} does not hold any resource, no thread can depend on it. 
   785   Since thread @{text "th'"} does not hold any resource, no thread can depend on it. 
   782   Therefore its current precedence @{term "cp (s' @ s) th'"} equals its own precedence
   786   Therefore its current precedence @{term "cp (s' @ s) th'"} equals its own precedence
   791   By defintion of @{text "running"}, @{text "th'"} can not be running in state
   795   By defintion of @{text "running"}, @{text "th'"} can not be running in state
   792   @{text "s' @ s"}, as we had to show.\qed
   796   @{text "s' @ s"}, as we had to show.\qed
   793   \end{proof}
   797   \end{proof}
   794 
   798 
   795   \noindent
   799   \noindent
   796   Since @{text "th'"} is not able to run at state @{text "s' @ s"}, it is not able to 
   800   Since @{text "th'"} is not able to run in state @{text "s' @ s"}, it is not able to 
   797   issue a @{text "P"} or @{text "V"} event. Therefore if @{text "s' @ s"} is extended
   801   issue a @{text "P"} or @{text "V"} event. Therefore if @{text "s' @ s"} is extended
   798   one step further, @{text "th'"} still cannot hold any resource. The situation will 
   802   one step further, @{text "th'"} still cannot hold any resource. The situation will 
   799   not change in further extensions as long as @{text "th"} holds the highest precedence.
   803   not change in further extensions as long as @{text "th"} holds the highest precedence.
   800 
   804 
   801   From this lemma we can deduce Theorem~\ref{mainthm}: that @{text th} can only be 
   805   From this lemma we can deduce Theorem~\ref{mainthm}: that @{text th} can only be 
   802   blocked by a thread @{text th'} that
   806   blocked by a thread @{text th'} that
   803   held some resource in state @{text s} (that is not @{text "detached"}). And furthermore
   807   held some resource in state @{text s} (that is not @{text "detached"}). And furthermore
   804   that the current precedence of @{text th'} in state @{text "(s' @ s)"} must be equal to the 
   808   that the current precedence of @{text th'} in state @{text "(s' @ s)"} must be equal to the 
   805   precedence of @{text th} in @{text "s"}.
   809   precedence of @{text th} in @{text "s"}.
   806   We show this theorem by induction on @{text "s'"} using Lemma~\ref{mainlem}.
   810   We show this theorem by induction on @{text "s'"} using Lemma~\ref{mainlem}.
   807   This theorem gives a stricter bound on the processes that can block @{text th}:
   811   This theorem gives a stricter bound on the processes that can block @{text th} than the
       
   812   one obtained by Sha et al.~\cite{Sha90}:
   808   only threads that were alive in state @{text s} and moreover held a resource.
   813   only threads that were alive in state @{text s} and moreover held a resource.
   809   This means our bound is in terms of both---alive threads in state @{text s}
   814   This means our bound is in terms of both---alive threads in state @{text s}
   810   and number of critical resources. Finally, the theorem establishes that the blocking threads have the
   815   and number of critical resources. Finally, the theorem establishes that the blocking threads have the
   811   current precedence raised to the precedence of @{text th}.
   816   current precedence raised to the precedence of @{text th}.
   812 
   817 
   944   al.~\cite{Sha90}), we found that the formalisation can even help us
   949   al.~\cite{Sha90}), we found that the formalisation can even help us
   945   with efficiently implementing PIP.
   950   with efficiently implementing PIP.
   946 
   951 
   947   For example Baker complained that calculating the current precedence
   952   For example Baker complained that calculating the current precedence
   948   in PIP is quite ``heavy weight'' in Linux (see the Introduction).
   953   in PIP is quite ``heavy weight'' in Linux (see the Introduction).
   949   In our model of PIP the current precedence of a thread in a state s
   954   In our model of PIP the current precedence of a thread in a state @{text s}
   950   depends on all its dependants---a ``global'' transitive notion,
   955   depends on all its dependants---a ``global'' transitive notion,
   951   which is indeed heavy weight (see Def.~shown in \eqref{cpreced}).
   956   which is indeed heavy weight (see Def.~shown in \eqref{cpreced}).
   952   We can however improve upon this. For this let us define the notion
   957   We can however improve upon this. For this let us define the notion
   953   of @{term children} of a thread @{text th} in a state @{text s} as
   958   of @{term children} of a thread @{text th} in a state @{text s} as
   954 
   959 
   957   @{thm children_def2}
   962   @{thm children_def2}
   958   \end{tabular}
   963   \end{tabular}
   959   \end{isabelle}
   964   \end{isabelle}
   960 
   965 
   961   \noindent
   966   \noindent
   962   where a child is a thread that is one ``hop'' away from the tread
   967   where a child is a thread that is only one ``hop'' away from the tread
   963   @{text th} in the @{term RAG} (and waiting for @{text th} to release
   968   @{text th} in the @{term RAG} (and waiting for @{text th} to release
   964   a resource). We can prove that
   969   a resource). We can prove the following lemma.
   965 
   970 
   966   \begin{lemma}\label{childrenlem}
   971   \begin{lemma}\label{childrenlem}
   967   @{text "If"} @{thm (prem 1) cp_rec} @{text "then"}
   972   @{text "If"} @{thm (prem 1) cp_rec} @{text "then"}
   968   \begin{center}
   973   \begin{center}
   969   @{thm (concl) cp_rec}.
   974   @{thm (concl) cp_rec}.
   978   precedence is computed in this more efficient manner, the selection
   983   precedence is computed in this more efficient manner, the selection
   979   of the thread with highest precedence from a set of ready threads is
   984   of the thread with highest precedence from a set of ready threads is
   980   a standard scheduling operation implemented in most operating
   985   a standard scheduling operation implemented in most operating
   981   systems.
   986   systems.
   982 
   987 
   983   Of course the main implementation work for PIP involves the
   988   Of course the main work for implementing PIP involves the
   984   scheduler and coding how it should react to events.  Below we
   989   scheduler and coding how it should react to events.  Below we
   985   outline how our formalisation guides this implementation for each
   990   outline how our formalisation guides this implementation for each
   986   kind of event.\smallskip
   991   kind of event.\smallskip
   987 *}
   992 *}
   988 
   993 
  1003   @{thm[mode=IfThen] eq_cp}
  1008   @{thm[mode=IfThen] eq_cp}
  1004   \end{tabular}
  1009   \end{tabular}
  1005   \end{isabelle}
  1010   \end{isabelle}
  1006 
  1011 
  1007   \noindent
  1012   \noindent
  1008   This means we do not have recalculate the @{text RAG} and also none of the
  1013   This means in an implementation we do not have recalculate the @{text RAG} and also none of the
  1009   current precedences of the other threads. The current precedence of the created
  1014   current precedences of the other threads. The current precedence of the created
  1010   thread @{text th} is just its precedence, namely the pair @{term "(prio, length (s::event list))"}.
  1015   thread @{text th} is just its precedence, namely the pair @{term "(prio, length (s::event list))"}.
  1011   \smallskip
  1016   \smallskip
  1012   *}
  1017   *}
  1013 (*<*)
  1018 (*<*)
  1054   \noindent
  1059   \noindent
  1055   The first property is again telling us we do not need to change the @{text RAG}. The second
  1060   The first property is again telling us we do not need to change the @{text RAG}. The second
  1056   however states that only threads that are \emph{not} dependants of @{text th} have their
  1061   however states that only threads that are \emph{not} dependants of @{text th} have their
  1057   current precedence unchanged. For the others we have to recalculate the current
  1062   current precedence unchanged. For the others we have to recalculate the current
  1058   precedence. To do this we can start from @{term "th"} 
  1063   precedence. To do this we can start from @{term "th"} 
  1059   and follow the @{term "depend"}-chains to recompute the @{term "cp"} of every 
  1064   and follow the @{term "depend"}-edges to recompute  using Lemma~\ref{childrenlem} 
  1060   thread encountered on the way using Lemma~\ref{childrenlem}. Since the @{term "depend"}
  1065   the @{term "cp"} of every 
       
  1066   thread encountered on the way. Since the @{term "depend"}
  1061   is loop free, this procedure will always stop. The following two lemmas show, however, 
  1067   is loop free, this procedure will always stop. The following two lemmas show, however, 
  1062   that this procedure can actually stop often earlier without having to consider all
  1068   that this procedure can actually stop often earlier without having to consider all
  1063   dependants.
  1069   dependants.
  1064 
  1070 
  1065   \begin{isabelle}\ \ \ \ \ %%%
  1071   \begin{isabelle}\ \ \ \ \ %%%
  1069   @{text "then"} @{thm (concl) eq_up}.
  1075   @{text "then"} @{thm (concl) eq_up}.
  1070   \end{tabular}
  1076   \end{tabular}
  1071   \end{isabelle}
  1077   \end{isabelle}
  1072 
  1078 
  1073   \noindent
  1079   \noindent
  1074   The first states that if the current precedence of @{text th} is unchanged,
  1080   The first lemma states that if the current precedence of @{text th} is unchanged,
  1075   then the procedure can stop immediately (all dependent threads have their @{term cp}-value unchanged).
  1081   then the procedure can stop immediately (all dependent threads have their @{term cp}-value unchanged).
  1076   The second states that if an intermediate @{term cp}-value does not change, then
  1082   The second states that if an intermediate @{term cp}-value does not change, then
  1077   the procedure can also stop, because none of its dependent threads will
  1083   the procedure can also stop, because none of its dependent threads will
  1078   have their current precedence changed.
  1084   have their current precedence changed.
  1079   \smallskip
  1085   \smallskip
  1088   \colorbox{mygrey}{@{term "V th cs"}:} We assume that @{text s'} and 
  1094   \colorbox{mygrey}{@{term "V th cs"}:} We assume that @{text s'} and 
  1089   @{term "s \<equiv> V th cs#s'"} are both valid. We have to consider two
  1095   @{term "s \<equiv> V th cs#s'"} are both valid. We have to consider two
  1090   subcases: one where there is a thread to ``take over'' the released
  1096   subcases: one where there is a thread to ``take over'' the released
  1091   resource @{text cs}, and one where there is not. Let us consider them
  1097   resource @{text cs}, and one where there is not. Let us consider them
  1092   in turn. Suppose in state @{text s}, the thread @{text th'} takes over
  1098   in turn. Suppose in state @{text s}, the thread @{text th'} takes over
  1093   resource @{text cs} from thread @{text th}. We can show
  1099   resource @{text cs} from thread @{text th}. We can prove
  1094 
  1100 
  1095 
  1101 
  1096   \begin{isabelle}\ \ \ \ \ %%%
  1102   \begin{isabelle}\ \ \ \ \ %%%
  1097   @{thm depend_s}
  1103   @{thm depend_s}
  1098   \end{isabelle}
  1104   \end{isabelle}
  1099   
  1105   
  1100   \noindent
  1106   \noindent
  1101   which shows how the @{text RAG} needs to be changed. This also suggests
  1107   which shows how the @{text RAG} needs to be changed. The next lemma suggests
  1102   how the current precedences need to be recalculated. For threads that are
  1108   how the current precedences need to be recalculated. For threads that are
  1103   not @{text "th"} and @{text "th'"} nothing needs to be changed, since we
  1109   not @{text "th"} and @{text "th'"} nothing needs to be changed, since we
  1104   can show
  1110   can show
  1105 
  1111 
  1106   \begin{isabelle}\ \ \ \ \ %%%
  1112   \begin{isabelle}\ \ \ \ \ %%%
  1125 (*<*)
  1131 (*<*)
  1126 end
  1132 end
  1127 context step_P_cps_e
  1133 context step_P_cps_e
  1128 begin
  1134 begin
  1129 (*>*)
  1135 (*>*)
  1130 
       
  1131 text {*
  1136 text {*
  1132   \noindent
  1137   \noindent
  1133   \colorbox{mygrey}{@{term "P th cs"}:} We assume that @{text s'} and 
  1138   \colorbox{mygrey}{@{term "P th cs"}:} We assume that @{text s'} and 
  1134   @{term "s \<equiv> P th cs#s'"} are both valid. We again have to analyse two subcases, namely
  1139   @{term "s \<equiv> P th cs#s'"} are both valid. We again have to analyse two subcases, namely
  1135   the one where @{text cs} is locked, and where it is not. We treat the second case
  1140   the one where @{text cs} is locked, and where it is not. We treat the second case
  1158   \noindent
  1163   \noindent
  1159   That means we have to add a waiting edge to the @{text RAG}. Furthermore
  1164   That means we have to add a waiting edge to the @{text RAG}. Furthermore
  1160   the current precedence for all threads that are not dependants of @{text th}
  1165   the current precedence for all threads that are not dependants of @{text th}
  1161   are unchanged. For the others we need to follow the edges 
  1166   are unchanged. For the others we need to follow the edges 
  1162   in the @{text RAG} and recompute the @{term "cp"}. However, like in the 
  1167   in the @{text RAG} and recompute the @{term "cp"}. However, like in the 
  1163   @case of {text Set}, this operation can stop often earlier, namely when intermediate
  1168   case of @{text Set}, this operation can stop often earlier, namely when intermediate
  1164   values do not change.
  1169   values do not change.
  1165   *}
  1170   *}
  1166 (*<*)
  1171 (*<*)
  1167 end
  1172 end
  1168 (*>*)
  1173 (*>*)
  1169 text {*
  1174 text {*
  1170   \noindent
  1175   \noindent
  1171   A pleasing result of our formalisation is that the properties in
  1176   As can be seen, a pleasing byproduct of our formalisation is that the properties in
  1172   this section closely inform an implementation of PIP:  Whether the
  1177   this section closely inform an implementation of PIP, namely whether the
  1173   @{text RAG} needs to be reconfigured or current precedences need to
  1178   @{text RAG} needs to be reconfigured or current precedences need to
  1174   recalculated for an event is given by a lemma we proved.
  1179   by recalculated for an event. This information is provided by the lemmas we proved.
  1175 *}
  1180 *}
  1176 
  1181 
  1177 section {* Conclusion *}
  1182 section {* Conclusion *}
  1178 
  1183 
  1179 text {* 
  1184 text {* 
  1180   The Priority Inheritance Protocol (PIP) is a classic textbook
  1185   The Priority Inheritance Protocol (PIP) is a classic textbook
  1181   algorithm used in real-time operating systems in order to avoid the problem of
  1186   algorithm used in many real-time operating systems in order to avoid the problem of
  1182   Priority Inversion.  Although classic and widely used, PIP does have
  1187   Priority Inversion.  Although classic and widely used, PIP does have
  1183   its faults: for example it does not prevent deadlocks in cases where threads
  1188   its faults: for example it does not prevent deadlocks in cases where threads
  1184   have circular lock dependencies.
  1189   have circular lock dependencies.
  1185 
  1190 
  1186   We had two goals in mind with our formalisation of PIP: One is to
  1191   We had two goals in mind with our formalisation of PIP: One is to
  1198   \cite{Wang09}.
  1203   \cite{Wang09}.
  1199 
  1204 
  1200   The second goal of our formalisation is to provide a specification for actually
  1205   The second goal of our formalisation is to provide a specification for actually
  1201   implementing PIP. Textbooks, for example \cite[Section 5.6.5]{Vahalia96},
  1206   implementing PIP. Textbooks, for example \cite[Section 5.6.5]{Vahalia96},
  1202   explain how to use various implementations of PIP and abstractly
  1207   explain how to use various implementations of PIP and abstractly
  1203   discuss their properties, but surprisingly lack most details for a
  1208   discuss their properties, but surprisingly lack most details important for a
  1204   programmer who wants to implement PIP.  That this is an issue in practice is illustrated by the
  1209   programmer who wants to implement PIP (similarly Sha et al.~\cite{Sha90}).  
       
  1210   That this is an issue in practice is illustrated by the
  1205   email from Baker we cited in the Introduction. We achieved also this
  1211   email from Baker we cited in the Introduction. We achieved also this
  1206   goal: The formalisation gives the first author enough data to enable
  1212   goal: The formalisation gives the first author enough data to enable
  1207   his undergraduate students to implement PIP (as part of their OS course)
  1213   his undergraduate students to implement PIP (as part of their OS course)
  1208   on top of PINTOS, a small operating system for teaching
  1214   on top of PINTOS, a small operating system for teaching
  1209   purposes. A byproduct of our formalisation effort is that nearly all
  1215   purposes. A byproduct of our formalisation effort is that nearly all
  1210   design choices for the PIP scheduler are backed up with a proved
  1216   design choices for the PIP scheduler are backed up with a proved
  1211   lemma. We were also able to establish the property that the choice of
  1217   lemma. We were also able to establish the property that the choice of
  1212   the next thread which takes over a lock is irrelevant for the correctness
  1218   the next thread which takes over a lock is irrelevant for the correctness
  1213   of PIP. Earlier model checking approaches which verified implementations
  1219   of PIP. Earlier model checking approaches which verified particular implementations
  1214   of PIP \cite{Faria08,Jahier09,Wellings07} cannot
  1220   of PIP \cite{Faria08,Jahier09,Wellings07} cannot
  1215   provide this kind of ``deep understanding'' about the principles behind 
  1221   provide this kind of ``deep understanding'' about the principles behind 
  1216   PIP and its correctness.
  1222   PIP and its correctness.
  1217 
  1223 
  1218   PIP is a scheduling algorithm for single-processor systems. We are
  1224   PIP is a scheduling algorithm for single-processor systems. We are
  1221   teaching. Priority Inversion certainly occurs also in
  1227   teaching. Priority Inversion certainly occurs also in
  1222   multi-processor systems.  However, the surprising answer, according
  1228   multi-processor systems.  However, the surprising answer, according
  1223   to \cite{Steinberg10}, is that except for one unsatisfactory
  1229   to \cite{Steinberg10}, is that except for one unsatisfactory
  1224   proposal nobody has a good idea for how PIP should be modified to
  1230   proposal nobody has a good idea for how PIP should be modified to
  1225   work correctly on multi-processor systems. The difficulties become
  1231   work correctly on multi-processor systems. The difficulties become
  1226   clear when considering that locking and releasing a resource always
  1232   clear when considering the fact that locking and releasing a resource always
  1227   requires a small amount of time. If processes work independently,
  1233   requires a small amount of time. If processes work independently,
  1228   then a low priority process can ``steal'' in such an unguarded
  1234   then a low priority process can ``steal'' in such an unguarded
  1229   moment a lock for a resource that was supposed allow a high-priority
  1235   moment a lock for a resource that was supposed to allow a high-priority
  1230   process to run next. Thus the problem of Priority Inversion is not
  1236   process to run next. Thus the problem of Priority Inversion is not
  1231   really prevented. It seems difficult to design a PIP-algorithm with
  1237   really prevented by the classic PIP. It seems difficult to design a PIP-algorithm with
  1232   a meaningful correctness property on a multi-processor systems where
  1238   a meaningful correctness property on a multi-processor systems where
  1233   processes work independently.  We can imagine PIP to be of use in
  1239   processes work independently.  We can imagine PIP to be of use in
  1234   situations where processes are \emph{not} independent, but
  1240   situations where processes are \emph{not} independent, but
  1235   coordinated via a master process that distributes work over some
  1241   coordinated via a master process that distributes work over some
  1236   slave processes. However, a formal investigation of this is beyond
  1242   slave processes. However, a formal investigation of this idea is beyond
  1237   the scope of this paper.  We are not aware of any proofs in this
  1243   the scope of this paper.  We are not aware of any proofs in this
  1238   area, not even informal ones.
  1244   area, not even informal or flawed ones.
  1239 
  1245 
  1240   The most closely related work to ours is the formal verification in
  1246   The most closely related work to ours is the formal verification in
  1241   PVS for Priority Ceiling done by Dutertre \cite{dutertre99b}. His formalisation
  1247   PVS of the Priority Ceiling Protocol done by Dutertre 
  1242   consists of 407 lemmas and 2500 lines of ``specification'' (we do not
  1248   \cite{dutertre99b}---another solution to the Priority Inversion 
  1243   know whether this includes also code for proofs).  Our formalisation
  1249   problem, which however needs
       
  1250   static analysis of programs in order to avoid it.
       
  1251   His formalisation consists of 407 lemmas and 2500 lines of (PVS) code.  Our formalisation
  1244   consists of around 210 lemmas and overall 6950 lines of readable Isabelle/Isar
  1252   consists of around 210 lemmas and overall 6950 lines of readable Isabelle/Isar
  1245   code with a few apply-scripts interspersed. The formal model of PIP
  1253   code with a few apply-scripts interspersed. The formal model of PIP
  1246   is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary
  1254   is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary
  1247   definitions and proofs took 770 lines of code. The properties relevant
  1255   definitions and proofs span over 770 lines of code. The properties relevant
  1248   for an implementation took 2000 lines. The code of our formalisation 
  1256   for an implementation require 2000 lines. The code of our formalisation 
  1249   can be downloaded from\\
  1257   can be downloaded from
  1250   \url{http://www.dcs.kcl.ac.uk/staff/urbanc/pip.html}.
  1258   \url{http://www.dcs.kcl.ac.uk/staff/urbanc/pip.html}.
  1251 
  1259 
  1252   \bibliographystyle{plain}
  1260   \bibliographystyle{plain}
  1253   \bibliography{root}
  1261   \bibliography{root}
  1254 *}
  1262 *}