782 (*<*) |
782 (*<*) |
783 context extend_highest_gen |
783 context extend_highest_gen |
784 begin |
784 begin |
785 (*>*) |
785 (*>*) |
786 text {* |
786 text {* |
|
787 |
787 Sha et al.~state their first correctness criterion for PIP in terms |
788 Sha et al.~state their first correctness criterion for PIP in terms |
788 of the number of low-priority threads \cite[Theorem 3]{Sha90}: if |
789 of the number of low-priority threads \cite[Theorem 3]{Sha90}: if |
789 there are @{text n} low-priority threads, then a blocked job with |
790 there are @{text n} low-priority threads, then a blocked job with |
790 high priority can only be blocked a maximum of @{text n} times. |
791 high priority can only be blocked a maximum of @{text n} times. |
791 Their second correctness criterion is given |
792 Their second correctness criterion is given in terms of the number |
792 in terms of the number of critical resources \cite[Theorem 6]{Sha90}: if there are |
793 of critical resources \cite[Theorem 6]{Sha90}: if there are @{text |
793 @{text m} critical resources, then a blocked job with high priority |
794 m} critical resources, then a blocked job with high priority can |
794 can only be blocked a maximum of @{text m} times. Both results on their own, strictly speaking, do |
795 only be blocked a maximum of @{text m} times. Both results on their |
795 \emph{not} prevent indefinite, or unbounded, Priority Inversion, |
796 own, strictly speaking, do \emph{not} prevent indefinite, or |
796 because if a low-priority thread does not give up its critical |
797 unbounded, Priority Inversion, because if a low-priority thread does |
797 resource (the one the high-priority thread is waiting for), then the |
798 not give up its critical resource (the one the high-priority thread |
798 high-priority thread can never run. The argument of Sha et al.~is |
799 is waiting for), then the high-priority thread can never run. The |
799 that \emph{if} threads release locked resources in a finite amount |
800 argument of Sha et al.~is that \emph{if} threads release locked |
800 of time, then indefinite Priority Inversion cannot occur---the high-priority |
801 resources in a finite amount of time, then indefinite Priority |
801 thread is guaranteed to run eventually. The assumption is that |
802 Inversion cannot occur---the high-priority thread is guaranteed to |
802 programmers must ensure that threads are programmed in this way. However, even |
803 run eventually. The assumption is that programmers must ensure that |
803 taking this assumption into account, the correctness properties of |
804 threads are programmed in this way. However, even taking this |
804 Sha et al.~are |
805 assumption into account, the correctness properties of Sha et |
805 \emph{not} true for their version of PIP---despite being ``proved''. As Yodaiken |
806 al.~are \emph{not} true for their version of PIP---despite being |
806 \cite{Yodaiken02} and Moylan et al.~\cite{deinheritance} pointed out: If a low-priority thread possesses |
807 ``proved''. As Yodaiken \cite{Yodaiken02} and Moylan et |
807 locks to two resources for which two high-priority threads are |
808 al.~\cite{deinheritance} pointed out: If a low-priority thread |
808 waiting for, then lowering the priority prematurely after giving up |
809 possesses locks to two resources for which two high-priority threads |
809 only one lock, can cause indefinite Priority Inversion for one of the |
810 are waiting for, then lowering the priority prematurely after giving |
810 high-priority threads, invalidating their two bounds. |
811 up only one lock, can cause indefinite Priority Inversion for one of |
|
812 the high-priority threads, invalidating their two bounds. |
811 |
813 |
812 Even when fixed, their proof idea does not seem to go through for |
814 Even when fixed, their proof idea does not seem to go through for |
813 us, because of the way we have set up our formal model of PIP. One |
815 us, because of the way we have set up our formal model of PIP. One |
814 reason is that we allow critical sections, which start with a @{text P}-event |
816 reason is that we allow critical sections, which start with a @{text |
815 and finish with a corresponding @{text V}-event, to arbitrarily overlap |
817 P}-event and finish with a corresponding @{text V}-event, to |
816 (something Sha et al.~explicitly exclude). Therefore we have |
818 arbitrarily overlap (something Sha et al.~explicitly exclude). |
817 designed a different correctness criterion for PIP. The idea behind |
819 Therefore we have designed a different correctness criterion for |
818 our criterion is as follows: for all states @{text s}, we know the |
820 PIP. The idea behind our criterion is as follows: for all states |
819 corresponding thread @{text th} with the highest precedence; we show |
821 @{text s}, we know the corresponding thread @{text th} with the |
820 that in every future state (denoted by @{text "s' @ s"}) in which |
822 highest precedence; we show that in every future state (denoted by |
821 @{text th} is still alive, either @{text th} is running or it is |
823 @{text "s' @ s"}) in which @{text th} is still alive, either @{text |
822 blocked by a thread that was alive in the state @{text s} and was waiting |
824 th} is running or it is blocked by a thread that was alive in the |
823 for or in the possession of a lock in @{text s}. Since in @{text s}, as in |
825 state @{text s} and was waiting for or in the possession of a lock |
824 every state, the set of alive threads is finite, @{text th} can only |
826 in @{text s}. Since in @{text s}, as in every state, the set of |
825 be blocked a finite number of times. This is independent of how many |
827 alive threads is finite, @{text th} can only be blocked a finite |
826 threads of lower priority are created in @{text "s'"}. We will actually prove a |
828 number of times. This is independent of how many threads of lower |
|
829 priority are created in @{text "s'"}. We will actually prove a |
827 stronger statement where we also provide the current precedence of |
830 stronger statement where we also provide the current precedence of |
828 the blocking thread. However, this correctness criterion hinges upon |
831 the blocking thread. |
829 a number of assumptions about the states @{text s} and @{text "s' @ |
832 |
830 s"}, the thread @{text th} and the events happening in @{text |
833 However, this correctness criterion hinges upon a number of |
831 s'}. We list them next: |
834 assumptions about the states @{text s} and @{text "s' @ s"}, the |
|
835 thread @{text th} and the events happening in @{text s'}. We list |
|
836 them next: |
832 |
837 |
833 \begin{quote} |
838 \begin{quote} |
834 {\bf Assumptions on the states {\boldmath@{text s}} and |
839 {\bf Assumptions on the states {\boldmath@{text s}} and |
835 {\boldmath@{text "s' @ s"}:}} We need to require that @{text "s"} and |
840 {\boldmath@{text "s' @ s"}:}} We need to require that @{text "s"} and |
836 @{text "s' @ s"} are valid states: |
841 @{text "s' @ s"} are valid states: |
870 {If}~~@{text "Exit th' \<in> set s'"}~~{then}~~@{text "th' \<noteq> th"}\\ |
875 {If}~~@{text "Exit th' \<in> set s'"}~~{then}~~@{text "th' \<noteq> th"}\\ |
871 \end{tabular} |
876 \end{tabular} |
872 \end{isabelle} |
877 \end{isabelle} |
873 \end{quote} |
878 \end{quote} |
874 |
879 |
875 \noindent |
880 \noindent The locale mechanism of Isabelle helps us to manage |
876 The locale mechanism of Isabelle helps us to manage conveniently such assumptions~\cite{Haftmann08}. |
881 conveniently such assumptions~\cite{Haftmann08}. Under these |
877 Under these assumptions we shall prove the following correctness property: |
882 assumptions we shall prove the following correctness property: |
878 |
883 |
879 \begin{theorem}\label{mainthm} |
884 \begin{theorem}\label{mainthm} |
880 Given the assumptions about states @{text "s"} and @{text "s' @ s"}, |
885 Given the assumptions about states @{text "s"} and @{text "s' @ s"}, |
881 the thread @{text th} and the events in @{text "s'"}, |
886 the thread @{text th} and the events in @{text "s'"}, |
882 if @{term "th' \<in> running (s' @ s)"} and @{text "th' \<noteq> th"} then |
887 if @{term "th' \<in> running (s' @ s)"} and @{text "th' \<noteq> th"} then |
883 @{text "th' \<in> threads s"}, @{text "\<not> detached s th'"} and |
888 @{text "th' \<in> threads s"}, @{text "\<not> detached s th'"} and |
884 @{term "cp (s' @ s) th' = prec th s"}. |
889 @{term "cp (s' @ s) th' = prec th s"}. |
885 \end{theorem} |
890 \end{theorem} |
886 |
891 |
887 \noindent |
892 \noindent This theorem ensures that the thread @{text th}, which has |
888 This theorem ensures that the thread @{text th}, which has the |
893 the highest precedence in the state @{text s}, can only be blocked |
889 highest precedence in the state @{text s}, can only be blocked in |
894 in the state @{text "s' @ s"} by a thread @{text th'} that already |
890 the state @{text "s' @ s"} by a thread @{text th'} that already |
895 existed in @{text s} and requested or had a lock on at least one |
891 existed in @{text s} and requested or had a lock on at least |
896 resource---that means the thread was not \emph{detached} in @{text |
892 one resource---that means the thread was not \emph{detached} in @{text s}. |
897 s}. As we shall see shortly, that means there are only finitely |
893 As we shall see shortly, that means there are only finitely |
898 many threads that can block @{text th} in this way and then they |
894 many threads that can block @{text th} in this way and then they |
|
895 need to run with the same precedence as @{text th}. |
899 need to run with the same precedence as @{text th}. |
896 |
900 |
897 Like in the argument by Sha et al.~our finite bound does not |
901 Like in the argument by Sha et al.~our finite bound does not |
898 guarantee absence of indefinite Priority Inversion. For this we |
902 guarantee absence of indefinite Priority Inversion. For this we |
899 further have to assume that every thread gives up its resources |
903 further have to assume that every thread gives up its resources |
900 after a finite amount of time. We found that this assumption is |
904 after a finite amount of time. We found that this assumption is |
901 awkward to formalise in our model. There are mainly two reasons for this: |
905 awkward to formalise in our model. There are mainly two reasons for |
902 First, we do not specify what ``running'' the code of a thread |
906 this: First, we do not specify what ``running'' the code of a thread |
903 means, for example by giving an operational semantics for machine |
907 means, for example by giving an operational semantics for machine |
904 instructions. Therefore we cannot characterise what are ``good'' |
908 instructions. Therefore we cannot characterise what are ``good'' |
905 programs that contain for every looking request also a corresponding |
909 programs that contain for every looking request also a corresponding |
906 unlocking request for a resource. Second, we would need to specify a |
910 unlocking request for a resource. Second, we would need to specify a |
907 kind of global clock that tracks the time how long a thread locks a |
911 kind of global clock that tracks the time how long a thread locks a |
908 resource. But this seems difficult, because how do we conveniently |
912 resource. But this seems difficult, because how do we conveniently |
909 distinguish between a thread that ``just'' lock a resource for a |
913 distinguish between a thread that ``just'' locks a resource for a |
910 very long time and one that locks it forever. Therefore we decided |
914 very long time and one that locks it forever. Therefore we decided |
911 to leave out this property and let the programmer assume the |
915 to leave out this property and let the programmer assume the |
912 responsibility to program threads in such a benign manner (in |
916 responsibility to program threads in such a benign manner (in |
913 addition to causing no circularity in the RAG). In this detail, we |
917 addition to causing no circularity in the RAG). In this detail, we |
914 do not make any progress in comparison with the work by Sha et al. |
918 do not make any progress in comparison with the work by Sha et al. |
915 However, we are able to combine their two separate bounds into a |
919 However, we are able to combine their two separate bounds into a |
916 single theorem improving their bound. |
920 single theorem improving their bound. |
917 |
921 |
|
922 In what follows we will describe properties of PIP that allow us to |
|
923 prove Theorem~\ref{mainthm} and, when instructive, briefly describe |
|
924 our argument. Recall we want to prove that in state @{term "s' @ s"} |
|
925 either @{term th} is either running or blocked by a thread @{term |
|
926 "th'"} (@{term "th \<noteq> th'"}) which was alive in state @{term s}. We |
|
927 can show that |
|
928 |
|
929 |
|
930 |
|
931 \begin{lemma} |
|
932 If @{thm (prem 2) eq_pv_blocked} |
|
933 then @{thm (concl) eq_pv_blocked} |
|
934 \end{lemma} |
|
935 |
|
936 \begin{lemma} |
|
937 If @{thm (prem 2) eq_pv_persist} |
|
938 then @{thm (concl) eq_pv_persist} |
|
939 \end{lemma} |
|
940 |
918 \subsection*{\bf OUTLINE} |
941 \subsection*{\bf OUTLINE} |
919 |
942 |
920 Since @{term "th"} is the most urgent thread, if it is somehow |
943 Since @{term "th"} is the most urgent thread, if it is somehow |
921 blocked, people want to know why and wether this blocking is |
944 blocked, people want to know why and wether this blocking is |
922 reasonable. |
945 reasonable. |