prio/Paper/Paper.thy
changeset 298 f2e0d031a395
parent 297 0a4be67ea7f8
child 299 4fcd802eba59
equal deleted inserted replaced
297:0a4be67ea7f8 298:f2e0d031a395
    21   readys ("ready") and
    21   readys ("ready") and
    22   depend ("RAG") and 
    22   depend ("RAG") and 
    23   preced ("prec") and
    23   preced ("prec") and
    24   cpreced ("cprec") and
    24   cpreced ("cprec") and
    25   dependents ("dependants") and
    25   dependents ("dependants") and
       
    26   cp ("cprec") and
       
    27   holdents ("resources") and
    26   DUMMY  ("\<^raw:\mbox{$\_\!\_$}>")
    28   DUMMY  ("\<^raw:\mbox{$\_\!\_$}>")
    27 (*>*)
    29 (*>*)
    28 
    30 
    29 section {* Introduction *}
    31 section {* Introduction *}
    30 
    32 
   163   The Priority Inheritance Protocol, short PIP, is a scheduling
   165   The Priority Inheritance Protocol, short PIP, is a scheduling
   164   algorithm for a single-processor system.\footnote{We shall come back
   166   algorithm for a single-processor system.\footnote{We shall come back
   165   later to the case of PIP on multi-processor systems.} Our model of
   167   later to the case of PIP on multi-processor systems.} Our model of
   166   PIP is based on Paulson's inductive approach to protocol
   168   PIP is based on Paulson's inductive approach to protocol
   167   verification \cite{Paulson98}, where the \emph{state} of a system is
   169   verification \cite{Paulson98}, where the \emph{state} of a system is
   168   given by a list of events that happened so far.  \emph{Events} in PIP fall
   170   given by a list of events that happened so far.  \emph{Events} of PIP fall
   169   into five categories defined as the datatype:
   171   into five categories defined as the datatype:
   170 
   172 
   171   \begin{isabelle}\ \ \ \ \ %%%
   173   \begin{isabelle}\ \ \ \ \ %%%
   172   \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l}
   174   \mbox{\begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l@ {\hspace{7mm}}l}
   173   \isacommand{datatype} event 
   175   \isacommand{datatype} event 
   182   \noindent
   184   \noindent
   183   whereby threads, priorities and (critical) resources are represented
   185   whereby threads, priorities and (critical) resources are represented
   184   as natural numbers. The event @{term Set} models the situation that
   186   as natural numbers. The event @{term Set} models the situation that
   185   a thread obtains a new priority given by the programmer or
   187   a thread obtains a new priority given by the programmer or
   186   user (for example via the {\tt nice} utility under UNIX).  As in Paulson's work, we
   188   user (for example via the {\tt nice} utility under UNIX).  As in Paulson's work, we
   187   need to define functions that allow one to make some observations
   189   need to define functions that allow us to make some observations
   188   about states.  One, called @{term threads}, calculates the set of
   190   about states.  One, called @{term threads}, calculates the set of
   189   ``live'' threads that we have seen so far:
   191   ``live'' threads that we have seen so far:
   190 
   192 
   191   \begin{isabelle}\ \ \ \ \ %%%
   193   \begin{isabelle}\ \ \ \ \ %%%
   192   \mbox{\begin{tabular}{lcl}
   194   \mbox{\begin{tabular}{lcl}
   254   this choice would translate to a quite natural FIFO-scheduling of processes with 
   256   this choice would translate to a quite natural FIFO-scheduling of processes with 
   255   the same priority.
   257   the same priority.
   256 
   258 
   257   Next, we introduce the concept of \emph{waiting queues}. They are
   259   Next, we introduce the concept of \emph{waiting queues}. They are
   258   lists of threads associated with every resource. The first thread in
   260   lists of threads associated with every resource. The first thread in
   259   this list (the head, or short @{term hd}) is chosen to be the one 
   261   this list (i.e.~the head, or short @{term hd}) is chosen to be the one 
   260   that is in possession of the
   262   that is in possession of the
   261   ``lock'' of the corresponding resource. We model waiting queues as
   263   ``lock'' of the corresponding resource. We model waiting queues as
   262   functions, below abbreviated as @{text wq}. They take a resource as
   264   functions, below abbreviated as @{text wq}. They take a resource as
   263   argument and return a list of threads.  This allows us to define
   265   argument and return a list of threads.  This allows us to define
   264   when a thread \emph{holds}, respectively \emph{waits} for, a
   266   when a thread \emph{holds}, respectively \emph{waits} for, a
   271   \end{tabular}
   273   \end{tabular}
   272   \end{isabelle}
   274   \end{isabelle}
   273 
   275 
   274   \noindent
   276   \noindent
   275   In this definition we assume @{text "set"} converts a list into a set.
   277   In this definition we assume @{text "set"} converts a list into a set.
   276   At the beginning, that is in the state where no process is created yet, 
   278   At the beginning, that is in the state where no thread is created yet, 
   277   the waiting queue function will be the function that just returns the
   279   the waiting queue function will be the function that returns the
   278   empty list for every resource.
   280   empty list for every resource.
   279 
   281 
   280   \begin{isabelle}\ \ \ \ \ %%%
   282   \begin{isabelle}\ \ \ \ \ %%%
   281   @{abbrev all_unlocked}
   283   @{abbrev all_unlocked}
   282   \end{isabelle}
   284   \end{isabelle}
   300   \begin{isabelle}\ \ \ \ \ %%%
   302   \begin{isabelle}\ \ \ \ \ %%%
   301   @{thm cs_depend_def}
   303   @{thm cs_depend_def}
   302   \end{isabelle}
   304   \end{isabelle}
   303 
   305 
   304   \noindent
   306   \noindent
   305   An instance of a RAG is as follows:
   307   Given three threads and three resources, an instance of a RAG is as follows:
   306 
   308 
   307   \begin{center}
   309   \begin{center}
   308   \newcommand{\fnt}{\fontsize{7}{8}\selectfont}
   310   \newcommand{\fnt}{\fontsize{7}{8}\selectfont}
   309   \begin{tikzpicture}[scale=1]
   311   \begin{tikzpicture}[scale=1]
   310   %%\draw[step=2mm] (-3,2) grid (1,-1);
   312   %%\draw[step=2mm] (-3,2) grid (1,-1);
   312   \node (A) at (0,0) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>0"}};
   314   \node (A) at (0,0) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>0"}};
   313   \node (B) at (2,0) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>1"}};
   315   \node (B) at (2,0) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>1"}};
   314   \node (C) at (4,0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>1"}};
   316   \node (C) at (4,0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>1"}};
   315   \node (D) at (4,-0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>2"}};
   317   \node (D) at (4,-0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>2"}};
   316   \node (E) at (6,-0.7) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>2"}};
   318   \node (E) at (6,-0.7) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>2"}};
       
   319   \node (E1) at (6, 0.2) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>3"}};
   317   \node (F) at (8,-0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>3"}};
   320   \node (F) at (8,-0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>3"}};
   318 
   321 
   319   \draw [->,line width=0.6mm] (A) to node [pos=0.45,sloped,above=-0.5mm] {\fnt{}holding}  (B);
   322   \draw [->,line width=0.6mm] (A) to node [pos=0.45,sloped,above=-0.5mm] {\fnt{}holding}  (B);
   320   \draw [->,line width=0.6mm] (C) to node [pos=0.4,sloped,above=-0.5mm] {\fnt{}waiting}  (B);
   323   \draw [->,line width=0.6mm] (C) to node [pos=0.4,sloped,above=-0.5mm] {\fnt{}waiting}  (B);
   321   \draw [->,line width=0.6mm] (D) to node [pos=0.4,sloped,above=-0.5mm] {\fnt{}waiting}  (B);
   324   \draw [->,line width=0.6mm] (D) to node [pos=0.4,sloped,below=-0.5mm] {\fnt{}waiting}  (B);
   322   \draw [->,line width=0.6mm] (D) to node [pos=0.45,sloped,above=-0.5mm] {\fnt{}holding}  (E);
   325   \draw [->,line width=0.6mm] (D) to node [pos=0.45,sloped,below=-0.5mm] {\fnt{}holding}  (E);
   323   \draw [->,line width=0.6mm] (F) to node [pos=0.45,sloped,above=-0.5mm] {\fnt{}waiting}  (E);
   326   \draw [->,line width=0.6mm] (D) to node [pos=0.45,sloped,above=-0.5mm] {\fnt{}holding}  (E1);
       
   327   \draw [->,line width=0.6mm] (F) to node [pos=0.45,sloped,below=-0.5mm] {\fnt{}waiting}  (E);
   324   \end{tikzpicture}
   328   \end{tikzpicture}
   325   \end{center}
   329   \end{center}
   326 
   330 
   327   \noindent
   331   \noindent
   328   The use of relations for representing RAGs allows us to conveniently define
   332   The use of relations for representing RAGs allows us to conveniently define
   333   \end{isabelle}
   337   \end{isabelle}
   334 
   338 
   335   \noindent
   339   \noindent
   336   This definition needs to account for all threads that wait for a thread to
   340   This definition needs to account for all threads that wait for a thread to
   337   release a resource. This means we need to include threads that transitively
   341   release a resource. This means we need to include threads that transitively
   338   wait for a resource being released (in the picture above this means also @{text "th\<^isub>3"}, 
   342   wait for a resource being released (in the picture above this means the dependants
   339   which cannot make any progress unless @{text "th\<^isub>2"} makes progress which
   343   of @{text "th\<^isub>0"} are @{text "th\<^isub>1"} and @{text "th\<^isub>2"}, but also @{text "th\<^isub>3"}, 
   340   in turn needs to wait for @{text "th\<^isub>1"}). If there is a circle in a RAG, then clearly
   344   which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which
       
   345   in turn needs to wait for @{text "th\<^isub>1"} to finish). If there is a circle in a RAG, then clearly
   341   we have a deadlock. Therefore when a thread requests a resource,
   346   we have a deadlock. Therefore when a thread requests a resource,
   342   we must ensure that the resulting RAG is not not circular. 
   347   we must ensure that the resulting RAG is not circular. 
   343 
   348 
   344   Next we introduce the notion of the \emph{current precedence} for a thread @{text th} in a 
   349   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   345   state @{text s}, which is defined as
   350   state @{text s}. It is defined as
   346 
   351 
   347   \begin{isabelle}\ \ \ \ \ %%%
   352   \begin{isabelle}\ \ \ \ \ %%%
   348   @{thm cpreced_def2}
   353   @{thm cpreced_def2}\numbered{permprops}
   349   \end{isabelle}
   354   \end{isabelle}
   350 
   355 
   351   \noindent
   356   \noindent
   352   While the precedence @{term prec} of a thread is determined by the programmer 
   357   While the precedence @{term prec} of a thread is determined by the programmer 
   353   (for example when the thread is
   358   (for example when the thread is
   357   processes that are dependants of @{text th}. Since the notion @{term "dependants"} is
   362   processes that are dependants of @{text th}. Since the notion @{term "dependants"} is
   358   defined as the transitive closure of all dependent threads, we deal correctly with the 
   363   defined as the transitive closure of all dependent threads, we deal correctly with the 
   359   problem in the algorithm by Sha et al.~\cite{Sha90} where a priority of a thread is
   364   problem in the algorithm by Sha et al.~\cite{Sha90} where a priority of a thread is
   360   lowered prematurely.
   365   lowered prematurely.
   361   
   366   
   362   The next function, called @{term schs}, defines the behaviour of the scheduler. It is defined
   367   The next function, called @{term schs}, defines the behaviour of the scheduler. It will be defined
   363   by recursion on the state (a list of events); @{term "schs"} takes a state as argument
   368   by recursion on the state (a list of events); @{term "schs"} returns a \emph{schedule state}, which 
   364   and returns a \emph{schedule state}, which we define as a record consisting of two
   369   we represent as a record consisting of two
   365   functions:
   370   functions:
   366 
   371 
   367   \begin{isabelle}\ \ \ \ \ %%%
   372   \begin{isabelle}\ \ \ \ \ %%%
   368   @{text "\<lparr>wq_fun, cprec_fun\<rparr>"}
   373   @{text "\<lparr>wq_fun, cprec_fun\<rparr>"}
   369   \end{isabelle}
   374   \end{isabelle}
   370 
   375 
   371   \noindent
   376   \noindent
   372   The first is a waiting queue function (that is takes a @{text "cs"} and returns the
   377   The first function is a waiting queue function (that is takes a @{text "cs"} and returns the
   373   corresponding list of threads that wait for it), the second is a function that takes
   378   corresponding list of threads that wait for it), the second is a function that takes
   374   a thread and returns its current precedence (see ???). We have the usual getter and 
   379   a thread and returns its current precedence (see ???). We assume the usual getter and 
   375   setter methods for such records.
   380   setter methods for such records.
   376 
   381 
   377   In the initial state, the scheduler starts with all resources unlocked and the
   382   In the initial state, the scheduler starts with all resources unlocked and the
   378   precedence of every thread is initialised with @{term "Prc 0 0"}. Therefore
   383   current precedence of every thread is initialised with @{term "Prc 0 0"}; that means 
       
   384   @{abbrev initial_cprec}. Therefore
   379   we have
   385   we have
   380 
   386 
   381   \begin{isabelle}\ \ \ \ \ %%%
   387   \begin{isabelle}\ \ \ \ \ %%%
   382   \begin{tabular}{@ {}l}
   388   \begin{tabular}{@ {}l}
   383   @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ 
   389   @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ 
   386   \end{isabelle}
   392   \end{isabelle}
   387 
   393 
   388   \noindent
   394   \noindent
   389   The cases for @{term Create}, @{term Exit} and @{term Set} are also straightforward:
   395   The cases for @{term Create}, @{term Exit} and @{term Set} are also straightforward:
   390   we calculate the waiting queue function of the (previous) state @{text s}; 
   396   we calculate the waiting queue function of the (previous) state @{text s}; 
   391   this waiting queue function @{text wq} is unchanged in the next schedule state; 
   397   this waiting queue function @{text wq} is unchanged in the next schedule state---because
       
   398   none of these events lock or release any resources; 
   392   for calculating the next @{term "cprec_fun"}, we use @{text wq} and the function 
   399   for calculating the next @{term "cprec_fun"}, we use @{text wq} and the function 
   393   @{term cpreced}. This gives the following three clauses:
   400   @{term cpreced}. This gives the following three clauses for @{term schs}:
   394 
   401 
   395   \begin{isabelle}\ \ \ \ \ %%%
   402   \begin{isabelle}\ \ \ \ \ %%%
   396   \begin{tabular}{@ {}l}
   403   \begin{tabular}{@ {}l}
   397   @{thm (lhs) schs.simps(2)} @{text "\<equiv>"}\\ 
   404   @{thm (lhs) schs.simps(2)} @{text "\<equiv>"}\\ 
   398   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   405   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   399   \hspace{8mm}@{term "(|wq_fun = wq\<iota>, cprec_fun = cpreced wq\<iota> (Create th prio # s)|)"}\\
   406   \hspace{8mm}@{term "(|wq_fun = wq\<iota>, cprec_fun = cpreced wq\<iota> (Create th prio # s)|)"}\smallskip\\
   400   @{thm (lhs) schs.simps(3)} @{text "\<equiv>"}\\
   407   @{thm (lhs) schs.simps(3)} @{text "\<equiv>"}\\
   401   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   408   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   402   \hspace{8mm}@{term "(|wq_fun = wq\<iota>, cprec_fun = cpreced wq\<iota> (Exit th # s)|)"}\smallskip\\
   409   \hspace{8mm}@{term "(|wq_fun = wq\<iota>, cprec_fun = cpreced wq\<iota> (Exit th # s)|)"}\smallskip\\
   403   @{thm (lhs) schs.simps(4)} @{text "\<equiv>"}\\ 
   410   @{thm (lhs) schs.simps(4)} @{text "\<equiv>"}\\ 
   404   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   411   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   406   \end{tabular}
   413   \end{tabular}
   407   \end{isabelle}
   414   \end{isabelle}
   408 
   415 
   409   \noindent 
   416   \noindent 
   410   More interesting are the cases when a resource, say @{text cs}, is locked or released. In this case
   417   More interesting are the cases when a resource, say @{text cs}, is locked or released. In this case
   411   we need to calculate a new waiting queue function. In case of @{term P}, we update
   418   we need to calculate a new waiting queue function. For the event @{term P}, we have to update
   412   the function so that the new thread list for @{text cs} is old thread list plus the thread @{text th} 
   419   the function so that the new thread list for @{text cs} is old thread list plus the thread @{text th} 
   413   appended to the end (remember the head of this list is in the possession of the
   420   appended to the end of that list (remember the head of this list is seen to be in the possession of the
   414   resource).
   421   resource).
   415 
   422 
   416   \begin{isabelle}\ \ \ \ \ %%%
   423   \begin{isabelle}\ \ \ \ \ %%%
   417   \begin{tabular}{@ {}l}
   424   \begin{tabular}{@ {}l}
   418   @{thm (lhs) schs.simps(5)} @{text "\<equiv>"}\\ 
   425   @{thm (lhs) schs.simps(5)} @{text "\<equiv>"}\\ 
   421   \hspace{8mm}@{term "(|wq_fun = new_wq, cprec_fun = cpreced new_wq (P th cs # s)|)"}
   428   \hspace{8mm}@{term "(|wq_fun = new_wq, cprec_fun = cpreced new_wq (P th cs # s)|)"}
   422   \end{tabular}
   429   \end{tabular}
   423   \end{isabelle}
   430   \end{isabelle}
   424 
   431 
   425   \noindent
   432   \noindent
   426   The case for @{term V} is similar, except that we need to update the waiting queue function
   433   The clause for event @{term V} is similar, except that we need to update the waiting queue function
   427   so that the thread that possessed the lock is eliminated. For this we use
   434   so that the thread that possessed the lock is deleted from the corresponding thread list. For this we use
   428   the auxiliary function @{term release}. A simple version of @{term release} would
   435   the auxiliary function @{term release}. A simple version of @{term release} would
   429   just delete this thread and return the rest like so
   436   just delete this thread and return the rest, namely
   430 
   437 
   431   \begin{isabelle}\ \ \ \ \ %%%
   438   \begin{isabelle}\ \ \ \ \ %%%
   432   \begin{tabular}{@ {}lcl}
   439   \begin{tabular}{@ {}lcl}
   433   @{term "release []"} & @{text "\<equiv>"} & @{term "[]"}\\
   440   @{term "release []"} & @{text "\<equiv>"} & @{term "[]"}\\
   434   @{term "release (DUMMY # qs)"} & @{text "\<equiv>"} & @{term "qs"}\\
   441   @{term "release (DUMMY # qs)"} & @{text "\<equiv>"} & @{term "qs"}\\
   435   \end{tabular}
   442   \end{tabular}
   436   \end{isabelle}
   443   \end{isabelle}
   437 
   444 
   438   \noindent
   445   \noindent
   439   However in practice often the thread with the highest precedence will get the
   446   In practice, however, often the thread with the highest precedence will get the
   440   lock next. We have implemented this choice, but later found out that the choice 
   447   lock next. We have implemented this choice, but later found out that the choice 
   441   about which thread is chosen next is actually irrelevant for the correctness of PIP.
   448   about which thread is chosen next is actually irrelevant for the correctness of PIP.
   442   Therefore we prove the stronger result where @{term release} is defined as
   449   Therefore we prove the stronger result where @{term release} is defined as
   443 
   450 
   444   \begin{isabelle}\ \ \ \ \ %%%
   451   \begin{isabelle}\ \ \ \ \ %%%
   448   \end{tabular}
   455   \end{tabular}
   449   \end{isabelle}
   456   \end{isabelle}
   450 
   457 
   451   \noindent
   458   \noindent
   452   @{text "SOME"} stands for Hilbert's epsilon and implements an arbitrary
   459   @{text "SOME"} stands for Hilbert's epsilon and implements an arbitrary
   453   choice for the next waiting list, it just has to be a distinct list and
   460   choice for the next waiting list. It just has to be a list of distinctive threads and
   454   contain the same elements as @{text "qs"}. This gives for @{term V} and @{term schs} the clause:
   461   contain the same elements as @{text "qs"}. This gives for @{term V} the clause:
   455  
   462  
   456   \begin{isabelle}\ \ \ \ \ %%%
   463   \begin{isabelle}\ \ \ \ \ %%%
   457   \begin{tabular}{@ {}l}
   464   \begin{tabular}{@ {}l}
   458   @{thm (lhs) schs.simps(6)} @{text "\<equiv>"}\\
   465   @{thm (lhs) schs.simps(6)} @{text "\<equiv>"}\\
   459   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   466   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   460   \hspace{5mm}@{text "let"} @{text "new_wq = release (wq cs)"} @{text "in"}\\
   467   \hspace{5mm}@{text "let"} @{text "new_wq = release (wq cs)"} @{text "in"}\\
   461   \hspace{8mm}@{term "(|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|)"}
   468   \hspace{8mm}@{term "(|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|)"}
   462   \end{tabular}
   469   \end{tabular}
   463   \end{isabelle}
   470   \end{isabelle}
   464 
   471 
   465 
   472   Having the scheduler function @{term schs} at our disposal, we can ``lift'' the notions
   466   TODO
   473   @{term waiting}, @{term holding} @{term depend} and @{term cp} such that they only depend 
   467 
   474   on states.
   468   \begin{isabelle}\ \ \ \ \ %%%
   475 
   469   \begin{tabular}{@ {}l}
   476   \begin{isabelle}\ \ \ \ \ %%%
   470   @{thm s_depend_def}\\
   477   \begin{tabular}{@ {}rcl}
       
   478   @{thm (lhs) s_holding_abv} & @{text "\<equiv>"} & @{thm (rhs) s_holding_abv}\\
       
   479   @{thm (lhs) s_waiting_abv} & @{text "\<equiv>"} & @{thm (rhs) s_waiting_abv}\\
       
   480   @{thm (lhs) s_depend_abv}  & @{text "\<equiv>"} & @{thm (rhs) s_depend_abv}\\
       
   481   @{thm (lhs) cp_def}        & @{text "\<equiv>"} & @{thm (rhs) cp_def}
   471   \end{tabular}
   482   \end{tabular}
   472   \end{isabelle}
   483   \end{isabelle}
       
   484 
       
   485   \noindent
       
   486   With them we can introduce the notion of threads being @{term readys} (i.e.~threads
       
   487   that do not wait for any resource) and the running thread.
   473 
   488 
   474   \begin{isabelle}\ \ \ \ \ %%%
   489   \begin{isabelle}\ \ \ \ \ %%%
   475   \begin{tabular}{@ {}l}
   490   \begin{tabular}{@ {}l}
   476   @{thm readys_def}\\
   491   @{thm readys_def}\\
   477   \end{tabular}
       
   478   \end{isabelle}
       
   479 
       
   480   \begin{isabelle}\ \ \ \ \ %%%
       
   481   \begin{tabular}{@ {}l}
       
   482   @{thm runing_def}\\
   492   @{thm runing_def}\\
   483   \end{tabular}
   493   \end{tabular}
   484   \end{isabelle}
   494   \end{isabelle}
   485 
   495 
   486 
   496   \noindent
   487   resources
   497   Note that in the initial case, that is where the list of events is empty, the set 
   488 
   498   @{term threads} is empty and therefore there is no thread ready nor a running.
   489   done: threads     not done: running
   499   If there is one or more threads ready, then there can only be \emph{one} thread
   490 
   500   running, namely the one whose current precedence is equal to the maximum of all ready 
   491   step relation:
   501   threads. We can also define the set of resources that are locked by a thread in a
       
   502   given state.
       
   503 
       
   504   \begin{isabelle}\ \ \ \ \ %%%
       
   505   @{thm holdents_def}
       
   506   \end{isabelle}
       
   507 
       
   508   \noindent
       
   509   These resources are given by the holding edges in the RAG.
       
   510 
       
   511   Finally we can define what a \emph{valid state} is. For example we cannot exptect to
       
   512   be able to exit a thread, if it was not created yet. These validity constraints
       
   513   are characterised by the inductive predicate @{term "step"} by the following five 
       
   514   inference rules relating a state and an event that can happen next.
   492 
   515 
   493   \begin{center}
   516   \begin{center}
   494   \begin{tabular}{c}
   517   \begin{tabular}{c}
   495   @{thm[mode=Rule] thread_create[where thread=th]}\hspace{1cm}
   518   @{thm[mode=Rule] thread_create[where thread=th]}\hspace{1cm}
   496   @{thm[mode=Rule] thread_exit[where thread=th]}\medskip\\
   519   @{thm[mode=Rule] thread_exit[where thread=th]}
   497 
   520   \end{tabular}
   498   @{thm[mode=Rule] thread_set[where thread=th]}\medskip\\
   521   \end{center}
       
   522 
       
   523   \noindent
       
   524   The first rule states that a thread can only be created, if it does not yet exists.
       
   525   Similarly, the second rule states that a thread can only be terminated if it was
       
   526   running and does not lock any resources anymore. The event @{text Set} can happen
       
   527   if the corresponding thread is running. 
       
   528 
       
   529   \begin{center}
       
   530   @{thm[mode=Rule] thread_set[where thread=th]}
       
   531   \end{center}
       
   532 
       
   533   \noindent
       
   534   If a thread wants to lock a resource, then the thread needs to be running and
       
   535   also we have to make sure that the resource lock doe not lead to a cycle in the 
       
   536   RAG. Similarly, if a thread wants to release a lock on a resource, then it must 
       
   537   be running and in the possession of that lock. This is formally given by the 
       
   538   last two inference rules of @{term step}.
       
   539 
       
   540   \begin{center}
       
   541   \begin{tabular}{c}
   499   @{thm[mode=Rule] thread_P[where thread=th]}\medskip\\
   542   @{thm[mode=Rule] thread_P[where thread=th]}\medskip\\
   500   @{thm[mode=Rule] thread_V[where thread=th]}\\
   543   @{thm[mode=Rule] thread_V[where thread=th]}\\
   501   \end{tabular}
   544   \end{tabular}
   502   \end{center}
   545   \end{center}
   503 
   546   
   504   valid state:
   547   \noindent
       
   548   A valid state of PIP can then be conveniently be defined as follows:
   505 
   549 
   506   \begin{center}
   550   \begin{center}
   507   \begin{tabular}{c}
   551   \begin{tabular}{c}
   508   @{thm[mode=Axiom] vt_nil[where cs=step]}\hspace{1cm}
   552   @{thm[mode=Axiom] vt_nil}\hspace{1cm}
   509   @{thm[mode=Rule] vt_cons[where cs=step]}
   553   @{thm[mode=Rule] vt_cons}
   510   \end{tabular}
   554   \end{tabular}
   511   \end{center}
   555   \end{center}
   512 
   556 
   513 
   557   \noindent
   514   To define events, the identifiers of {\em threads},
   558   This completes our formal model of PIP. In the next section we present
   515   {\em priority} and {\em critical resources } (abbreviated as @{text "cs"}) 
   559   properties that show our version of PIP is correct.
   516   need to be represented. All three are represetned using standard 
       
   517   Isabelle/HOL type @{typ "nat"}:
       
   518 *}
   560 *}
       
   561 
       
   562 section {* Correctness Proof *}
       
   563 
       
   564 text {* TO DO *}
       
   565 
       
   566 section {* Properties for an Implementation *}
       
   567 
       
   568 text {* TO DO *}
       
   569 
       
   570 section {* Conclusion *}
       
   571 
       
   572 text {* TO DO *}
   519 
   573 
   520 text {*
   574 text {*
   521   \bigskip
   575   \bigskip
   522   The priority inversion phenomenon was first published in
   576   The priority inversion phenomenon was first published in
   523   \cite{Lampson80}.  The two protocols widely used to eliminate
   577   \cite{Lampson80}.  The two protocols widely used to eliminate