809 |
812 |
810 (*<*) |
813 (*<*) |
811 end |
814 end |
812 (*>*) |
815 (*>*) |
813 |
816 |
814 section {* Properties for an Implementation \label{implement}*} |
817 section {* Properties for an Implementation\label{implement}*} |
815 |
818 |
816 text {* |
819 text {* |
817 The properties (centered around @{text "runing_inversion_2"} in particular) |
820 While a formal correctness proof for our model of PIP is certainly |
818 convinced us that the formal model |
821 attractive (especially in light of the flawed proof by Sha et |
819 in Section \ref{model} does prevent indefinite priority inversion and therefore fulfills |
822 al.~\cite{Sha90}), we found that the formalisation can even help us |
820 the fundamental requirement of Priority Inheritance protocol. Another purpose of this paper |
823 with efficiently implementing PIP. |
821 is to show how this model can be used to guide a concrete implementation. |
824 |
822 |
825 For example Baker complained that calculating the current precedence |
823 The difficult part of implementation is the calculation of current precedence. |
826 in PIP is quite ``heavy weight'' in Linux (see our Introduction). |
824 Once current precedence is computed efficiently and correctly, |
827 In our model of PIP the current precedence of a thread in a state s |
825 the selection of the thread with highest precedence from ready threads is a |
828 depends on all its dependants---a ``global'' transitive notion, |
826 standard scheduling mechanism implemented in most operating systems. |
829 which is indeed heavy weight (see Def.~shown in \eqref{cpreced}). |
827 |
830 We can however prove how to improve upon this. For this let us |
828 Our implementation related formalization focuses on how to compute |
831 define the notion of @{term children} of a thread as |
829 current precedence. First, it can be proved that the computation of current |
832 |
830 precedence @{term "cp"} of a threads |
833 \begin{isabelle}\ \ \ \ \ %%% |
831 only involves its children (@{text "cp_rec"}): |
834 \begin{tabular}{@ {}l} |
832 @{thm [display] cp_rec} |
835 @{thm children_def2} |
833 where @{term "children s th"} represents the set of children of @{term "th"} in the current |
836 \end{tabular} |
834 RAG: |
837 \end{isabelle} |
835 \[ |
838 |
836 @{thm (lhs) children_def} @{text "\<equiv>"} @{thm (rhs) children_def} |
839 \noindent |
837 \] |
840 where a child is a thread that is one ``hop'' away in the @{term RAG} from the |
838 where the definition of @{term "child"} is: |
841 tread @{text th} (and waiting for @{text th} to release a resource). We can prove that |
839 \[ @{thm (lhs) child_def} @{text "\<equiv>"} @{thm (rhs) child_def} |
842 |
840 \] |
843 \begin{lemma}\label{childrenlem} |
841 which corresponds a two hop link between threads in the RAG, with a resource in the middle. |
844 @{text "If"} @{thm (prem 1) cp_rec} @{text "then"} |
|
845 \begin{center} |
|
846 @{thm (concl) cp_rec}. |
|
847 \end{center} |
|
848 \end{lemma} |
842 |
849 |
843 Lemma @{text "cp_rec"} means, the current precedence of threads can be computed locally, |
850 \noindent |
844 i.e. the current precedence of one thread only needs to be recomputed when some of its |
851 That means the current precedence of a thread @{text th} can be |
845 children change their current precedence. |
852 computed locally by considering only the children of @{text th}. In |
846 |
853 effect, it only needs to be recomputed for @{text th} when one of |
847 Each of the following subsections discusses one event type, investigating |
854 its children change their current precedence. Once the current |
848 which parts in the RAG need current precedence re-computation when that type of event |
855 precedence is computed in this more efficient manner, the selection |
849 happens. |
856 of the thread with highest precedence from a set of ready threads is |
850 *} |
857 a standard scheduling operation implemented in most operating |
851 |
858 systems. |
852 subsection {* Event @{text "Set th prio"} *} |
859 |
853 |
860 Of course the main implementation work for PIP involves the scheduler |
854 (*<*) |
861 and coding how it should react to the events, for example which |
855 context step_set_cps |
862 datastructures need to be modified (mainly @{text RAG} and @{text cprec}). |
856 begin |
863 Below we outline how our formalisation guides this implementation for each |
857 (*>*) |
864 event.\smallskip |
858 |
|
859 text {* |
|
860 The context under which event @{text "Set th prio"} happens is formalized as follows: |
|
861 \begin{enumerate} |
|
862 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
863 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
864 event @{text "Set th prio"} is eligible to happen under state @{term "s'"} and |
|
865 state @{term "s'"} is a valid state. |
|
866 \end{enumerate} |
|
867 *} |
|
868 |
|
869 text {* \noindent |
|
870 Under such a context, we investigated how the current precedence @{term "cp"} of |
|
871 threads change from state @{term "s'"} to @{term "s"} and obtained the following |
|
872 results: |
|
873 \begin{enumerate} |
|
874 %% \item The RAG does not change (@{text "eq_dep"}): @{thm "eq_dep"}. |
|
875 \item All threads with no dependence relation with thread @{term "th"} have their |
|
876 @{term "cp"}-value unchanged (@{text "eq_cp"}): |
|
877 @{thm [display] eq_cp} |
|
878 This lemma implies the @{term "cp"}-value of @{term "th"} |
|
879 and those threads which have a dependence relation with @{term "th"} might need |
|
880 to be recomputed. The way to do this is to start from @{term "th"} |
|
881 and follow the @{term "depend"}-chain to recompute the @{term "cp"}-value of every |
|
882 encountered thread using lemma @{text "cp_rec"}. |
|
883 Since the @{term "depend"}-relation is loop free, this procedure |
|
884 can always stop. The the following lemma shows this procedure actually could stop earlier. |
|
885 \item The following two lemma shows, if a thread the re-computation of which |
|
886 gives an unchanged @{term "cp"}-value, the procedure described above can stop. |
|
887 \begin{enumerate} |
|
888 \item Lemma @{text "eq_up_self"} shows if the re-computation of |
|
889 @{term "th"}'s @{term "cp"} gives the same result, the procedure can stop: |
|
890 @{thm [display] eq_up_self} |
|
891 \item Lemma @{text "eq_up"}) shows if the re-computation at intermediate threads |
|
892 gives unchanged result, the procedure can stop: |
|
893 @{thm [display] eq_up} |
|
894 \end{enumerate} |
|
895 \end{enumerate} |
|
896 *} |
|
897 |
|
898 (*<*) |
|
899 end |
|
900 (*>*) |
|
901 |
|
902 subsection {* Event @{text "V th cs"} *} |
|
903 |
|
904 (*<*) |
|
905 context step_v_cps_nt |
|
906 begin |
|
907 (*>*) |
|
908 |
|
909 text {* |
|
910 The context under which event @{text "V th cs"} happens is formalized as follows: |
|
911 \begin{enumerate} |
|
912 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
913 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
914 event @{text "V th cs"} is eligible to happen under state @{term "s'"} and |
|
915 state @{term "s'"} is a valid state. |
|
916 \end{enumerate} |
|
917 *} |
|
918 |
|
919 text {* \noindent |
|
920 Under such a context, we investigated how the current precedence @{term "cp"} of |
|
921 threads change from state @{term "s'"} to @{term "s"}. |
|
922 |
|
923 |
|
924 Two subcases are considerted, |
|
925 where the first is that there exits @{term "th'"} |
|
926 such that |
|
927 @{thm [display] nt} |
|
928 holds, which means there exists a thread @{term "th'"} to take over |
|
929 the resource release by thread @{term "th"}. |
|
930 In this sub-case, the following results are obtained: |
|
931 \begin{enumerate} |
|
932 \item The change of RAG is given by lemma @{text "depend_s"}: |
|
933 @{thm [display] "depend_s"} |
|
934 which shows two edges are removed while one is added. These changes imply how |
|
935 the current precedences should be re-computed. |
|
936 \item First all threads different from @{term "th"} and @{term "th'"} have their |
|
937 @{term "cp"}-value kept, therefore do not need a re-computation |
|
938 (@{text "cp_kept"}): @{thm [display] cp_kept} |
|
939 This lemma also implies, only the @{term "cp"}-values of @{term "th"} and @{term "th'"} |
|
940 need to be recomputed. |
|
941 \end{enumerate} |
|
942 *} |
|
943 |
|
944 (*<*) |
|
945 end |
|
946 |
|
947 context step_v_cps_nnt |
|
948 begin |
|
949 (*>*) |
|
950 |
|
951 text {* |
|
952 The other sub-case is when for all @{text "th'"} |
|
953 @{thm [display] nnt} |
|
954 holds, no such thread exists. The following results can be obtained for this |
|
955 sub-case: |
|
956 \begin{enumerate} |
|
957 \item The change of RAG is given by lemma @{text "depend_s"}: |
|
958 @{thm [display] depend_s} |
|
959 which means only one edge is removed. |
|
960 \item In this case, no re-computation is needed (@{text "eq_cp"}): |
|
961 @{thm [display] eq_cp} |
|
962 \end{enumerate} |
|
963 *} |
|
964 |
|
965 (*<*) |
|
966 end |
|
967 (*>*) |
|
968 |
|
969 |
|
970 subsection {* Event @{text "P th cs"} *} |
|
971 |
|
972 (*<*) |
|
973 context step_P_cps_e |
|
974 begin |
|
975 (*>*) |
|
976 |
|
977 text {* |
|
978 The context under which event @{text "P th cs"} happens is formalized as follows: |
|
979 \begin{enumerate} |
|
980 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
981 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
982 event @{text "P th cs"} is eligible to happen under state @{term "s'"} and |
|
983 state @{term "s'"} is a valid state. |
|
984 \end{enumerate} |
|
985 |
|
986 This case is further divided into two sub-cases. The first is when @{thm ee} holds. |
|
987 The following results can be obtained: |
|
988 \begin{enumerate} |
|
989 \item One edge is added to the RAG (@{text "depend_s"}): |
|
990 @{thm [display] depend_s} |
|
991 \item No re-computation is needed (@{text "eq_cp"}): |
|
992 @{thm [display] eq_cp} |
|
993 \end{enumerate} |
|
994 *} |
865 *} |
995 |
|
996 (*<*) |
|
997 end |
|
998 |
|
999 context step_P_cps_ne |
|
1000 begin |
|
1001 (*>*) |
|
1002 |
|
1003 text {* |
|
1004 The second is when @{thm ne} holds. |
|
1005 The following results can be obtained: |
|
1006 \begin{enumerate} |
|
1007 \item One edge is added to the RAG (@{text "depend_s"}): |
|
1008 @{thm [display] depend_s} |
|
1009 \item Threads with no dependence relation with @{term "th"} do not need a re-computation |
|
1010 of their @{term "cp"}-values (@{text "eq_cp"}): |
|
1011 @{thm [display] eq_cp} |
|
1012 This lemma implies all threads with a dependence relation with @{term "th"} may need |
|
1013 re-computation. |
|
1014 \item Similar to the case of @{term "Set"}, the computation procedure could stop earlier |
|
1015 (@{text "eq_up"}): |
|
1016 @{thm [display] eq_up} |
|
1017 \end{enumerate} |
|
1018 |
|
1019 *} |
|
1020 |
|
1021 (*<*) |
|
1022 end |
|
1023 (*>*) |
|
1024 |
|
1025 subsection {* Event @{text "Create th prio"} *} |
|
1026 |
866 |
1027 (*<*) |
867 (*<*) |
1028 context step_create_cps |
868 context step_create_cps |
1029 begin |
869 begin |
1030 (*>*) |
870 (*>*) |
1031 |
871 text {* |
1032 text {* |
872 \noindent |
1033 The context under which event @{text "Create th prio"} happens is formalized as follows: |
873 @{term "Create th prio"}: We assume that the current state @{text s'} and |
1034 \begin{enumerate} |
874 the next state @{term "s \<equiv> Create th prio#s'"} are both valid (meaning the event |
1035 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
875 is allowed to occur). In this situation we can show that |
1036 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
876 |
1037 event @{text "Create th prio"} is eligible to happen under state @{term "s'"} and |
877 \begin{isabelle}\ \ \ \ \ %%% |
1038 state @{term "s'"} is a valid state. |
878 \begin{tabular}{@ {}l} |
1039 \end{enumerate} |
879 @{thm eq_dep}\\ |
1040 The following results can be obtained under this context: |
880 @{thm eq_cp_th}\\ |
1041 \begin{enumerate} |
881 @{thm[mode=IfThen] eq_cp} |
1042 \item The RAG does not change (@{text "eq_dep"}): |
882 \end{tabular} |
1043 @{thm [display] eq_dep} |
883 \end{isabelle} |
1044 \item All threads other than @{term "th"} do not need re-computation (@{text "eq_cp"}): |
884 |
1045 @{thm [display] eq_cp} |
885 \noindent |
1046 \item The @{term "cp"}-value of @{term "th"} equals its precedence |
886 This means we do not have recalculate the @{text RAG} and also none of the |
1047 (@{text "eq_cp_th"}): |
887 current precedences of the other threads. The current precedence of the created |
1048 @{thm [display] eq_cp_th} |
888 thread is just its precedence, that is the pair @{term "(prio, length (s::event list))"}. |
1049 \end{enumerate} |
889 \smallskip |
1050 |
890 *} |
|
891 (*<*) |
|
892 end |
|
893 context step_exit_cps |
|
894 begin |
|
895 (*>*) |
|
896 text {* |
|
897 \noindent |
|
898 @{term "Exit th"}: We again assume that the current state @{text s'} and |
|
899 the next state @{term "s \<equiv> Exit th#s'"} are both valid. We can show that |
|
900 |
|
901 \begin{isabelle}\ \ \ \ \ %%% |
|
902 \begin{tabular}{@ {}l} |
|
903 @{thm eq_dep}\\ |
|
904 @{thm[mode=IfThen] eq_cp} |
|
905 \end{tabular} |
|
906 \end{isabelle} |
|
907 |
|
908 \noindent |
|
909 This means also we do not have to recalculate the @{text RAG} and |
|
910 not the current precedences for the other threads. Since @{term th} is not |
|
911 alive anymore in state @{term "s"}, there is no need to calculate its |
|
912 current precedence. |
|
913 \smallskip |
1051 *} |
914 *} |
1052 |
915 (*<*) |
1053 |
916 end |
|
917 context step_set_cps |
|
918 begin |
|
919 (*>*) |
|
920 text {* |
|
921 \noindent |
|
922 @{term "Set th prio"}: We assume that @{text s'} and |
|
923 @{term "s \<equiv> Set th prio#s'"} are both valid. We can show that |
|
924 |
|
925 \begin{isabelle}\ \ \ \ \ %%% |
|
926 \begin{tabular}{@ {}l} |
|
927 @{thm[mode=IfThen] eq_dep}\\ |
|
928 @{thm[mode=IfThen] eq_cp} |
|
929 \end{tabular} |
|
930 \end{isabelle} |
|
931 |
|
932 \noindent |
|
933 The first is again telling us we do not need to change the @{text RAG}. The second |
|
934 however states that only threads that are \emph{not} dependent on @{text th} have their |
|
935 current precedence unchanged. For the others we have to recalculate the current |
|
936 precedence. To do this we can start from @{term "th"} |
|
937 and follow the @{term "depend"}-chains to recompute the @{term "cp"} of every |
|
938 thread encountered on the way using Lemma~\ref{childrenlem}. Since the @{term "depend"} |
|
939 is loop free, this procedure always stop. The the following two lemmas show this |
|
940 procedure can actually stop often earlier. |
|
941 |
|
942 \begin{isabelle}\ \ \ \ \ %%% |
|
943 \begin{tabular}{@ {}l} |
|
944 @{thm[mode=IfThen] eq_up_self}\\ |
|
945 @{text "If"} @{thm (prem 1) eq_up}, @{thm (prem 2) eq_up} and @{thm (prem 3) eq_up}\\ |
|
946 @{text "then"} @{thm (concl) eq_up}. |
|
947 \end{tabular} |
|
948 \end{isabelle} |
|
949 |
|
950 \noindent |
|
951 The first states that if the current precedence of @{text th} is unchanged, |
|
952 then the procedure can stop immediately (all dependent threads have their @{term cp}-value unchanged). |
|
953 The second states that if an intermediate @{term cp}-value does not change, then |
|
954 the procedure can also stop, because none of its dependent threads will |
|
955 have their current precedence changed. |
|
956 \smallskip |
|
957 *} |
|
958 |
|
959 (*<*) |
|
960 end |
|
961 context step_v_cps_nt |
|
962 begin |
|
963 (*>*) |
|
964 text {* |
|
965 \noindent |
|
966 @{term "V th cs"}: We assume that @{text s'} and |
|
967 @{term "s \<equiv> V th cs#s'"} are both valid. We have to consider two |
|
968 subcases: one where there is a thread to ``take over'' the released |
|
969 resource @{text cs}, and where there is not. Let us consider them |
|
970 in turn. Suppose in state @{text s}, the thread @{text th'} takes over |
|
971 resource @{text cs} from thread @{text th}. We can show |
|
972 |
|
973 |
|
974 \begin{isabelle}\ \ \ \ \ %%% |
|
975 @{thm depend_s} |
|
976 \end{isabelle} |
|
977 |
|
978 \noindent |
|
979 which shows how the @{text RAG} needs to be changed. This also suggests |
|
980 how the current precedences need to be recalculated. For threads that are |
|
981 not @{text "th"} and @{text "th'"} nothing needs to be changed, since we |
|
982 can show |
|
983 |
|
984 \begin{isabelle}\ \ \ \ \ %%% |
|
985 @{thm[mode=IfThen] cp_kept} |
|
986 \end{isabelle} |
|
987 |
|
988 \noindent |
|
989 For @{text th} and @{text th'} we need to use Lemma~\ref{childrenlem} to |
|
990 recalculate their current prcedence since their children have changed. *}(*<*)end context step_v_cps_nnt begin (*>*)text {* |
|
991 \noindent |
|
992 In the other case where there is no thread that takes over @{text cs}, we can show how |
|
993 to recalculate the @{text RAG} and also show that no current precedence needs |
|
994 to be recalculated, except for @{text th} (like in the case above). |
|
995 |
|
996 \begin{isabelle}\ \ \ \ \ %%% |
|
997 \begin{tabular}{@ {}l} |
|
998 @{thm depend_s}\\ |
|
999 @{thm eq_cp} |
|
1000 \end{tabular} |
|
1001 \end{isabelle} |
|
1002 *} |
|
1003 (*<*) |
|
1004 end |
|
1005 context step_P_cps_e |
|
1006 begin |
|
1007 (*>*) |
|
1008 |
|
1009 text {* |
|
1010 \noindent |
|
1011 @{term "P th cs"}: We assume that @{text s'} and |
|
1012 @{term "s \<equiv> P th cs#s'"} are both valid. We again have to analyse two subcases, namely |
|
1013 the one where @{text cs} is locked, and where it is not. We treat the second case |
|
1014 first by showing that |
|
1015 |
|
1016 \begin{isabelle}\ \ \ \ \ %%% |
|
1017 \begin{tabular}{@ {}l} |
|
1018 @{thm depend_s}\\ |
|
1019 @{thm eq_cp} |
|
1020 \end{tabular} |
|
1021 \end{isabelle} |
|
1022 |
|
1023 \noindent |
|
1024 This means we do not need to add a holding edge to the @{text RAG} and no |
|
1025 current precedence must be recalculated (including that for @{text th}).*}(*<*)end context step_P_cps_ne begin(*>*) text {* |
|
1026 \noindent |
|
1027 In the second case we know that resouce @{text cs} is locked. We can show that |
|
1028 |
|
1029 \begin{isabelle}\ \ \ \ \ %%% |
|
1030 \begin{tabular}{@ {}l} |
|
1031 @{thm depend_s}\\ |
|
1032 @{thm[mode=IfThen] eq_cp} |
|
1033 \end{tabular} |
|
1034 \end{isabelle} |
|
1035 |
|
1036 \noindent |
|
1037 That means we have to add a waiting edge to the @{text RAG}. Furthermore |
|
1038 the current precedence for all threads that are not dependent on @{text th} |
|
1039 are unchanged. For the others we need to follow the @{term "depend"}-chains |
|
1040 in the @{text RAG} and recompute the @{term "cp"}. However, like in the |
|
1041 @{text Set}-event, this operation can stop often earlier, namely when intermediate |
|
1042 values do not change. |
|
1043 *} |
1054 (*<*) |
1044 (*<*) |
1055 end |
1045 end |
1056 (*>*) |
1046 (*>*) |
1057 |
1047 |
1058 subsection {* Event @{text "Exit th"} *} |
1048 text {* |
1059 |
1049 \noindent |
1060 (*<*) |
1050 TO DO a few sentences summarising what has been achieved. |
1061 context step_exit_cps |
|
1062 begin |
|
1063 (*>*) |
|
1064 |
|
1065 text {* |
|
1066 The context under which event @{text "Exit th"} happens is formalized as follows: |
|
1067 \begin{enumerate} |
|
1068 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
1069 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
1070 event @{text "Exit th"} is eligible to happen under state @{term "s'"} and |
|
1071 state @{term "s'"} is a valid state. |
|
1072 \end{enumerate} |
|
1073 The following results can be obtained under this context: |
|
1074 \begin{enumerate} |
|
1075 \item The RAG does not change (@{text "eq_dep"}): |
|
1076 @{thm [display] eq_dep} |
|
1077 \item All threads other than @{term "th"} do not need re-computation (@{text "eq_cp"}): |
|
1078 @{thm [display] eq_cp} |
|
1079 \end{enumerate} |
|
1080 Since @{term th} does not live in state @{term "s"}, there is no need to compute |
|
1081 its @{term cp}-value. |
|
1082 *} |
1051 *} |
1083 |
|
1084 (*<*) |
|
1085 end |
|
1086 (*>*) |
|
1087 |
1052 |
1088 section {* Conclusion *} |
1053 section {* Conclusion *} |
1089 |
1054 |
1090 text {* |
1055 text {* |
1091 The Priority Inheritance Protocol is a classic textbook algorithm |
1056 The Priority Inheritance Protocol is a classic textbook algorithm |
1351 |
1318 |
1352 (*<*) |
1319 (*<*) |
1353 end |
1320 end |
1354 (*>*) |
1321 (*>*) |
1355 |
1322 |
1356 section {* Properties to guide implementation \label{implement} *} |
|
1357 |
|
1358 text {* |
|
1359 The properties (especially @{text "runing_inversion_2"}) convinced us that the model defined |
|
1360 in Section \ref{model} does prevent indefinite priority inversion and therefore fulfills |
|
1361 the fundamental requirement of Priority Inheritance protocol. Another purpose of this paper |
|
1362 is to show how this model can be used to guide a concrete implementation. As discussed in |
|
1363 Section 5.6.5 of \cite{Vahalia96}, the implementation of Priority Inheritance in Solaris |
|
1364 uses sophisticated linking data structure. Except discussing two scenarios to show how |
|
1365 the data structure should be manipulated, a lot of details of the implementation are missing. |
|
1366 In \cite{Faria08,Jahier09,Wellings07} the protocol is described formally |
|
1367 using different notations, but little information is given on how this protocol can be |
|
1368 implemented efficiently, especially there is no information on how these data structure |
|
1369 should be manipulated. |
|
1370 |
|
1371 Because the scheduling of threads is based on current precedence, |
|
1372 the central issue in implementation of Priority Inheritance is how to compute the precedence |
|
1373 correctly and efficiently. As long as the precedence is correct, it is very easy to |
|
1374 modify the scheduling algorithm to select the correct thread to execute. |
|
1375 |
|
1376 First, it can be proved that the computation of current precedence @{term "cp"} of a threads |
|
1377 only involves its children (@{text "cp_rec"}): |
|
1378 @{thm [display] cp_rec} |
|
1379 where @{term "children s th"} represents the set of children of @{term "th"} in the current |
|
1380 RAG: |
|
1381 \[ |
|
1382 @{thm (lhs) children_def} @{text "\<equiv>"} @{thm (rhs) children_def} |
|
1383 \] |
|
1384 where the definition of @{term "child"} is: |
|
1385 \[ @{thm (lhs) child_def} @{text "\<equiv>"} @{thm (rhs) child_def} |
|
1386 \] |
|
1387 |
|
1388 The aim of this section is to fill the missing details of how current precedence should |
|
1389 be changed with the happening of events, with each event type treated by one subsection, |
|
1390 where the computation of @{term "cp"} uses lemma @{text "cp_rec"}. |
|
1391 *} |
|
1392 |
|
1393 subsection {* Event @{text "Set th prio"} *} |
|
1394 |
|
1395 (*<*) |
|
1396 context step_set_cps |
|
1397 begin |
|
1398 (*>*) |
|
1399 |
|
1400 text {* |
|
1401 The context under which event @{text "Set th prio"} happens is formalized as follows: |
|
1402 \begin{enumerate} |
|
1403 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
1404 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
1405 event @{text "Set th prio"} is eligible to happen under state @{term "s'"} and |
|
1406 state @{term "s'"} is a valid state. |
|
1407 \end{enumerate} |
|
1408 *} |
|
1409 |
|
1410 text {* \noindent |
|
1411 Under such a context, we investigated how the current precedence @{term "cp"} of |
|
1412 threads change from state @{term "s'"} to @{term "s"} and obtained the following |
|
1413 conclusions: |
|
1414 \begin{enumerate} |
|
1415 %% \item The RAG does not change (@{text "eq_dep"}): @{thm "eq_dep"}. |
|
1416 \item All threads with no dependence relation with thread @{term "th"} have their |
|
1417 @{term "cp"}-value unchanged (@{text "eq_cp"}): |
|
1418 @{thm [display] eq_cp} |
|
1419 This lemma implies the @{term "cp"}-value of @{term "th"} |
|
1420 and those threads which have a dependence relation with @{term "th"} might need |
|
1421 to be recomputed. The way to do this is to start from @{term "th"} |
|
1422 and follow the @{term "depend"}-chain to recompute the @{term "cp"}-value of every |
|
1423 encountered thread using lemma @{text "cp_rec"}. |
|
1424 Since the @{term "depend"}-relation is loop free, this procedure |
|
1425 can always stop. The the following lemma shows this procedure actually could stop earlier. |
|
1426 \item The following two lemma shows, if a thread the re-computation of which |
|
1427 gives an unchanged @{term "cp"}-value, the procedure described above can stop. |
|
1428 \begin{enumerate} |
|
1429 \item Lemma @{text "eq_up_self"} shows if the re-computation of |
|
1430 @{term "th"}'s @{term "cp"} gives the same result, the procedure can stop: |
|
1431 @{thm [display] eq_up_self} |
|
1432 \item Lemma @{text "eq_up"}) shows if the re-computation at intermediate threads |
|
1433 gives unchanged result, the procedure can stop: |
|
1434 @{thm [display] eq_up} |
|
1435 \end{enumerate} |
|
1436 \end{enumerate} |
|
1437 *} |
|
1438 |
|
1439 (*<*) |
|
1440 end |
|
1441 (*>*) |
|
1442 |
|
1443 subsection {* Event @{text "V th cs"} *} |
|
1444 |
|
1445 (*<*) |
|
1446 context step_v_cps_nt |
|
1447 begin |
|
1448 (*>*) |
|
1449 |
|
1450 text {* |
|
1451 The context under which event @{text "V th cs"} happens is formalized as follows: |
|
1452 \begin{enumerate} |
|
1453 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
1454 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
1455 event @{text "V th cs"} is eligible to happen under state @{term "s'"} and |
|
1456 state @{term "s'"} is a valid state. |
|
1457 \end{enumerate} |
|
1458 *} |
|
1459 |
|
1460 text {* \noindent |
|
1461 Under such a context, we investigated how the current precedence @{term "cp"} of |
|
1462 threads change from state @{term "s'"} to @{term "s"}. |
|
1463 |
|
1464 |
|
1465 Two subcases are considerted, |
|
1466 where the first is that there exits @{term "th'"} |
|
1467 such that |
|
1468 @{thm [display] nt} |
|
1469 holds, which means there exists a thread @{term "th'"} to take over |
|
1470 the resource release by thread @{term "th"}. |
|
1471 In this sub-case, the following results are obtained: |
|
1472 \begin{enumerate} |
|
1473 \item The change of RAG is given by lemma @{text "depend_s"}: |
|
1474 @{thm [display] "depend_s"} |
|
1475 which shows two edges are removed while one is added. These changes imply how |
|
1476 the current precedences should be re-computed. |
|
1477 \item First all threads different from @{term "th"} and @{term "th'"} have their |
|
1478 @{term "cp"}-value kept, therefore do not need a re-computation |
|
1479 (@{text "cp_kept"}): @{thm [display] cp_kept} |
|
1480 This lemma also implies, only the @{term "cp"}-values of @{term "th"} and @{term "th'"} |
|
1481 need to be recomputed. |
|
1482 \end{enumerate} |
|
1483 *} |
|
1484 |
|
1485 (*<*) |
|
1486 end |
|
1487 |
|
1488 context step_v_cps_nnt |
|
1489 begin |
|
1490 (*>*) |
|
1491 |
|
1492 text {* |
|
1493 The other sub-case is when for all @{text "th'"} |
|
1494 @{thm [display] nnt} |
|
1495 holds, no such thread exists. The following results can be obtained for this |
|
1496 sub-case: |
|
1497 \begin{enumerate} |
|
1498 \item The change of RAG is given by lemma @{text "depend_s"}: |
|
1499 @{thm [display] depend_s} |
|
1500 which means only one edge is removed. |
|
1501 \item In this case, no re-computation is needed (@{text "eq_cp"}): |
|
1502 @{thm [display] eq_cp} |
|
1503 \end{enumerate} |
|
1504 *} |
|
1505 |
|
1506 (*<*) |
|
1507 end |
|
1508 (*>*) |
|
1509 |
|
1510 |
|
1511 subsection {* Event @{text "P th cs"} *} |
|
1512 |
|
1513 (*<*) |
|
1514 context step_P_cps_e |
|
1515 begin |
|
1516 (*>*) |
|
1517 |
|
1518 text {* |
|
1519 The context under which event @{text "P th cs"} happens is formalized as follows: |
|
1520 \begin{enumerate} |
|
1521 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
1522 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
1523 event @{text "P th cs"} is eligible to happen under state @{term "s'"} and |
|
1524 state @{term "s'"} is a valid state. |
|
1525 \end{enumerate} |
|
1526 |
|
1527 This case is further divided into two sub-cases. The first is when @{thm ee} holds. |
|
1528 The following results can be obtained: |
|
1529 \begin{enumerate} |
|
1530 \item One edge is added to the RAG (@{text "depend_s"}): |
|
1531 @{thm [display] depend_s} |
|
1532 \item No re-computation is needed (@{text "eq_cp"}): |
|
1533 @{thm [display] eq_cp} |
|
1534 \end{enumerate} |
|
1535 *} |
|
1536 |
|
1537 (*<*) |
|
1538 end |
|
1539 |
|
1540 context step_P_cps_ne |
|
1541 begin |
|
1542 (*>*) |
|
1543 |
|
1544 text {* |
|
1545 The second is when @{thm ne} holds. |
|
1546 The following results can be obtained: |
|
1547 \begin{enumerate} |
|
1548 \item One edge is added to the RAG (@{text "depend_s"}): |
|
1549 @{thm [display] depend_s} |
|
1550 \item Threads with no dependence relation with @{term "th"} do not need a re-computation |
|
1551 of their @{term "cp"}-values (@{text "eq_cp"}): |
|
1552 @{thm [display] eq_cp} |
|
1553 This lemma implies all threads with a dependence relation with @{term "th"} may need |
|
1554 re-computation. |
|
1555 \item Similar to the case of @{term "Set"}, the computation procedure could stop earlier |
|
1556 (@{text "eq_up"}): |
|
1557 @{thm [display] eq_up} |
|
1558 \end{enumerate} |
|
1559 |
|
1560 *} |
|
1561 |
|
1562 (*<*) |
|
1563 end |
|
1564 (*>*) |
|
1565 |
|
1566 subsection {* Event @{text "Create th prio"} *} |
|
1567 |
|
1568 (*<*) |
|
1569 context step_create_cps |
|
1570 begin |
|
1571 (*>*) |
|
1572 |
|
1573 text {* |
|
1574 The context under which event @{text "Create th prio"} happens is formalized as follows: |
|
1575 \begin{enumerate} |
|
1576 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
1577 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
1578 event @{text "Create th prio"} is eligible to happen under state @{term "s'"} and |
|
1579 state @{term "s'"} is a valid state. |
|
1580 \end{enumerate} |
|
1581 The following results can be obtained under this context: |
|
1582 \begin{enumerate} |
|
1583 \item The RAG does not change (@{text "eq_dep"}): |
|
1584 @{thm [display] eq_dep} |
|
1585 \item All threads other than @{term "th"} do not need re-computation (@{text "eq_cp"}): |
|
1586 @{thm [display] eq_cp} |
|
1587 \item The @{term "cp"}-value of @{term "th"} equals its precedence |
|
1588 (@{text "eq_cp_th"}): |
|
1589 @{thm [display] eq_cp_th} |
|
1590 \end{enumerate} |
|
1591 |
|
1592 *} |
|
1593 |
|
1594 |
|
1595 (*<*) |
|
1596 end |
|
1597 (*>*) |
|
1598 |
|
1599 subsection {* Event @{text "Exit th"} *} |
|
1600 |
|
1601 (*<*) |
|
1602 context step_exit_cps |
|
1603 begin |
|
1604 (*>*) |
|
1605 |
|
1606 text {* |
|
1607 The context under which event @{text "Exit th"} happens is formalized as follows: |
|
1608 \begin{enumerate} |
|
1609 \item The formation of @{term "s"} (@{text "s_def"}): @{thm s_def}. |
|
1610 \item State @{term "s"} is a valid state (@{text "vt_s"}): @{thm vt_s}. This implies |
|
1611 event @{text "Exit th"} is eligible to happen under state @{term "s'"} and |
|
1612 state @{term "s'"} is a valid state. |
|
1613 \end{enumerate} |
|
1614 The following results can be obtained under this context: |
|
1615 \begin{enumerate} |
|
1616 \item The RAG does not change (@{text "eq_dep"}): |
|
1617 @{thm [display] eq_dep} |
|
1618 \item All threads other than @{term "th"} do not need re-computation (@{text "eq_cp"}): |
|
1619 @{thm [display] eq_cp} |
|
1620 \end{enumerate} |
|
1621 Since @{term th} does not live in state @{term "s"}, there is no need to compute |
|
1622 its @{term cp}-value. |
|
1623 *} |
|
1624 |
|
1625 (*<*) |
|
1626 end |
|
1627 (*>*) |
|
1628 |
|
1629 |
1323 |
1630 section {* Related works \label{related} *} |
1324 section {* Related works \label{related} *} |
1631 |
1325 |
1632 text {* |
1326 text {* |
1633 \begin{enumerate} |
1327 \begin{enumerate} |