Journal/Paper.thy
changeset 170 def87c589516
parent 169 5697bb5b6b2b
child 171 daf75d6ebc89
equal deleted inserted replaced
169:5697bb5b6b2b 170:def87c589516
  1016   alive threads is finite, @{text th} can only be blocked a finite
  1016   alive threads is finite, @{text th} can only be blocked a finite
  1017   number of threads.  We will actually prove a
  1017   number of threads.  We will actually prove a
  1018   stronger statement where we also provide the current precedence of
  1018   stronger statement where we also provide the current precedence of
  1019   the blocking thread. 
  1019   the blocking thread. 
  1020 
  1020 
  1021   However, this correctness criterion hinges upon a number of
  1021   However, the theorem we are going to prove hinges upon a number of
  1022   natural assumptions about the states @{text s} and @{text "s' @ s"}, the
  1022   natural assumptions about the states @{text s} and @{text "s' @ s"}, the
  1023   thread @{text th} and the events happening in @{text s'}. We list
  1023   thread @{text th} and the events happening in @{text s'}. We list
  1024   them next:
  1024   them next:
  1025 
  1025 
  1026   \begin{quote}
  1026   \begin{quote}
  1581   after a finite amount of time. We found that this property is not so
  1581   after a finite amount of time. We found that this property is not so
  1582   straightforward to formalise in our model. There are mainly two
  1582   straightforward to formalise in our model. There are mainly two
  1583   reasons for this: First, we do not specify what ``running'' the code
  1583   reasons for this: First, we do not specify what ``running'' the code
  1584   of a thread means, for example by giving an operational semantics
  1584   of a thread means, for example by giving an operational semantics
  1585   for machine instructions. Therefore we cannot characterise what are
  1585   for machine instructions. Therefore we cannot characterise what are
  1586   ``good'' programs that contain for every locking request also a
  1586   ``good'' programs that contain for every locking request for a
  1587   corresponding unlocking request for a resource.  Second, we need to
  1587   resource also a corresponding unlocking request.  Second, we need to
  1588   distinghish between a thread that ``just'' locks a resource for a
  1588   distinghish between a thread that ``just'' locks a resource for a
  1589   finite amount of time (even if it is very long) and one that locks
  1589   finite amount of time (even if it is very long) and one that locks
  1590   it forever (there might be a lookp in between the locking and
  1590   it forever (there might be a loop in between the locking and
  1591   unlocking requests).
  1591   unlocking requests).
  1592 
  1592 
  1593   Because of these problems, we decided in our earlier paper
  1593   Because of these problems, we decided in our earlier paper
  1594   \cite{ZhangUrbanWu12} to leave out this property and let the
  1594   \cite{ZhangUrbanWu12} to leave out this property and let the
  1595   programmer assume the responsibility to program threads in such a
  1595   programmer take on the responsibility to program threads in such a
  1596   benign manner (in addition to causing no circularity in the
  1596   benign manner (in addition to causing no circularity in the
  1597   RAG). This leave-it-to-the-programmer was also the approach taken by
  1597   RAG). This leave-it-to-the-programmer was also the approach taken by
  1598   Sha et al.~in their paper.  However, in this paper we can make an
  1598   Sha et al.~in their paper.  However, in this paper we can make an
  1599   improvement: we can look at the \emph{events} that are happening
  1599   improvement by establishing a finite bound on the duration of
  1600   after a Priority Inversion occurs. The events can be seen as a
  1600   Priority Inversion measured by the number of events.  The events can
  1601   \textbf{rough} abstraction of the ``runtime behaviour'' of threads
  1601   be seen as a \textit{rough(!)} abstraction of the ``runtime
  1602   and also as an abstract notion of ``time''---when a new event
  1602   behaviour'' of threads and also as an abstract notion of
  1603   happened, some time must have passed.  In this setting we can prove
  1603   ``time''---when a new event happened, some time must have passed.
  1604   a more direct bound for the absence of indefinite Priority
  1604   In this setting we can prove a more direct bound for the absence of
  1605   Inversion. This is what we shall show below.
  1605   indefinite Priority Inversion. This is what we shall show below.
  1606 
  1606 
  1607   What we will establish in this section is that there can only be a
  1607   What we will establish in this section is that there can only be a
  1608   finite amount of states after state @{term s} in which the thread
  1608   finite number of states after state @{term s} in which the thread
  1609   @{term th} is blocked.  For this finiteness bound to exist, Sha et
  1609   @{term th} is blocked.  For this finiteness bound to exist, Sha et
  1610   al.~assume in their work that there is a finite pool of threads
  1610   al.~informally make two assumtions: first, there is a finite pool of
  1611   (active or hibernating). However, we do not have this concept of
  1611   threads (active or hibernating) and second, each of them giving up
  1612   active or hibernating threads in our model. Rather, in our model we
  1612   its resources after a finite amount of time.  However, we do not
  1613   can create or exit threads arbitrarily. Consequently, the avoidance
  1613   have this concept of active or hibernating threads in our model.  In
  1614   of indefinite priority inversion we are trying to establish is in
  1614   fact we can dispence with the first assumption altogether and allow
  1615   our model not true, unless we require that the number of threads
  1615   that in our model we can create or exit threads
  1616   created is bounded in every valid future state after @{term s}. So
  1616   arbitrarily. Consequently, the avoidance of indefinite priority
  1617   our first assumption states:
  1617   inversion we are trying to establish is in our model not true,
       
  1618   unless we require that the number of threads created is bounded in
       
  1619   every valid future state after @{term s}. So our first assumption
       
  1620   states:
  1618 
  1621 
  1619   \begin{quote} {\bf Assumption on the number of threads created in
  1622   \begin{quote} {\bf Assumption on the number of threads created in
  1620   every valid state after the state {\boldmath@{text s}}:} Given the
  1623   every valid state after the state {\boldmath@{text s}}:} Given the
  1621   state @{text s}, in every ``future'' valid state @{text "t @ s"}, we
  1624   state @{text s}, in every ``future'' valid state @{text "t @ s"}, we
  1622   require that the number of created threads is less than
  1625   require that the number of created threads is less than
  1633   For our second assumption about giving up resources after a finite
  1636   For our second assumption about giving up resources after a finite
  1634   amount of ``time'', let us introduce the following definition about
  1637   amount of ``time'', let us introduce the following definition about
  1635   threads that can potentially block @{text th}:
  1638   threads that can potentially block @{text th}:
  1636 
  1639 
  1637   \begin{isabelle}\ \ \ \ \ %%%
  1640   \begin{isabelle}\ \ \ \ \ %%%
  1638   @{thm blockers_def}
  1641   @{thm blockers_def[THEN eq_reflection]}
  1639   \end{isabelle}
  1642   \end{isabelle}
  1640 
  1643 
  1641   \noindent This set contains all treads that are not detached in
  1644   \noindent This set contains all treads that are not detached in
  1642   state @{text s} (i.e.~they have a lock on a resource) and therefore
  1645   state @{text s} (i.e.~they have a lock on a resource) and therefore
  1643   can potentially block @{text th} after state @{text s}. We need to
  1646   can potentially block @{text th} after state @{text s}. We need to
  1659   s}. The bound reflects how each thread @{text "th'"} is programmed:
  1662   s}. The bound reflects how each thread @{text "th'"} is programmed:
  1660   Though we cannot express what instructions a thread is executing,
  1663   Though we cannot express what instructions a thread is executing,
  1661   the events in our model correspond to the system calls made by
  1664   the events in our model correspond to the system calls made by
  1662   thread. Our @{text "BND(th')"} binds the number of these calls.
  1665   thread. Our @{text "BND(th')"} binds the number of these calls.
  1663   
  1666   
  1664   The main reason for these two assumptions is that we can prove: the
  1667   The main reason for these two assumptions is that we can prove the
  1665   number of states after @{text s} in which the thread @{text th} is
  1668   following: The number of states after @{text s} in which the thread
  1666   is not running (that is where Priority Inversion occurs) can be
  1669   @{text th} is not running (that is where Priority Inversion occurs)
  1667   bounded by the number of actions the threads in @{text blockers}
  1670   can be bounded by the number of actions the threads in @{text
  1668   perform and how many threads are newly created. This bound can be
  1671   blockers} perform and how many threads are newly created. This bound
  1669   stated for all valid states @{term "t @ s"} that can happen after
  1672   can be stated for all valid intermediate states @{term "t @ s"} that
  1670   @{text s}. To state our bound we need to make a definition of what we
  1673   can happen after @{text s}. To state our bound we need to make a
  1671   mean by intermediate states: it will be the list of traces/states starting 
  1674   definition of what we mean by intermediate states; it will be the
  1672   from @{text s} ending in @{text "t @ s"}
  1675   list of states starting from @{text s} upto the state @{text "t @
       
  1676   s"}. For example, suppose $\textit{t} = 
       
  1677   [\textit{e}_n, \textit{e}_{n-1}, \ldots, \textit{e}_2, \textit{e}_1]$, then
       
  1678   the intermediate states from @{text s} upto @{text "t @ s"} are
  1673 
  1679 
  1674   \begin{center}
  1680   \begin{center}
  1675   @{text "t @ s"},\; \ldots,\; @{text "e2 :: e1 :: s"},\;@{text "e1 :: s"},\;@{text "s"}
  1681   \begin{tabular}{l}
       
  1682   $\textit{s}$\\
       
  1683   $\textit{e}_1 :: \textit{s}$\\
       
  1684   $\textit{e}_2 :: \textit{e}_1 :: \textit{s}$\\
       
  1685   \ldots\\
       
  1686   $\textit{e}_{n - 1} :: \ldots :: \textit{e}_2 :: \textit{e}_1 :: \textit{s}$\\
       
  1687   \end{tabular}
  1676   \end{center}
  1688   \end{center}
  1677 
  1689 
  1678   \noindent This can be defined by the following recursive functions
  1690 
       
  1691   \noindent This can be defined by the following recursive function
  1679 
  1692 
  1680   \begin{center}
  1693   \begin{center}
  1681   \begin{tabular}{rcl}
  1694   \begin{tabular}{lcl}
  1682   @{text "s upto t"} & $\equiv$ & @{text "if (t = []) then [s]"} \\
  1695   @{text "s upto []"} & $\dn$ & $[]$\\
  1683   & & @{text "else (t @ s) :: s upto (tail t)"}
  1696   @{text "s upto (e::es)"} & $\dn$ & @{text "(es @ s) :: s upto es"}
  1684   \end{tabular}
  1697   \end{tabular}
  1685   \end{center}
  1698   \end{center}
  1686   
  1699   
  1687 
  1700 
  1688   \noindent Assume you have an extension @{text t}, this essentially 
  1701   \noindent Assume you have an extension @{text t}, this essentially