Journal/Paper.thy
changeset 32 e861aff29655
parent 28 7fa738a9615a
child 33 9b9f2117561f
equal deleted inserted replaced
31:8f026b608378 32:e861aff29655
     9 
     9 
    10 notation (latex output)
    10 notation (latex output)
    11   Cons ("_::_" [78,77] 73) and
    11   Cons ("_::_" [78,77] 73) and
    12   vt ("valid'_state") and
    12   vt ("valid'_state") and
    13   runing ("running") and
    13   runing ("running") and
    14   birthtime ("last'_set") and
       
    15   If  ("(\<^raw:\textrm{>if\<^raw:}> (_)/ \<^raw:\textrm{>then\<^raw:}> (_)/ \<^raw:\textrm{>else\<^raw:}> (_))" 10) and
    14   If  ("(\<^raw:\textrm{>if\<^raw:}> (_)/ \<^raw:\textrm{>then\<^raw:}> (_)/ \<^raw:\textrm{>else\<^raw:}> (_))" 10) and
    16   Prc ("'(_, _')") and
    15   Prc ("'(_, _')") and
    17   holding ("holds") and
    16   holding ("holds") and
    18   waiting ("waits") and
    17   waiting ("waits") and
    19   Th ("T") and
    18   Th ("T") and
    20   Cs ("C") and
    19   Cs ("C") and
    21   readys ("ready") and
    20   readys ("ready") and
    22   depend ("RAG") and 
    21   depend ("RAG") and 
    23   preced ("prec") and
    22   preced ("prec") and
    24   cpreced ("cprec") and
    23   cpreced ("cprec") and
    25   dependents ("dependants") and
       
    26   cp ("cprec") and
    24   cp ("cprec") and
    27   holdents ("resources") and
    25   holdents ("resources") and
    28   original_priority ("priority") and
       
    29   DUMMY  ("\<^raw:\mbox{$\_\!\_$}>")
    26   DUMMY  ("\<^raw:\mbox{$\_\!\_$}>")
    30  
    27  
    31   
    28   
    32 (*>*)
    29 (*>*)
    33 
    30 
    81   priority $M$. While a few other solutions exist for the Priority
    78   priority $M$. While a few other solutions exist for the Priority
    82   Inversion problem, PIP is one that is widely deployed and
    79   Inversion problem, PIP is one that is widely deployed and
    83   implemented. This includes VxWorks (a proprietary real-time OS used
    80   implemented. This includes VxWorks (a proprietary real-time OS used
    84   in the Mars Pathfinder mission, in Boeing's 787 Dreamliner, Honda's
    81   in the Mars Pathfinder mission, in Boeing's 787 Dreamliner, Honda's
    85   ASIMO robot, etc.) and ThreadX (another proprietary real-time OS
    82   ASIMO robot, etc.) and ThreadX (another proprietary real-time OS
    86   used in HP inkjet printers \cite{ThreadX}), but also
    83   used in nearly all HP inkjet printers \cite{ThreadX}), but also
    87   the POSIX 1003.1c Standard realised for
    84   the POSIX 1003.1c Standard realised for
    88   example in libraries for FreeBSD, Solaris and Linux. 
    85   example in libraries for FreeBSD, Solaris and Linux. 
    89 
    86 
    90   Two advantages of PIP are that it is deterministic and that increasing the priority of a thread
    87   Two advantages of PIP are that it is deterministic and that increasing the priority of a thread
    91   can be performed dynamically by the scheduler.
    88   can be performed dynamically by the scheduler.
    92   This is in contrast to \emph{Priority Ceiling}
    89   This is in contrast to \emph{Priority Ceiling}
    93   \cite{Sha90}, another solution to the Priority Inversion problem,
    90   \cite{Sha90}, another solution to the Priority Inversion problem,
    94   which requires static analysis of the program in order to prevent
    91   which requires static analysis of the program in order to prevent
    95   Priority Inversion, and also in contrast to the Windows NT scheduler, which avoids
    92   Priority Inversion, and also in contrast to the approach taken in the Windows NT scheduler, which avoids
    96   this problem by randomly boosting the priority of ready low-priority threads
    93   this problem by randomly boosting the priority of ready low-priority threads
    97   (see for instance~\cite{WINDOWSNT}).
    94   (see for instance~\cite{WINDOWSNT}).
    98   However, there has also been strong criticism against
    95   However, there has also been strong criticism against
    99   PIP. For instance, PIP cannot prevent deadlocks when lock
    96   PIP. For instance, PIP cannot prevent deadlocks when lock
   100   dependencies are circular, and also blocking times can be
    97   dependencies are circular, and also blocking times can be
   139 
   136 
   140   Yodaiken \cite{Yodaiken02} and also Moylan et al.~\cite{deinheritance} 
   137   Yodaiken \cite{Yodaiken02} and also Moylan et al.~\cite{deinheritance} 
   141   point to a subtlety that had been
   138   point to a subtlety that had been
   142   overlooked in the informal proof by Sha et al. They specify in
   139   overlooked in the informal proof by Sha et al. They specify in
   143   \cite{Sha90} that after the thread (whose priority has been raised)
   140   \cite{Sha90} that after the thread (whose priority has been raised)
   144   completes its critical section and releases the lock, it ``returns
   141   completes its critical section and releases the lock, it ``{\it returns
   145   to its original priority level.'' This leads them to believe that an
   142   to its original priority level}''. This leads them to believe that an
   146   implementation of PIP is ``rather straightforward''~\cite{Sha90}.
   143   implementation of PIP is ``{\it rather straightforward}''~\cite{Sha90}.
   147   Unfortunately, as Yodaiken and Moylan et al.~point out, this behaviour is too
   144   Unfortunately, as Yodaiken and Moylan et al.~point out, this behaviour is too
   148   simplistic.  Consider the case where the low priority thread $L$
   145   simplistic. Moylan et al.~write that there are ``{\it some hidden traps}''. 
       
   146   Consider the case where the low priority thread $L$
   149   locks \emph{two} resources, and two high-priority threads $H$ and
   147   locks \emph{two} resources, and two high-priority threads $H$ and
   150   $H'$ each wait for one of them.  If $L$ releases one resource
   148   $H'$ each wait for one of them.  If $L$ releases one resource
   151   so that $H$, say, can proceed, then we still have Priority Inversion
   149   so that $H$, say, can proceed, then we still have Priority Inversion
   152   with $H'$ (which waits for the other resource). The correct
   150   with $H'$ (which waits for the other resource). The correct
   153   behaviour for $L$ is to switch to the highest remaining priority of
   151   behaviour for $L$ is to switch to the highest remaining priority of
   154   the threads that it blocks. A similar error is made in the textbook
   152   the threads that it blocks. A similar error is made in the textbook
   155   \cite[Section 2.3.1]{book} which specifies for a process that 
   153   \cite[Section 2.3.1]{book} which specifies for a process that 
   156   inherited a higher priority and exits a critical section ``it resumes 
   154   inherited a higher priority and exits a critical section ``{\it it resumes 
   157   the priority it had at the point of entry into the critical section''.
   155   the priority it had at the point of entry into the critical section}''.
   158    
   156    
   159   While \cite{book} and
   157   While \cite{book} and
   160   \cite{Sha90} are the only formal publications we have 
   158   \cite{Sha90} are the only formal publications we have 
   161   found that describe the incorrect behaviour, not all, but many
   159   found that describe the incorrect behaviour, not all, but many
   162   informal\footnote{informal as in ``found on the Web''} 
   160   informal\footnote{informal as in ``found on the Web''} 
   182   when a resource is released is irrelevant for PIP being correct---a
   180   when a resource is released is irrelevant for PIP being correct---a
   183   fact that has not been mentioned in the literature and not been used
   181   fact that has not been mentioned in the literature and not been used
   184   in the reference implementation of PIP in PINTOS.  This fact, however, is important
   182   in the reference implementation of PIP in PINTOS.  This fact, however, is important
   185   for an efficient implementation of PIP, because we can give the lock
   183   for an efficient implementation of PIP, because we can give the lock
   186   to the thread with the highest priority so that it terminates more
   184   to the thread with the highest priority so that it terminates more
   187   quickly.  We were also able to generalise the scheduler of Sha
   185   quickly.  We were also being able to generalise the scheduler of Sha
   188   et al.~\cite{Sha90} to the practically relevant case where critical 
   186   et al.~\cite{Sha90} to the practically relevant case where critical 
   189   sections can overlap.
   187   sections can overlap; see Figure~\ref{overlap} below for an example of 
       
   188   this restriction. In the existing literature there is no 
       
   189   proof and also no prove method that cover this generalised case.
       
   190 
       
   191   \begin{figure}
       
   192   \begin{center}
       
   193   \begin{tikzpicture}[scale=1]
       
   194   %%\draw[step=2mm] (0,0) grid (10,2);
       
   195   \draw [->,line width=0.6mm] (0,0) -- (10,0);
       
   196   \draw [->,line width=0.6mm] (0,1.5) -- (10,1.5);
       
   197   \draw [line width=0.6mm, pattern=horizontal lines] (0.8,0) rectangle (4,0.5);
       
   198   \draw [line width=0.6mm, pattern=north east lines] (3.0,0) rectangle (6,0.5);
       
   199   \draw [line width=0.6mm, pattern=vertical lines] (5.0,0) rectangle (9,0.5);
       
   200 
       
   201   \draw [line width=0.6mm, pattern=horizontal lines] (0.6,1.5) rectangle (4.0,2); 
       
   202   \draw [line width=0.6mm, pattern=north east lines] (1.0,1.5) rectangle (3.4,2); 
       
   203   \draw [line width=0.6mm, pattern=vertical lines] (5.0,1.5) rectangle (8.8,2); 
       
   204  
       
   205   \node at (0.8,-0.3) {@{term "P\<^sub>1"}};
       
   206   \node at (3.0,-0.3) {@{term "P\<^sub>2"}};
       
   207   \node at (4.0,-0.3) {@{term "V\<^sub>1"}}; 
       
   208   \node at (5.0,-0.3) {@{term "P\<^sub>3"}};
       
   209   \node at (6.0,-0.3) {@{term "V\<^sub>2"}};
       
   210   \node at (9.0,-0.3) {@{term "V\<^sub>3"}};
       
   211   
       
   212   \node at (0.6,1.2) {@{term "P\<^sub>1"}};
       
   213   \node at (1.0,1.2) {@{term "P\<^sub>2"}};
       
   214   \node at (3.4,1.2) {@{term "V\<^sub>2"}};
       
   215   \node at (4.0,1.2) {@{term "V\<^sub>1"}};
       
   216   \node at (5.0,1.2) {@{term "P\<^sub>3"}};
       
   217   \node at (8.8,1.2) {@{term "V\<^sub>3"}};
       
   218   \node at (10.3,0) {$t$};
       
   219   \node at (10.3,1.5) {$t$};
       
   220 
       
   221   \node at (-0.3,0.2) {$b)$};
       
   222   \node at (-0.3,1.7) {$a)$};
       
   223   \end{tikzpicture}\mbox{}\\[-10mm]\mbox{}
       
   224   \end{center}
       
   225   \caption{Assume a process is over time locking and unlocking, say, three resources.
       
   226   The locking requests are labelled @{term "P\<^sub>1"}, @{term "P\<^sub>2"}, and @{term "P\<^sub>3"} 
       
   227   respectively, and the corresponding unlocking operations are labelled
       
   228   @{term "V\<^sub>1"}, @{term "V\<^sub>2"}, and @{term "V\<^sub>3"}. 
       
   229   Then graph $a)$ shows \emph{properly nested} critical sections as required 
       
   230   by Sha et al.~\cite{Sha90} in their proof---the sections must either be contained within 
       
   231   each other
       
   232   (the section @{term "P\<^sub>2"}--@{term "V\<^sub>2"} is contained in @{term "P\<^sub>1"}--@{term "V\<^sub>1"}) or
       
   233   be independent (@{term "P\<^sub>3"}--@{term "V\<^sub>3"} is independent from the other 
       
   234   two). Graph $b)$ shows the general case where 
       
   235   the locking and unlocking of different critical sections can 
       
   236   overlap.\label{overlap}}
       
   237   \end{figure}
   190 *}
   238 *}
   191 
   239 
   192 section {* Formal Model of the Priority Inheritance Protocol\label{model} *}
   240 section {* Formal Model of the Priority Inheritance Protocol\label{model} *}
   193 
   241 
   194 text {*
   242 text {*
   203   into five categories defined as the datatype:
   251   into five categories defined as the datatype:
   204 
   252 
   205   \begin{isabelle}\ \ \ \ \ %%%
   253   \begin{isabelle}\ \ \ \ \ %%%
   206   \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l}
   254   \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l}
   207   \isacommand{datatype} event 
   255   \isacommand{datatype} event 
   208   & @{text "="} & @{term "Create thread priority"}\\
   256   & @{text "="} & @{term "Create thread priority\<iota>"}\\
   209   & @{text "|"} & @{term "Exit thread"} \\
   257   & @{text "|"} & @{term "Exit thread"} \\
   210   & @{text "|"} & @{term "Set thread priority"} & {\rm reset of the priority for} @{text thread}\\
   258   & @{text "|"} & @{term "Set thread priority\<iota>"} & {\rm reset of the priority for} @{text thread}\\
   211   & @{text "|"} & @{term "P thread cs"} & {\rm request of resource} @{text "cs"} {\rm by} @{text "thread"}\\
   259   & @{text "|"} & @{term "P thread cs"} & {\rm request of resource} @{text "cs"} {\rm by} @{text "thread"}\\
   212   & @{text "|"} & @{term "V thread cs"} & {\rm release of resource} @{text "cs"} {\rm by} @{text "thread"}
   260   & @{text "|"} & @{term "V thread cs"} & {\rm release of resource} @{text "cs"} {\rm by} @{text "thread"}
   213   \end{tabular}}
   261   \end{tabular}}
   214   \end{isabelle}
   262   \end{isabelle}
   215 
   263 
   233   @{term "threads (DUMMY#s)"} & @{text "\<equiv>"} & @{term "threads s"}\\
   281   @{term "threads (DUMMY#s)"} & @{text "\<equiv>"} & @{term "threads s"}\\
   234   \end{tabular}}
   282   \end{tabular}}
   235   \end{isabelle}
   283   \end{isabelle}
   236 
   284 
   237   \noindent
   285   \noindent
   238   In this definition @{term "DUMMY # DUMMY"} stands for list-cons.
   286   In this definition @{term "DUMMY # DUMMY"} stands for list-cons and @{term "[]"} for the empty list.
   239   Another function calculates the priority for a thread @{text "th"}, which is 
   287   Another function calculates the priority for a thread @{text "th"}, which is 
   240   defined as
   288   defined as
   241 
   289 
   242   \begin{isabelle}\ \ \ \ \ %%%
   290   \begin{isabelle}\ \ \ \ \ %%%
   243   \mbox{\begin{tabular}{lcl}
   291   \mbox{\begin{tabular}{lcl}
   244   @{thm (lhs) original_priority.simps(1)[where thread="th"]} & @{text "\<equiv>"} & 
   292   @{thm (lhs) priority.simps(1)[where thread="th"]} & @{text "\<equiv>"} & 
   245     @{thm (rhs) original_priority.simps(1)[where thread="th"]}\\
   293     @{thm (rhs) priority.simps(1)[where thread="th"]}\\
   246   @{thm (lhs) original_priority.simps(2)[where thread="th" and thread'="th'"]} & @{text "\<equiv>"} & 
   294   @{thm (lhs) priority.simps(2)[where thread="th" and thread'="th'"]} & @{text "\<equiv>"} & 
   247     @{thm (rhs) original_priority.simps(2)[where thread="th" and thread'="th'"]}\\
   295     @{thm (rhs) priority.simps(2)[where thread="th" and thread'="th'"]}\\
   248   @{thm (lhs) original_priority.simps(3)[where thread="th" and thread'="th'"]} & @{text "\<equiv>"} & 
   296   @{thm (lhs) priority.simps(3)[where thread="th" and thread'="th'"]} & @{text "\<equiv>"} & 
   249     @{thm (rhs) original_priority.simps(3)[where thread="th" and thread'="th'"]}\\
   297     @{thm (rhs) priority.simps(3)[where thread="th" and thread'="th'"]}\\
   250   @{term "original_priority th (DUMMY#s)"} & @{text "\<equiv>"} & @{term "original_priority th s"}\\
   298   @{term "priority th (DUMMY#s)"} & @{text "\<equiv>"} & @{term "priority th s"}\\
   251   \end{tabular}}
   299   \end{tabular}}
   252   \end{isabelle}
   300   \end{isabelle}
   253 
   301 
   254   \noindent
   302   \noindent
   255   In this definition we set @{text 0} as the default priority for
   303   In this definition we set @{text 0} as the default priority for
   256   threads that have not (yet) been created. The last function we need 
   304   threads that have not (yet) been created. The last function we need 
   257   calculates the ``time'', or index, at which time a process had its 
   305   calculates the ``time'', or index, at which time a thread had its 
   258   priority last set.
   306   priority last set.
   259 
   307 
   260   \begin{isabelle}\ \ \ \ \ %%%
   308   \begin{isabelle}\ \ \ \ \ %%%
   261   \mbox{\begin{tabular}{lcl}
   309   \mbox{\begin{tabular}{lcl}
   262   @{thm (lhs) birthtime.simps(1)[where thread="th"]} & @{text "\<equiv>"} & 
   310   @{thm (lhs) last_set.simps(1)[where thread="th"]} & @{text "\<equiv>"} & 
   263     @{thm (rhs) birthtime.simps(1)[where thread="th"]}\\
   311     @{thm (rhs) last_set.simps(1)[where thread="th"]}\\
   264   @{thm (lhs) birthtime.simps(2)[where thread="th" and thread'="th'"]} & @{text "\<equiv>"} & 
   312   @{thm (lhs) last_set.simps(2)[where thread="th" and thread'="th'"]} & @{text "\<equiv>"} & 
   265     @{thm (rhs) birthtime.simps(2)[where thread="th" and thread'="th'"]}\\
   313     @{thm (rhs) last_set.simps(2)[where thread="th" and thread'="th'"]}\\
   266   @{thm (lhs) birthtime.simps(3)[where thread="th" and thread'="th'"]} & @{text "\<equiv>"} & 
   314   @{thm (lhs) last_set.simps(3)[where thread="th" and thread'="th'"]} & @{text "\<equiv>"} & 
   267     @{thm (rhs) birthtime.simps(3)[where thread="th" and thread'="th'"]}\\
   315     @{thm (rhs) last_set.simps(3)[where thread="th" and thread'="th'"]}\\
   268   @{term "birthtime th (DUMMY#s)"} & @{text "\<equiv>"} & @{term "birthtime th s"}\\
   316   @{term "last_set th (DUMMY#s)"} & @{text "\<equiv>"} & @{term "last_set th s"}\\
   269   \end{tabular}}
   317   \end{tabular}}
   270   \end{isabelle}
   318   \end{isabelle}
   271 
   319 
   272   \noindent
   320   \noindent
   273   In this definition @{term "length s"} stands for the length of the list
   321   In this definition @{term "length s"} stands for the length of the list
   284   we do in case two threads have the same priority), but according to precedences. 
   332   we do in case two threads have the same priority), but according to precedences. 
   285   Precedences allow us to always discriminate between two threads with equal priority by 
   333   Precedences allow us to always discriminate between two threads with equal priority by 
   286   taking into account the time when the priority was last set. We order precedences so 
   334   taking into account the time when the priority was last set. We order precedences so 
   287   that threads with the same priority get a higher precedence if their priority has been 
   335   that threads with the same priority get a higher precedence if their priority has been 
   288   set earlier, since for such threads it is more urgent to finish their work. In an implementation
   336   set earlier, since for such threads it is more urgent to finish their work. In an implementation
   289   this choice would translate to a quite natural FIFO-scheduling of processes with 
   337   this choice would translate to a quite natural FIFO-scheduling of threads with 
   290   the same priority.
   338   the same priority. 
       
   339   
       
   340   Moylan et al.~\cite{deinheritance} considered the alternative of 
       
   341   ``time-slicing'' threads with equal priority, but found that it does not lead to 
       
   342   advantages in practice. On the contrary, according to their work having a policy 
       
   343   like our FIFO-scheduling of threads with equal priority reduces the number of
       
   344   tasks involved in the inheritance process and thus minimises the number
       
   345   of potentially expensive thread-switches. 
   291 
   346 
   292   Next, we introduce the concept of \emph{waiting queues}. They are
   347   Next, we introduce the concept of \emph{waiting queues}. They are
   293   lists of threads associated with every resource. The first thread in
   348   lists of threads associated with every resource. The first thread in
   294   this list (i.e.~the head, or short @{term hd}) is chosen to be the one 
   349   this list (i.e.~the head, or short @{term hd}) is chosen to be the one 
   295   that is in possession of the
   350   that is in possession of the
   383 
   438 
   384   We will design our scheduler  
   439   We will design our scheduler  
   385   so that every thread can be in the possession of several resources, that is 
   440   so that every thread can be in the possession of several resources, that is 
   386   it has potentially several incoming holding edges in the RAG, but has at most one outgoing  
   441   it has potentially several incoming holding edges in the RAG, but has at most one outgoing  
   387   waiting edge. The reason is that when a thread asks for resource that is locked
   442   waiting edge. The reason is that when a thread asks for resource that is locked
   388   already, then the process is blocked and cannot ask for another resource.
   443   already, then the thread is blocked and cannot ask for another resource.
   389   Clearly, also every resource can only have at most one outgoing holding edge---indicating
   444   Clearly, also every resource can only have at most one outgoing holding edge---indicating
   390   that the resource is locked. In this way we can always start at a thread waiting for a 
   445   that the resource is locked. In this way we can always start at a thread waiting for a 
   391   resource and ``chase'' outgoing arrows leading to a single root of a tree. 
   446   resource and ``chase'' outgoing arrows leading to a single root of a tree. 
   392   
   447   
   393 
   448 
   394 
   449 
   395   The use of relations for representing RAGs allows us to conveniently define
   450   The use of relations for representing RAGs allows us to conveniently define
   396   the notion of the \emph{dependants} of a thread using the transitive closure
   451   the notion of the \emph{dependants} of a thread using the transitive closure
   397   operation for relations. This gives
   452   operation for relations, written ~@{term "trancl DUMMY"}. This gives
   398 
   453 
   399   \begin{isabelle}\ \ \ \ \ %%%
   454   \begin{isabelle}\ \ \ \ \ %%%
   400   @{thm cs_dependents_def}
   455   @{thm cs_dependants_def}
   401   \end{isabelle}
   456   \end{isabelle}
   402 
   457 
   403   \noindent
   458   \noindent
   404   This definition needs to account for all threads that wait for a thread to
   459   This definition needs to account for all threads that wait for a thread to
   405   release a resource. This means we need to include threads that transitively
   460   release a resource. This means we need to include threads that transitively
   406   wait for a resource being released (in the picture above this means the dependants
   461   wait for a resource to be released (in the picture above this means the dependants
   407   of @{text "th\<^sub>0"} are @{text "th\<^sub>1"} and @{text "th\<^sub>2"}, which wait for resource @{text "cs\<^sub>1"}, 
   462   of @{text "th\<^sub>0"} are @{text "th\<^sub>1"} and @{text "th\<^sub>2"}, which wait for resource @{text "cs\<^sub>1"}, 
   408   but also @{text "th\<^sub>3"}, 
   463   but also @{text "th\<^sub>3"}, 
   409   which cannot make any progress unless @{text "th\<^sub>2"} makes progress, which
   464   which cannot make any progress unless @{text "th\<^sub>2"} makes progress, which
   410   in turn needs to wait for @{text "th\<^sub>0"} to finish). If there is a circle of dependencies 
   465   in turn needs to wait for @{text "th\<^sub>0"} to finish). If there is a circle of dependencies 
   411   in a RAG, then clearly
   466   in a RAG, then clearly
   646   \noindent
   701   \noindent
   647   Note, however, that apart from the circularity condition, we do not make any 
   702   Note, however, that apart from the circularity condition, we do not make any 
   648   assumption on how different resources can be locked and released relative to each 
   703   assumption on how different resources can be locked and released relative to each 
   649   other. In our model it is possible that critical sections overlap. This is in 
   704   other. In our model it is possible that critical sections overlap. This is in 
   650   contrast to Sha et al \cite{Sha90} who require that critical sections are 
   705   contrast to Sha et al \cite{Sha90} who require that critical sections are 
   651   properly nested.
   706   properly nested (recall Fig.~\ref{overlap}).
   652 
   707 
   653   A valid state of PIP can then be conveniently be defined as follows:
   708   A valid state of PIP can then be conveniently be defined as follows:
   654 
   709 
   655   \begin{center}
   710   \begin{center}
   656   \begin{tabular}{c}
   711   \begin{tabular}{c}
   783 
   838 
   784   Like in the argument by Sha et al.~our
   839   Like in the argument by Sha et al.~our
   785   finite bound does not guarantee absence of indefinite Priority
   840   finite bound does not guarantee absence of indefinite Priority
   786   Inversion. For this we further have to assume that every thread
   841   Inversion. For this we further have to assume that every thread
   787   gives up its resources after a finite amount of time. We found that
   842   gives up its resources after a finite amount of time. We found that
   788   this assumption is awkward to formalise in our model. Therefore we
   843   this assumption is awkward to formalise in our model. There are mainly 
       
   844   two reasons: First, we do not specify what ``running'' the code of a 
       
   845   thread means, for example by giving an operational semantics for
       
   846   machine instructions. Therefore we cannot characterise what are ``good''
       
   847   programs that contain for every looking request also a corresponding
       
   848   unlocking request for a resource. (HERE)
       
   849 
       
   850 
       
   851   Therefore we
   789   leave it out and let the programmer assume the responsibility to
   852   leave it out and let the programmer assume the responsibility to
   790   program threads in such a benign manner (in addition to causing no 
   853   program threads in such a benign manner (in addition to causing no 
   791   circularity in the RAG). In this detail, we do not
   854   circularity in the RAG). In this detail, we do not
   792   make any progress in comparison with the work by Sha et al.
   855   make any progress in comparison with the work by Sha et al.
   793   However, we are able to combine their two separate bounds into a
   856   However, we are able to combine their two separate bounds into a
   939   %\item When a thread is not living, it does not hold any critical resource 
  1002   %\item When a thread is not living, it does not hold any critical resource 
   940   %  (@{text "not_thread_holdents"}):
  1003   %  (@{text "not_thread_holdents"}):
   941   %  @  {thm [display] not_thread_holdents}
  1004   %  @  {thm [display] not_thread_holdents}
   942   %\item When the number of @{text "P"} equals the number of @{text "V"}, the relevant 
  1005   %\item When the number of @{text "P"} equals the number of @{text "V"}, the relevant 
   943   %  thread does not hold any critical resource, therefore no thread can depend on it
  1006   %  thread does not hold any critical resource, therefore no thread can depend on it
   944   %  (@{text "count_eq_dependents"}):
  1007   %  (@{text "count_eq_dependants"}):
   945   %  @  {thm [display] count_eq_dependents}
  1008   %  @  {thm [display] count_eq_dependants}
   946   %\end{enumerate}
  1009   %\end{enumerate}
   947 
  1010 
   948   %The reason that only threads which already held some resoures
  1011   %The reason that only threads which already held some resoures
   949   %can be runing and block @{text "th"} is that if , otherwise, one thread 
  1012   %can be runing and block @{text "th"} is that if , otherwise, one thread 
   950   %does not hold any resource, it may never have its prioirty raised
  1013   %does not hold any resource, it may never have its prioirty raised
  1255   %%@ {t hm[mode=IfThen] eq_up_self}\\
  1318   %%@ {t hm[mode=IfThen] eq_up_self}\\
  1256   @{text "If"} @{thm (prem 1) eq_up}, @{thm (prem 2) eq_up} and @{thm (prem 3) eq_up}\\
  1319   @{text "If"} @{thm (prem 1) eq_up}, @{thm (prem 2) eq_up} and @{thm (prem 3) eq_up}\\
  1257   @{text "then"} @{thm (concl) eq_up}.
  1320   @{text "then"} @{thm (concl) eq_up}.
  1258   \end{tabular}
  1321   \end{tabular}
  1259   \end{isabelle}
  1322   \end{isabelle}
  1260 
  1323  
  1261   \noindent
  1324   \noindent
  1262   This lemma states that if an intermediate @{term cp}-value does not change, then
  1325   This lemma states that if an intermediate @{term cp}-value does not change, then
  1263   the procedure can also stop, because none of its dependent threads will
  1326   the procedure can also stop, because none of its dependent threads will
  1264   have their current precedence changed.
  1327   have their current precedence changed.
  1265   *}(*<*)end(*>*)text {*
  1328   *}(*<*)end(*>*)text {*
  1267   this section closely inform an implementation of PIP, namely whether the
  1330   this section closely inform an implementation of PIP, namely whether the
  1268   RAG needs to be reconfigured or current precedences need to
  1331   RAG needs to be reconfigured or current precedences need to
  1269   be recalculated for an event. This information is provided by the lemmas we proved.
  1332   be recalculated for an event. This information is provided by the lemmas we proved.
  1270   We confirmed that our observations translate into practice by implementing
  1333   We confirmed that our observations translate into practice by implementing
  1271   our version of PIP on top of PINTOS, a small operating system written in C and used for teaching at 
  1334   our version of PIP on top of PINTOS, a small operating system written in C and used for teaching at 
  1272   Stanford University \cite{PINTOS}. To implement PIP, we only need to modify the kernel 
  1335   Stanford University \cite{PINTOS}. An alternative would have been the small Xv6 operating 
       
  1336   system used for teaching at MIT \cite{Xv6link,Xv6}. However this operating system implements
       
  1337   a simple round robin scheduler that lacks stubs for dealing with priorities. This
       
  1338   is inconvenient for our purposes.
       
  1339 
       
  1340 
       
  1341   To implement PIP in PINTOS, we only need to modify the kernel 
  1273   functions corresponding to the events in our formal model. The events translate to the following 
  1342   functions corresponding to the events in our formal model. The events translate to the following 
  1274   function interface in PINTOS:
  1343   function interface in PINTOS:
  1275 
  1344 
  1276   \begin{center}
  1345   \begin{center}
  1277   \begin{tabular}{|l@ {\hspace{2mm}}|l@ {\hspace{2mm}}|}
  1346   \begin{tabular}{|l@ {\hspace{2mm}}|l@ {\hspace{2mm}}|}
  1448   design choices for the implementation of PIP scheduler are backed up with a proved
  1517   design choices for the implementation of PIP scheduler are backed up with a proved
  1449   lemma. We were also able to establish the property that the choice of
  1518   lemma. We were also able to establish the property that the choice of
  1450   the next thread which takes over a lock is irrelevant for the correctness
  1519   the next thread which takes over a lock is irrelevant for the correctness
  1451   of PIP. Moreover, we eliminated a crucial restriction present in 
  1520   of PIP. Moreover, we eliminated a crucial restriction present in 
  1452   the proof of Sha et al.: they require that critical sections nest properly, 
  1521   the proof of Sha et al.: they require that critical sections nest properly, 
  1453   whereas our scheduler allows critical sections to overlap. 
  1522   whereas our scheduler allows critical sections to overlap. What we
       
  1523   are not able to do is to mechanically ``synthesise'' an actual implementation 
       
  1524   from our formalisation. To do so for C-code seems quite hard and is beyond 
       
  1525   current technology available for Isabelle. Also our proof-method based
       
  1526   on events is not ``computational'' in the sense of having a concrete
       
  1527   algorithm behind it: our formalisation is really more about the 
       
  1528   specification of PIP and ensuring that it has the desired properties
       
  1529   (the informal specification by Sha et al.~did not). 
       
  1530   
  1454 
  1531 
  1455   PIP is a scheduling algorithm for single-processor systems. We are
  1532   PIP is a scheduling algorithm for single-processor systems. We are
  1456   now living in a multi-processor world. Priority Inversion certainly
  1533   now living in a multi-processor world. Priority Inversion certainly
  1457   occurs also there, see for example \cite{Brandenburg11,Davis11}.  
  1534   occurs also there, see for example \cite{Brandenburg11,Davis11}.  
  1458   However, there is very little ``foundational''
  1535   However, there is very little ``foundational''