489 @{thm holding_raw_def[where thread="th"]}\\ |
489 @{thm holding_raw_def[where thread="th"]}\\ |
490 @{thm waiting_raw_def[where thread="th"]} |
490 @{thm waiting_raw_def[where thread="th"]} |
491 \end{tabular} |
491 \end{tabular} |
492 \end{isabelle} |
492 \end{isabelle} |
493 |
493 |
494 \noindent |
494 \noindent In this definition we assume that @{text "set"} converts a |
495 In this definition we assume that @{text "set"} converts a list into a set. |
495 list into a set. Note that in the first definition the condition |
496 Note that in the first definition the condition about @{text "th \<in> set (wq cs)"} does not follow |
496 about @{text "th \<in> set (wq cs)"} does not follow from @{text "th |
497 from @{text "th = hd (set (wq cs))"}, since the head of an empty list is undefined in Isabelle/HOL. |
497 = hd (set (wq cs))"}, since the head of an empty list is undefined |
498 At the beginning, that is in the state where no thread is created yet, |
498 in Isabelle/HOL. At the beginning, that is in the state where no |
499 the waiting queue function will be the function that returns the |
499 thread is created yet, the waiting queue function will be the |
500 empty list for every resource. |
500 function that returns the empty list for every resource. |
501 |
501 |
502 \begin{isabelle}\ \ \ \ \ %%% |
502 \begin{isabelle}\ \ \ \ \ %%% |
503 @{abbrev all_unlocked}\hfill\numbered{allunlocked} |
503 @{abbrev all_unlocked}\hfill\numbered{allunlocked} |
504 \end{isabelle} |
504 \end{isabelle} |
505 |
505 |
561 \end{center} |
561 \end{center} |
562 \caption{An instance of a Resource Allocation Graph (RAG).\label{RAGgraph}} |
562 \caption{An instance of a Resource Allocation Graph (RAG).\label{RAGgraph}} |
563 \end{figure} |
563 \end{figure} |
564 |
564 |
565 \noindent |
565 \noindent |
566 If there is no cycle, then every @{text RAG} can be pictured as a forrest of trees, as |
566 If there is no cycle, then every @{text RAG} can be pictured as a forest of trees, as |
567 for example in Figure~\ref{RAGgraph}. |
567 for example in Figure~\ref{RAGgraph}. |
568 |
568 |
569 Because of the @{text RAG}s, we will need to formalise some results about |
569 Because of the @{text RAG}s, we will need to formalise some results |
570 graphs. While there are few formalisations for graphs already |
570 about graphs. While there are few formalisations for graphs already |
571 implemented in Isabelle, we choose to introduce our own library of |
571 implemented in Isabelle, we choose to introduce our own library of |
572 graphs for PIP. The justification for this is that we wanted |
572 graphs for PIP. The justification for this is that we wanted to have |
573 to have a more general theory of graphs which is capable of |
573 a more general theory of graphs which is capable of representing |
574 representing potentially infinite graphs (in the sense of infinitely |
574 potentially infinite graphs (in the sense of infinitely branching |
575 branching and infinite size): the property that our @{text RAG}s are |
575 and infinite size): the property that our @{text RAG}s are actually |
576 actually forrests of finitely branching trees having only an finite |
576 forests of finitely branching trees having only an finite depth |
577 depth should be something we can \emph{prove} for our model of |
577 should be something we can \emph{prove} for our model of PIP---it |
578 PIP---it should not be an assumption we build already into our |
578 should not be an assumption we build already into our model. It |
579 model. It seemed for our purposes the most convenient |
579 seemed for our purposes the most convenient represeantation of |
580 represeantation of graphs are binary relations given by sets of |
580 graphs are binary relations given by sets of pairs shown in |
581 pairs shown in \eqref{pairs}. The pairs stand for the edges in |
581 \eqref{pairs}. The pairs stand for the edges in graphs. This |
582 graphs. This relation-based representation is convenient since we |
582 relation-based representation has the advantage that the notions |
583 can use the notions of transitive closure operations @{term "trancl |
583 @{text "waiting"} and @{text "holiding"} are already defined in |
584 DUMMY"} and @{term "rtrancl DUMMY"}, as well as relation |
584 terms of relations amongst theads and resources. Also, we can easily |
585 composition. A \emph{forrest} is defined in our representation as the relation @{text |
585 re-use the standard notions for transitive closure operations @{term |
586 rel} that is \emph{single valued} and \emph{acyclic}: |
586 "trancl DUMMY"} and @{term "rtrancl DUMMY"}, as well as relation |
|
587 composition for our graphs. A \emph{forest} is defined in our |
|
588 representation as the relation @{text rel} that is \emph{single |
|
589 valued} and \emph{acyclic}: |
587 |
590 |
588 \begin{isabelle}\ \ \ \ \ %%% |
591 \begin{isabelle}\ \ \ \ \ %%% |
589 \begin{tabular}{@ {}l} |
592 \begin{tabular}{@ {}l} |
590 @{thm single_valued_def[where ?r="rel", THEN eq_reflection]}\\ |
593 @{thm single_valued_def[where ?r="rel", THEN eq_reflection]}\\ |
591 @{thm acyclic_def[where ?r="rel", THEN eq_reflection]} |
594 @{thm acyclic_def[where ?r="rel", THEN eq_reflection]} |
603 @{thm ancestors_def[where ?r="rel" and ?x="node", THEN eq_reflection]}\\ |
606 @{thm ancestors_def[where ?r="rel" and ?x="node", THEN eq_reflection]}\\ |
604 \end{tabular}\\ |
607 \end{tabular}\\ |
605 \mbox{}\hfill\numbered{children} |
608 \mbox{}\hfill\numbered{children} |
606 \end{isabelle} |
609 \end{isabelle} |
607 |
610 |
608 \noindent Note that forrests can have trees with infinte depth and |
611 \noindent Note that forests can have trees with infinte depth and |
609 containing nodes with infinitely many children. A \emph{finite |
612 containing nodes with infinitely many children. A \emph{finite |
610 forrest} is a forrest which is well-founded and every node has |
613 forest} is a forest whose underlying relation is |
611 finitely many children (is only finitely branching). |
614 well-founded\footnote{For \emph{well-founded} we use the quite natural |
|
615 definition from Isabelle.} |
|
616 and every node has finitely many children (is only finitely |
|
617 branching). |
612 |
618 |
613 %\endnote{ |
619 %\endnote{ |
614 %\begin{isabelle}\ \ \ \ \ %%% |
620 %\begin{isabelle}\ \ \ \ \ %%% |
615 %@ {thm rtrancl_path.intros} |
621 %@ {thm rtrancl_path.intros} |
616 %\end{isabelle} |
622 %\end{isabelle} |
1183 |
1189 |
1184 |
1190 |
1185 \begin{proof}[of Theorem 1] If @{term "th \<in> running (s' @ s)"}, |
1191 \begin{proof}[of Theorem 1] If @{term "th \<in> running (s' @ s)"}, |
1186 then there is nothing to show. So let us assume otherwise. Since the |
1192 then there is nothing to show. So let us assume otherwise. Since the |
1187 @{text "RAG"} is well-founded, we know there exists an ancestor of |
1193 @{text "RAG"} is well-founded, we know there exists an ancestor of |
1188 @{text "th"} that is the root of the corrsponding subtree and |
1194 @{text "th"} that is the root of the corresponding subtree and |
1189 therefore is ready (it does not request any resources). Let us call |
1195 therefore is ready (it does not request any resources). Let us call |
1190 this thread @{text "th'"}. Since in PIP the @{term "cpreced"}-value |
1196 this thread @{text "th'"}. Since in PIP the @{term "cpreced"}-value |
1191 of any thread equals the maximum precedence of all threads in its |
1197 of any thread equals the maximum precedence of all threads in its |
1192 @{term "RAG"}-subtree, and @{text "th"} is in the subtree of @{text |
1198 @{term "RAG"}-subtree, and @{text "th"} is in the subtree of @{text |
1193 "th'"}, the @{term "cpreced"}-value of @{text "th'"} cannot be lower |
1199 "th'"}, the @{term "cpreced"}-value of @{text "th'"} cannot be lower |
1610 reasons for this: First, we do not specify what ``running the code'' |
1616 reasons for this: First, we do not specify what ``running the code'' |
1611 of a thread means, for example by giving an operational semantics |
1617 of a thread means, for example by giving an operational semantics |
1612 for machine instructions. Therefore we cannot characterise what are |
1618 for machine instructions. Therefore we cannot characterise what are |
1613 ``good'' programs that contain for every locking request for a |
1619 ``good'' programs that contain for every locking request for a |
1614 resource also a corresponding unlocking request. Second, we need to |
1620 resource also a corresponding unlocking request. Second, we need to |
1615 distinghish between a thread that ``just'' locks a resource for a |
1621 distinguish between a thread that ``just'' locks a resource for a |
1616 finite amount of time (even if it is very long) and one that locks |
1622 finite amount of time (even if it is very long) and one that locks |
1617 it forever (there might be an unbounded loop in between the locking and |
1623 it forever (there might be an unbounded loop in between the locking and |
1618 unlocking requests). |
1624 unlocking requests). |
1619 |
1625 |
1620 Because of these problems, we decided in our earlier paper |
1626 Because of these problems, we decided in our earlier paper |
1636 events). For this finiteness bound to exist, Sha et al.~informally |
1642 events). For this finiteness bound to exist, Sha et al.~informally |
1637 make two assumptions: first, there is a finite pool of threads |
1643 make two assumptions: first, there is a finite pool of threads |
1638 (active or hibernating) and second, each of them giving up its |
1644 (active or hibernating) and second, each of them giving up its |
1639 resources after a finite amount of time. However, we do not have |
1645 resources after a finite amount of time. However, we do not have |
1640 this concept of active or hibernating threads in our model. In fact |
1646 this concept of active or hibernating threads in our model. In fact |
1641 we can dispence with the first assumption altogether and allow that |
1647 we can dispense with the first assumption altogether and allow that |
1642 in our model we can create new threads or exit existing threads |
1648 in our model we can create new threads or exit existing threads |
1643 arbitrarily. Consequently, the avoidance of indefinite priority |
1649 arbitrarily. Consequently, the avoidance of indefinite priority |
1644 inversion we are trying to establish is in our model not true, |
1650 inversion we are trying to establish is in our model not true, |
1645 unless we stipulate an upper bound on the number of threads that |
1651 unless we stipulate an upper bound on the number of threads that |
1646 have been created during the time leading to any future state |
1652 have been created during the time leading to any future state |
1647 after @{term s}. Otherwise our PIP scheduler could be ``swamped'' |
1653 after @{term s}. Otherwise our PIP scheduler could be ``swamped'' |
1648 with @{text "Create"}-requests. So our first assumption states: |
1654 with @{text "Create"}-requests from of lower priority threads. |
|
1655 So our first assumption states: |
1649 |
1656 |
1650 \begin{quote} {\bf Assumption on the number of threads created |
1657 \begin{quote} {\bf Assumption on the number of threads created |
1651 after the state {\boldmath@{text s}}:} Given the |
1658 after the state {\boldmath@{text s}}:} Given the |
1652 state @{text s}, in every ``future'' valid state @{text "es @ s"}, we |
1659 state @{text s}, in every ``future'' valid state @{text "es @ s"}, we |
1653 require that the number of created threads is less than |
1660 require that the number of created threads is less than |
1697 anymore) after a finite number of events in @{text "es @ s"}. Again |
1704 anymore) after a finite number of events in @{text "es @ s"}. Again |
1698 we have to state this bound to hold in all valid states after @{text |
1705 we have to state this bound to hold in all valid states after @{text |
1699 s}. The bound reflects how each thread @{text "th'"} is programmed: |
1706 s}. The bound reflects how each thread @{text "th'"} is programmed: |
1700 Though we cannot express what instructions a thread is executing, |
1707 Though we cannot express what instructions a thread is executing, |
1701 the events in our model correspond to the system calls made by |
1708 the events in our model correspond to the system calls made by |
1702 a thread. Our @{text "BND(th')"} binds the number of these ``calls''. |
1709 a thread. Our @{text "BND(th')"} bounds the number of these ``calls''. |
1703 |
1710 |
1704 The main reason for these two assumptions is that we can prove the |
1711 The main reason for these two assumptions is that we can prove the |
1705 following: The number of states after @{text s} in which the thread |
1712 following: The number of states after @{text s} in which the thread |
1706 @{text th} is not running (that is where Priority Inversion occurs) |
1713 @{text th} is not running (that is where Priority Inversion occurs) |
1707 can be bounded by the number of actions the threads in @{text |
1714 can be bounded by the number of actions the threads in @{text |