155 checking techniques. This paper presents a formalised and |
155 checking techniques. This paper presents a formalised and |
156 mechanically checked proof for the correctness of PIP (to our |
156 mechanically checked proof for the correctness of PIP (to our |
157 knowledge the first one; the earlier informal proof by Sha et |
157 knowledge the first one; the earlier informal proof by Sha et |
158 al.~\cite{Sha90} is flawed). In contrast to model checking, our |
158 al.~\cite{Sha90} is flawed). In contrast to model checking, our |
159 formalisation provides insight into why PIP is correct and allows us |
159 formalisation provides insight into why PIP is correct and allows us |
160 to prove stronger properties that, as we will show, inform an |
160 to prove stronger properties that, as we will show, can inform an |
161 implementation. For example, we found by ``playing'' with the formalisation |
161 implementation. For example, we found by ``playing'' with the formalisation |
162 that the choice of the next thread to take over a lock when a |
162 that the choice of the next thread to take over a lock when a |
163 resource is released is irrelevant for PIP being correct. Something |
163 resource is released is irrelevant for PIP being correct. Something |
164 which has not been mentioned in the relevant literature. |
164 which has not been mentioned in the relevant literature. |
165 *} |
165 *} |
548 \noindent |
548 \noindent |
549 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 |
550 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 |
551 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 |
552 of course the responsibility of the programmer. In our formal |
552 of course the responsibility of the programmer. In our formal |
553 model we just exclude such problematic cases in order to make |
553 model we just exclude such problematic cases in order to be able to make |
554 some meaningful statements about PIP.\footnote{This situation is |
554 some meaningful statements about PIP.\footnote{This situation is |
555 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 |
556 anything meaningful about unification, one needs to perform an occurs |
556 anything meaningful about unification, one needs to perform an occurs |
557 check, but in practice the occurs check is ommited and the |
557 check. But in practice the occurs check is ommited and the |
558 responsibility for avoiding problems rests with the programmer.} |
558 responsibility for avoiding problems rests with the programmer.} |
559 |
559 |
560 \begin{center} |
560 \begin{center} |
561 @{thm[mode=Rule] thread_P[where thread=th]} |
561 @{thm[mode=Rule] thread_P[where thread=th]} |
562 \end{center} |
562 \end{center} |
583 \noindent |
583 \noindent |
584 This completes our formal model of PIP. In the next section we present |
584 This completes our formal model of PIP. In the next section we present |
585 properties that show our model of PIP is correct. |
585 properties that show our model of PIP is correct. |
586 *} |
586 *} |
587 |
587 |
588 section {* Correctness Proof *} |
588 section {* The Correctness Proof *} |
589 |
589 |
590 (*<*) |
590 (*<*) |
591 context extend_highest_gen |
591 context extend_highest_gen |
592 begin |
592 begin |
593 print_locale extend_highest_gen |
593 print_locale extend_highest_gen |
594 thm extend_highest_gen_def |
594 thm extend_highest_gen_def |
595 thm extend_highest_gen_axioms_def |
595 thm extend_highest_gen_axioms_def |
596 thm highest_gen_def |
596 thm highest_gen_def |
597 (*>*) |
597 (*>*) |
598 text {* |
598 text {* |
599 Sha et al.~\cite{Sha90} state their correctness criterion of PIP in terms |
599 Sha et al.~\cite[Theorem 6]{Sha90} state their correctness criterion for PIP in terms |
600 of the number of critical resources: if there are @{text m} critical |
600 of the number of critical resources: if there are @{text m} critical |
601 resources, then a blocked job can only be blocked @{text m} times---that is |
601 resources, then a blocked job can only be blocked @{text m} times---that is |
602 a bounded number of times. |
602 a bounded number of times. |
603 For their version of PIP, this property is \emph{not} true (as pointed out by |
603 For their version of PIP, this property is \emph{not} true (as pointed out by |
604 Yodaiken \cite{Yodaiken02}) as a high-priority thread can be |
604 Yodaiken \cite{Yodaiken02}) as a high-priority thread can be |
605 blocked an unbounded number of times by creating medium-priority |
605 blocked an unbounded number of times by creating medium-priority |
606 threads that block a thread locking a critical resource and having |
606 threads that block a thread, which in turn locks a critical resource and has |
607 a too low priority. In the way we have set up our formal model of PIP, |
607 too low priority to make progress. In the way we have set up our formal model of PIP, |
608 their proof idea, even when fixed, does not seem to go through. |
608 their proof idea, even when fixed, does not seem to go through. |
609 |
609 |
610 The idea behind our correctness criterion of PIP is as follows: for all states |
610 The idea behind our correctness criterion of PIP is as follows: for all states |
611 @{text s}, we know the corresponding thread @{text th} with the highest precedence; |
611 @{text s}, we know the corresponding thread @{text th} with the highest precedence; |
612 we show that in every future state (denoted by @{text "s' @ s"}) in which |
612 we show that in every future state (denoted by @{text "s' @ s"}) in which |
613 @{text th} is still active, either @{text th} is running or it is blocked by a |
613 @{text th} is still alive, either @{text th} is running or it is blocked by a |
614 thread that was active in the state @{text s}. Since in @{text s}, as in every |
614 thread that was alive in the state @{text s}. Since in @{text s}, as in every |
615 state, the set of active threads is finite, @{text th} can only be blocked a |
615 state, the set of alive threads is finite, @{text th} can only be blocked a |
616 finite number of times. We will actually prove a stricter bound. However, |
616 finite number of times. We will actually prove a stricter bound below. However, |
617 this correctness criterion hinges on a number of assumptions about the states |
617 this correctness criterion hinges upon a number of assumptions about the states |
618 @{text s} and @{text "s' @ s"}, the thread @{text th} and the events happening |
618 @{text s} and @{text "s' @ s"}, the thread @{text th} and the events happening |
619 in @{text s'}. We list them next. |
619 in @{text s'}. We list them next: |
620 |
620 |
621 \begin{quote} |
621 \begin{quote} |
622 {\bf Assumptions on the states @{text s} and @{text "s' @ s"}:} In order to make |
622 {\bf Assumptions on the states @{text s} and @{text "s' @ s"}:} In order to make |
623 any meaningful statement, we need to require that @{text "s"} and |
623 any meaningful statement, we need to require that @{text "s"} and |
624 @{text "s' @ s"} are valid states, namely |
624 @{text "s' @ s"} are valid states, namely |
646 \begin{quote} |
646 \begin{quote} |
647 {\bf Assumptions on the events in @{text "s'"}:} We want to prove that @{text th} cannot |
647 {\bf Assumptions on the events in @{text "s'"}:} We want to prove that @{text th} cannot |
648 be blocked indefinitely. Of course this can happen if threads with higher priority |
648 be blocked indefinitely. Of course this can happen if threads with higher priority |
649 than @{text th} are continously created in @{text s'}. Therefore we have to assume that |
649 than @{text th} are continously created in @{text s'}. Therefore we have to assume that |
650 events in @{text s'} can only create (respectively set) threads with equal or lower |
650 events in @{text s'} can only create (respectively set) threads with equal or lower |
651 priority than @{text prio} of the thread @{text th}. We also have to assume that @{text th} does |
651 priority than @{text prio} of @{text th}. We also need to assume that the |
652 not get ``exited'' in @{text "s'"}. |
652 priority of @{text "th"} does not get reset and also that @{text th} does |
|
653 not get ``exited'' in @{text "s'"}. This can be ensured by assuming the following three implications. |
653 \begin{isabelle}\ \ \ \ \ %%% |
654 \begin{isabelle}\ \ \ \ \ %%% |
654 \begin{tabular}{l} |
655 \begin{tabular}{l} |
655 {If}~~@{text "Create _ prio' \<in> set s'"}~~{then}~~@{text "prio' \<le> prio"}\\ |
656 {If}~~@{text "Create th' prio' \<in> set s'"}~~{then}~~@{text "prio' \<le> prio"}\\ |
656 {If}~~@{text "Set th' prio' \<in> set s'"}~~{then}~~@{text "th' \<noteq> th"}~~{and}~~@{text "prio' \<le> prio"}\\ |
657 {If}~~@{text "Set th' prio' \<in> set s'"}~~{then}~~@{text "th' \<noteq> th"}~~{and}~~@{text "prio' \<le> prio"}\\ |
657 {If}~~@{text "Exit th' \<in> set s'"}~~{then}~~@{text "th' \<noteq> th"}\\ |
658 {If}~~@{text "Exit th' \<in> set s'"}~~{then}~~@{text "th' \<noteq> th"}\\ |
658 \end{tabular} |
659 \end{tabular} |
659 \end{isabelle} |
660 \end{isabelle} |
660 \end{quote} |
661 \end{quote} |
661 |
662 |
662 \noindent |
663 \noindent |
663 Under these assumptions we will prove the following property: |
664 Under these assumptions we will prove the following correctness property: |
664 |
665 |
665 \begin{theorem}\label{mainthm} |
666 \begin{theorem}\label{mainthm} |
666 Given the assumptions about states @{text "s"} and @{text "s' @ s"}, |
667 Given the assumptions about states @{text "s"} and @{text "s' @ s"}, |
667 the thread @{text th} and the events in @{text "s'"}, |
668 the thread @{text th} and the events in @{text "s'"}, |
668 if @{term "th' \<in> running (s' @ s)"} and @{text "th' \<noteq> th"} then |
669 if @{term "th' \<in> running (s' @ s)"} and @{text "th' \<noteq> th"} then |
672 \noindent |
673 \noindent |
673 This theorem ensures that the thread @{text th}, which has the highest |
674 This theorem ensures that the thread @{text th}, which has the highest |
674 precedence in the state @{text s}, can only be blocked in the state @{text "s' @ s"} |
675 precedence in the state @{text s}, can only be blocked in the state @{text "s' @ s"} |
675 by a thread @{text th'} that already existed in @{text s}. As we shall see shortly, |
676 by a thread @{text th'} that already existed in @{text s}. As we shall see shortly, |
676 that means by only finitely many threads. Consequently, indefinite wait of |
677 that means by only finitely many threads. Consequently, indefinite wait of |
677 @{text th}---whcih is Priority Inversion---cannot occur. |
678 @{text th}---which would be Priority Inversion---cannot occur. |
678 |
679 |
679 In what follows we will describe properties of PIP that allow us to prove |
680 In what follows we will describe properties of PIP that allow us to prove |
680 Theorem~\ref{mainthm}. It is relatively easily to see that |
681 Theorem~\ref{mainthm}. It is relatively easily to see that |
681 |
682 |
682 \begin{isabelle}\ \ \ \ \ %%% |
683 \begin{isabelle}\ \ \ \ \ %%% |
698 \end{tabular} |
699 \end{tabular} |
699 \end{isabelle} |
700 \end{isabelle} |
700 |
701 |
701 \noindent |
702 \noindent |
702 The first one states that every waiting thread can only wait for a single |
703 The first one states that every waiting thread can only wait for a single |
703 resource (because it gets suspended after requesting that resource), and |
704 resource (because it gets suspended after requesting that resource and having |
704 the second that every resource can only be held by a single thread. The |
705 to wait for it); the second that every resource can only be held by a single thread; |
705 third property establishes that in every given valid state, there is |
706 the third property establishes that in every given valid state, there is |
706 at most one running thread. |
707 at most one running thread. We can also show the following properties |
|
708 about the RAG in @{text "s"}. |
|
709 |
|
710 \begin{isabelle}\ \ \ \ \ %%% |
|
711 \begin{tabular}{@ {}l} |
|
712 %@{thm[mode=IfThen] }\\ |
|
713 %@{thm[mode=IfThen] }\\ |
|
714 %@{thm[mode=IfThen] } |
|
715 \end{tabular} |
|
716 \end{isabelle} |
707 |
717 |
708 TODO |
718 TODO |
709 |
719 |
710 \noindent |
720 \noindent |
711 The following lemmas show how RAG is changed with the execution of events: |
721 The following lemmas show how RAG is changed with the execution of events: |