prio/Paper/Paper.thy
changeset 306 5113aa1ae69a
parent 305 463bed130705
child 307 a2d4450b4bf3
equal deleted inserted replaced
305:463bed130705 306:5113aa1ae69a
   301 
   301 
   302   \noindent
   302   \noindent
   303   where the first stands for a \emph{waiting edge} and the second for a 
   303   where the first stands for a \emph{waiting edge} and the second for a 
   304   \emph{holding edge} (@{term Cs} and @{term Th} are constructors of a 
   304   \emph{holding edge} (@{term Cs} and @{term Th} are constructors of a 
   305   datatype for vertices). Given a waiting queue function, a RAG is defined 
   305   datatype for vertices). Given a waiting queue function, a RAG is defined 
   306   as
   306   as the union of the sets of waiting and holding edges, namely
   307 
   307 
   308   \begin{isabelle}\ \ \ \ \ %%%
   308   \begin{isabelle}\ \ \ \ \ %%%
   309   @{thm cs_depend_def}
   309   @{thm cs_depend_def}
   310   \end{isabelle}
   310   \end{isabelle}
   311 
   311 
   312   \noindent
   312   \noindent
   313   Given three threads and three resources, an instance of a RAG is as follows:
   313   Given three threads and three resources, an instance of a RAG can be pictured 
       
   314   as follows:
   314 
   315 
   315   \begin{center}
   316   \begin{center}
   316   \newcommand{\fnt}{\fontsize{7}{8}\selectfont}
   317   \newcommand{\fnt}{\fontsize{7}{8}\selectfont}
   317   \begin{tikzpicture}[scale=1]
   318   \begin{tikzpicture}[scale=1]
   318   %%\draw[step=2mm] (-3,2) grid (1,-1);
   319   %%\draw[step=2mm] (-3,2) grid (1,-1);
   334   \end{tikzpicture}
   335   \end{tikzpicture}
   335   \end{center}
   336   \end{center}
   336 
   337 
   337   \noindent
   338   \noindent
   338   The use of relations for representing RAGs allows us to conveniently define
   339   The use of relations for representing RAGs allows us to conveniently define
   339   the notion of the \emph{dependants} of a thread. This is defined as
   340   the notion of the \emph{dependants} of a thread using the transitive closure
       
   341   operation for relations. This gives
   340 
   342 
   341   \begin{isabelle}\ \ \ \ \ %%%
   343   \begin{isabelle}\ \ \ \ \ %%%
   342   @{thm cs_dependents_def}
   344   @{thm cs_dependents_def}
   343   \end{isabelle}
   345   \end{isabelle}
   344 
   346 
   345   \noindent
   347   \noindent
   346   This definition needs to account for all threads that wait for a thread to
   348   This definition needs to account for all threads that wait for a thread to
   347   release a resource. This means we need to include threads that transitively
   349   release a resource. This means we need to include threads that transitively
   348   wait for a resource being released (in the picture above this means the dependants
   350   wait for a resource being released (in the picture above this means the dependants
   349   of @{text "th\<^isub>0"} are @{text "th\<^isub>1"} and @{text "th\<^isub>2"}, but also @{text "th\<^isub>3"}, 
   351   of @{text "th\<^isub>0"} are @{text "th\<^isub>1"} and @{text "th\<^isub>2"}, which wait for resource @{text "cs\<^isub>1"}, 
       
   352   but also @{text "th\<^isub>3"}, 
   350   which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which
   353   which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which
   351   in turn needs to wait for @{text "th\<^isub>1"} to finish). If there is a circle in a RAG, then clearly
   354   in turn needs to wait for @{text "th\<^isub>0"} to finish). If there is a circle in a RAG, then clearly
   352   we have a deadlock. Therefore when a thread requests a resource,
   355   we have a deadlock. Therefore when a thread requests a resource,
   353   we must ensure that the resulting RAG is not circular. 
   356   we must ensure that the resulting RAG is not circular. 
   354 
   357 
   355   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   358   Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a 
   356   state @{text s}. It is defined as
   359   state @{text s}. It is defined as
   358   \begin{isabelle}\ \ \ \ \ %%%
   361   \begin{isabelle}\ \ \ \ \ %%%
   359   @{thm cpreced_def2}\hfill\numbered{cpreced}
   362   @{thm cpreced_def2}\hfill\numbered{cpreced}
   360   \end{isabelle}
   363   \end{isabelle}
   361 
   364 
   362   \noindent
   365   \noindent
       
   366   where the dependants of @{text th} are given by the waiting queue function.
   363   While the precedence @{term prec} of a thread is determined by the programmer 
   367   While the precedence @{term prec} of a thread is determined by the programmer 
   364   (for example when the thread is
   368   (for example when the thread is
   365   created), the point of the current precedence is to let scheduler increase this
   369   created), the point of the current precedence is to let the scheduler increase this
   366   priority, if needed according to PIP. Therefore the current precedence of @{text th} is
   370   precedence, if needed according to PIP. Therefore the current precedence of @{text th} is
   367   given as the maximum of the precedence @{text th} has in state @{text s} \emph{and} all 
   371   given as the maximum of the precedence @{text th} has in state @{text s} \emph{and} all 
   368   processes that are dependants of @{text th}. Since the notion @{term "dependants"} is
   372   threads that are dependants of @{text th}. Since the notion @{term "dependants"} is
   369   defined as the transitive closure of all dependent threads, we deal correctly with the 
   373   defined as the transitive closure of all dependent threads, we deal correctly with the 
   370   problem in the algorithm by Sha et al.~\cite{Sha90} where a priority of a thread is
   374   problem in the informal algorithm by Sha et al.~\cite{Sha90} where a priority of a thread is
   371   lowered prematurely.
   375   lowered prematurely.
   372   
   376   
   373   The next function, called @{term schs}, defines the behaviour of the scheduler. It will be defined
   377   The next function, called @{term schs}, defines the behaviour of the scheduler. It will be defined
   374   by recursion on the state (a list of events); @{term "schs"} returns a \emph{schedule state}, which 
   378   by recursion on the state (a list of events); this function returns a \emph{schedule state}, which 
   375   we represent as a record consisting of two
   379   we represent as a record consisting of two
   376   functions:
   380   functions:
   377 
   381 
   378   \begin{isabelle}\ \ \ \ \ %%%
   382   \begin{isabelle}\ \ \ \ \ %%%
   379   @{text "\<lparr>wq_fun, cprec_fun\<rparr>"}
   383   @{text "\<lparr>wq_fun, cprec_fun\<rparr>"}
   380   \end{isabelle}
   384   \end{isabelle}
   381 
   385 
   382   \noindent
   386   \noindent
   383   The first function is a waiting queue function (that is it takes a resource @{text "cs"} and returns the
   387   The first function is a waiting queue function (that is, it takes a resource @{text "cs"} and returns the
   384   corresponding list of threads that wait for it), the second is a function that takes
   388   corresponding list of threads that wait for it), the second is a function that takes
   385   a thread and returns its current precedence (see \eqref{cpreced}). We assume the usual getter and 
   389   a thread and returns its current precedence (see \eqref{cpreced}). We assume the usual getter and 
   386   setter methods for such records.
   390   setter methods for such records.
   387 
   391 
   388   In the initial state, the scheduler starts with all resources unlocked (see \eqref{allunlocked}) and the
   392   In the initial state, the scheduler starts with all resources unlocked (the corresponding 
       
   393   function is defined in \eqref{allunlocked}) and the
   389   current precedence of every thread is initialised with @{term "Prc 0 0"}; that means 
   394   current precedence of every thread is initialised with @{term "Prc 0 0"}; that means 
   390   \mbox{@{abbrev initial_cprec}}. Therefore
   395   \mbox{@{abbrev initial_cprec}}. Therefore
   391   we have
   396   we have for the initial state
   392 
   397 
   393   \begin{isabelle}\ \ \ \ \ %%%
   398   \begin{isabelle}\ \ \ \ \ %%%
   394   \begin{tabular}{@ {}l}
   399   \begin{tabular}{@ {}l}
   395   @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ 
   400   @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ 
   396   \hspace{5mm}@{term "(|wq_fun = all_unlocked, cprec_fun = (\<lambda>_::thread. Prc 0 0)|)"}
   401   \hspace{5mm}@{term "(|wq_fun = all_unlocked, cprec_fun = (\<lambda>_::thread. Prc 0 0)|)"}
   399 
   404 
   400   \noindent
   405   \noindent
   401   The cases for @{term Create}, @{term Exit} and @{term Set} are also straightforward:
   406   The cases for @{term Create}, @{term Exit} and @{term Set} are also straightforward:
   402   we calculate the waiting queue function of the (previous) state @{text s}; 
   407   we calculate the waiting queue function of the (previous) state @{text s}; 
   403   this waiting queue function @{text wq} is unchanged in the next schedule state---because
   408   this waiting queue function @{text wq} is unchanged in the next schedule state---because
   404   none of these events lock or release any resources; 
   409   none of these events lock or release any resource; 
   405   for calculating the next @{term "cprec_fun"}, we use @{text wq} and the function 
   410   for calculating the next @{term "cprec_fun"}, we use @{text wq} and 
   406   @{term cpreced}. This gives the following three clauses for @{term schs}:
   411   @{term cpreced}. This gives the following three clauses for @{term schs}:
   407 
   412 
   408   \begin{isabelle}\ \ \ \ \ %%%
   413   \begin{isabelle}\ \ \ \ \ %%%
   409   \begin{tabular}{@ {}l}
   414   \begin{tabular}{@ {}l}
   410   @{thm (lhs) schs.simps(2)} @{text "\<equiv>"}\\ 
   415   @{thm (lhs) schs.simps(2)} @{text "\<equiv>"}\\ 
   418   \hspace{8mm}@{term "(|wq_fun = wq\<iota>, cprec_fun = cpreced wq\<iota> (Set th prio # s)|)"}
   423   \hspace{8mm}@{term "(|wq_fun = wq\<iota>, cprec_fun = cpreced wq\<iota> (Set th prio # s)|)"}
   419   \end{tabular}
   424   \end{tabular}
   420   \end{isabelle}
   425   \end{isabelle}
   421 
   426 
   422   \noindent 
   427   \noindent 
   423   More interesting are the cases when a resource, say @{text cs}, is locked or released. In these cases
   428   More interesting are the cases where a resource, say @{text cs}, is locked or released. In these cases
   424   we need to calculate a new waiting queue function. For the event @{term "P th cs"}, we have to update
   429   we need to calculate a new waiting queue function. For the event @{term "P th cs"}, we have to update
   425   the function so that the new thread list for @{text cs} is old thread list plus the thread @{text th} 
   430   the function so that the new thread list for @{text cs} is the old thread list plus the thread @{text th} 
   426   appended to the end of that list (remember the head of this list is seen to be in the possession of this
   431   appended to the end of that list (remember the head of this list is seen to be in the possession of this
   427   resource).
   432   resource). This gives the clause
   428 
   433 
   429   \begin{isabelle}\ \ \ \ \ %%%
   434   \begin{isabelle}\ \ \ \ \ %%%
   430   \begin{tabular}{@ {}l}
   435   \begin{tabular}{@ {}l}
   431   @{thm (lhs) schs.simps(5)} @{text "\<equiv>"}\\ 
   436   @{thm (lhs) schs.simps(5)} @{text "\<equiv>"}\\ 
   432   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   437   \hspace{5mm}@{text "let"} @{text "wq = wq_fun (schs s)"} @{text "in"}\\
   438   \noindent
   443   \noindent
   439   The clause for event @{term "V th cs"} is similar, except that we need to update the waiting queue function
   444   The clause for event @{term "V th cs"} is similar, except that we need to update the waiting queue function
   440   so that the thread that possessed the lock is deleted from the corresponding thread list. For this 
   445   so that the thread that possessed the lock is deleted from the corresponding thread list. For this 
   441   list transformation, we use
   446   list transformation, we use
   442   the auxiliary function @{term release}. A simple version of @{term release} would
   447   the auxiliary function @{term release}. A simple version of @{term release} would
   443   just delete this thread and return the rest, namely
   448   just delete this thread and return the remaining threads, namely
   444 
   449 
   445   \begin{isabelle}\ \ \ \ \ %%%
   450   \begin{isabelle}\ \ \ \ \ %%%
   446   \begin{tabular}{@ {}lcl}
   451   \begin{tabular}{@ {}lcl}
   447   @{term "release []"} & @{text "\<equiv>"} & @{term "[]"}\\
   452   @{term "release []"} & @{text "\<equiv>"} & @{term "[]"}\\
   448   @{term "release (DUMMY # qs)"} & @{text "\<equiv>"} & @{term "qs"}\\
   453   @{term "release (DUMMY # qs)"} & @{text "\<equiv>"} & @{term "qs"}\\
   461   @{term "release (DUMMY # qs)"} & @{text "\<equiv>"} & @{term "SOME qs'. distinct qs' \<and> set qs' = set qs"}\\
   466   @{term "release (DUMMY # qs)"} & @{text "\<equiv>"} & @{term "SOME qs'. distinct qs' \<and> set qs' = set qs"}\\
   462   \end{tabular}
   467   \end{tabular}
   463   \end{isabelle}
   468   \end{isabelle}
   464 
   469 
   465   \noindent
   470   \noindent
   466   @{text "SOME"} stands for Hilbert's epsilon and implements an arbitrary
   471   where @{text "SOME"} stands for Hilbert's epsilon and implements an arbitrary
   467   choice for the next waiting list. It just has to be a list of distinctive threads and
   472   choice for the next waiting list. It just has to be a list of distinctive threads and
   468   contain the same elements as @{text "qs"}. This gives for @{term V} the clause:
   473   contain the same elements as @{text "qs"}. This gives for @{term V} the clause:
   469  
   474  
   470   \begin{isabelle}\ \ \ \ \ %%%
   475   \begin{isabelle}\ \ \ \ \ %%%
   471   \begin{tabular}{@ {}l}
   476   \begin{tabular}{@ {}l}
   500   @{thm runing_def}\\
   505   @{thm runing_def}\\
   501   \end{tabular}
   506   \end{tabular}
   502   \end{isabelle}
   507   \end{isabelle}
   503 
   508 
   504   \noindent
   509   \noindent
   505   In this definition @{term "f ` S"} stands for the set @{text S} under the image of the 
   510   In this definition @{term "DUMMY ` DUMMY"} stands for the image of a set under a function.
   506   function @{text f}. 
   511   Note that in the initial state, that is where the list of events is empty, the set 
   507   Note that in the initial case, that is where the list of events is empty, the set 
       
   508   @{term threads} is empty and therefore there is no thread ready nor a running.
   512   @{term threads} is empty and therefore there is no thread ready nor a running.
   509   If there is one or more threads ready, then there can only be \emph{one} thread
   513   If there is one or more threads ready, then there can only be \emph{one} thread
   510   running, namely the one whose current precedence is equal to the maximum of all ready 
   514   running, namely the one whose current precedence is equal to the maximum of all ready 
   511   threads. We use the set-comprehension to capture both possibilities.
   515   threads. We use the set-comprehension to capture both possibilities.
   512   We can now also define the set of resources that are locked by a thread in any
   516   We can now also conveniently define the set of resources that are locked by a thread in a
   513   given state.
   517   given state.
   514 
   518 
   515   \begin{isabelle}\ \ \ \ \ %%%
   519   \begin{isabelle}\ \ \ \ \ %%%
   516   @{thm holdents_def}
   520   @{thm holdents_def}
   517   \end{isabelle}
   521   \end{isabelle}
   518 
   522 
   519   \noindent
   523   Finally we can define what a \emph{valid state} is in our model of PIP. For
   520   These resources are given by the holding edges in the RAG.
       
   521 
       
   522   Finally we can define what a \emph{valid state} is in our PIP. For
       
   523   example we cannot expect to be able to exit a thread, if it was not
   524   example we cannot expect to be able to exit a thread, if it was not
   524   created yet. These validity constraints are characterised by the
   525   created yet. These validity constraints on states are characterised by the
   525   inductive predicate @{term "step"}. We give five inference rules
   526   inductive predicate @{term "step"} and @{term vt}. We first give five inference rules
   526   relating a state and an event that can happen next.
   527   for @{term step} relating a state and an event that can happen next.
   527 
   528 
   528   \begin{center}
   529   \begin{center}
   529   \begin{tabular}{c}
   530   \begin{tabular}{c}
   530   @{thm[mode=Rule] thread_create[where thread=th]}\hspace{1cm}
   531   @{thm[mode=Rule] thread_create[where thread=th]}\hspace{1cm}
   531   @{thm[mode=Rule] thread_exit[where thread=th]}
   532   @{thm[mode=Rule] thread_exit[where thread=th]}
   533   \end{center}
   534   \end{center}
   534 
   535 
   535   \noindent
   536   \noindent
   536   The first rule states that a thread can only be created, if it does not yet exists.
   537   The first rule states that a thread can only be created, if it does not yet exists.
   537   Similarly, the second rule states that a thread can only be terminated if it was
   538   Similarly, the second rule states that a thread can only be terminated if it was
   538   running and does not lock any resources anymore (to simplify ). The event @{text Set} can happen
   539   running and does not lock any resources anymore (this simplifies slightly our model;
       
   540   in practice we would expect the operating system releases all held lock of a
       
   541   thread that is about to exit). The event @{text Set} can happen
   539   if the corresponding thread is running. 
   542   if the corresponding thread is running. 
   540 
   543 
   541   \begin{center}
   544   \begin{center}
   542   @{thm[mode=Rule] thread_set[where thread=th]}
   545   @{thm[mode=Rule] thread_set[where thread=th]}
   543   \end{center}
   546   \end{center}
   544 
   547 
   545   \noindent
   548   \noindent
   546   If a thread wants to lock a resource, then the thread needs to be
   549   If a thread wants to lock a resource, then the thread needs to be
   547   running and also we have to make sure that the resource lock does
   550   running and also we have to make sure that the resource lock does
   548   not lead to a cycle in the RAG. In practice, ensuring the latter is
   551   not lead to a cycle in the RAG. In practice, ensuring the latter is
   549   of course the responsibility of the programmer.  Here in our formal
   552   of course the responsibility of the programmer.  In our formal
   550   model we just exclude such problematic cases in order to make
   553   model we just exclude such problematic cases in order to make
   551   some meaningful statements about PIP.\footnote{This situation is
   554   some meaningful statements about PIP.\footnote{This situation is
   552   similar to the infamous occurs check in Prolog: in order to say
   555   similar to the infamous occurs check in Prolog: in order to say
   553   anything meaningful about unification, we need to perform an occurs
   556   anything meaningful about unification, one needs to perform an occurs
   554   check; but in practice the occurs check is ommited and the
   557   check, but in practice the occurs check is ommited and the
   555   responsibility to avoid problems rests with the programmer.}
   558   responsibility for avoiding problems rests with the programmer.}
       
   559  
       
   560   \begin{center}
       
   561   @{thm[mode=Rule] thread_P[where thread=th]}
       
   562   \end{center}
       
   563  
       
   564   \noindent
   556   Similarly, if a thread wants to release a lock on a resource, then
   565   Similarly, if a thread wants to release a lock on a resource, then
   557   it must be running and in the possession of that lock. This is
   566   it must be running and in the possession of that lock. This is
   558   formally given by the last two inference rules of @{term step}.
   567   formally given by the last inference rule of @{term step}.
   559 
   568  
   560   \begin{center}
   569   \begin{center}
   561   \begin{tabular}{c}
   570   @{thm[mode=Rule] thread_V[where thread=th]}
   562   @{thm[mode=Rule] thread_P[where thread=th]}\medskip\\
       
   563   @{thm[mode=Rule] thread_V[where thread=th]}\\
       
   564   \end{tabular}
       
   565   \end{center}
   571   \end{center}
   566   
   572 
   567   \noindent
   573   \noindent
   568   A valid state of PIP can then be conveniently be defined as follows:
   574   A valid state of PIP can then be conveniently be defined as follows:
   569 
   575 
   570   \begin{center}
   576   \begin{center}
   571   \begin{tabular}{c}
   577   \begin{tabular}{c}