895 attractive (especially in light of the flawed proof by Sha et |
895 attractive (especially in light of the flawed proof by Sha et |
896 al.~\cite{Sha90}), we found that the formalisation can even help us |
896 al.~\cite{Sha90}), we found that the formalisation can even help us |
897 with efficiently implementing PIP. |
897 with efficiently implementing PIP. |
898 |
898 |
899 For example Baker complained that calculating the current precedence |
899 For example Baker complained that calculating the current precedence |
900 in PIP is quite ``heavy weight'' in Linux (see our Introduction). |
900 in PIP is quite ``heavy weight'' in Linux (see the Introduction). |
901 In our model of PIP the current precedence of a thread in a state s |
901 In our model of PIP the current precedence of a thread in a state s |
902 depends on all its dependants---a ``global'' transitive notion, |
902 depends on all its dependants---a ``global'' transitive notion, |
903 which is indeed heavy weight (see Def.~shown in \eqref{cpreced}). |
903 which is indeed heavy weight (see Def.~shown in \eqref{cpreced}). |
904 We can however prove how to improve upon this. For this let us |
904 We can however improve upon this. For this let us define the notion |
905 define the notion of @{term children} of a thread as |
905 of @{term children} of a thread @{text th} in a state @{text s} as |
906 |
906 |
907 \begin{isabelle}\ \ \ \ \ %%% |
907 \begin{isabelle}\ \ \ \ \ %%% |
908 \begin{tabular}{@ {}l} |
908 \begin{tabular}{@ {}l} |
909 @{thm children_def2} |
909 @{thm children_def2} |
910 \end{tabular} |
910 \end{tabular} |
911 \end{isabelle} |
911 \end{isabelle} |
912 |
912 |
913 \noindent |
913 \noindent |
914 where a child is a thread that is one ``hop'' away in the @{term RAG} from the |
914 where a child is a thread that is one ``hop'' away from the tread |
915 tread @{text th} (and waiting for @{text th} to release a resource). We can prove that |
915 @{text th} in the @{term RAG} (and waiting for @{text th} to release |
|
916 a resource). We can prove that |
916 |
917 |
917 \begin{lemma}\label{childrenlem} |
918 \begin{lemma}\label{childrenlem} |
918 @{text "If"} @{thm (prem 1) cp_rec} @{text "then"} |
919 @{text "If"} @{thm (prem 1) cp_rec} @{text "then"} |
919 \begin{center} |
920 \begin{center} |
920 @{thm (concl) cp_rec}. |
921 @{thm (concl) cp_rec}. |
923 |
924 |
924 \noindent |
925 \noindent |
925 That means the current precedence of a thread @{text th} can be |
926 That means the current precedence of a thread @{text th} can be |
926 computed locally by considering only the children of @{text th}. In |
927 computed locally by considering only the children of @{text th}. In |
927 effect, it only needs to be recomputed for @{text th} when one of |
928 effect, it only needs to be recomputed for @{text th} when one of |
928 its children change their current precedence. Once the current |
929 its children changes its current precedence. Once the current |
929 precedence is computed in this more efficient manner, the selection |
930 precedence is computed in this more efficient manner, the selection |
930 of the thread with highest precedence from a set of ready threads is |
931 of the thread with highest precedence from a set of ready threads is |
931 a standard scheduling operation implemented in most operating |
932 a standard scheduling operation implemented in most operating |
932 systems. |
933 systems. |
933 |
934 |
934 Of course the main implementation work for PIP involves the scheduler |
935 Of course the main implementation work for PIP involves the |
935 and coding how it should react to the events, for example which |
936 scheduler and coding how it should react to events. Below we |
936 datastructures need to be modified (mainly @{text RAG} and @{text cprec}). |
937 outline how our formalisation guides this implementation for each |
937 Below we outline how our formalisation guides this implementation for each |
938 kind of event.\smallskip |
938 event.\smallskip |
|
939 *} |
939 *} |
940 |
940 |
941 (*<*) |
941 (*<*) |
942 context step_create_cps |
942 context step_create_cps |
943 begin |
943 begin |
944 (*>*) |
944 (*>*) |
945 text {* |
945 text {* |
946 \noindent |
946 \noindent |
947 @{term "Create th prio"}: We assume that the current state @{text s'} and |
947 \colorbox{mygrey}{@{term "Create th prio"}:} We assume that the current state @{text s'} and |
948 the next state @{term "s \<equiv> Create th prio#s'"} are both valid (meaning the event |
948 the next state @{term "s \<equiv> Create th prio#s'"} are both valid (meaning the event |
949 is allowed to occur). In this situation we can show that |
949 is allowed to occur). In this situation we can show that |
950 |
950 |
951 \begin{isabelle}\ \ \ \ \ %%% |
951 \begin{isabelle}\ \ \ \ \ %%% |
952 \begin{tabular}{@ {}l} |
952 \begin{tabular}{@ {}l} |
953 @{thm eq_dep}\\ |
953 @{thm eq_dep},\\ |
954 @{thm eq_cp_th}\\ |
954 @{thm eq_cp_th}, and\\ |
955 @{thm[mode=IfThen] eq_cp} |
955 @{thm[mode=IfThen] eq_cp} |
956 \end{tabular} |
956 \end{tabular} |
957 \end{isabelle} |
957 \end{isabelle} |
958 |
958 |
959 \noindent |
959 \noindent |
960 This means we do not have recalculate the @{text RAG} and also none of the |
960 This means we do not have recalculate the @{text RAG} and also none of the |
961 current precedences of the other threads. The current precedence of the created |
961 current precedences of the other threads. The current precedence of the created |
962 thread is just its precedence, that is the pair @{term "(prio, length (s::event list))"}. |
962 thread @{text th} is just its precedence, namely the pair @{term "(prio, length (s::event list))"}. |
963 \smallskip |
963 \smallskip |
964 *} |
964 *} |
965 (*<*) |
965 (*<*) |
966 end |
966 end |
967 context step_exit_cps |
967 context step_exit_cps |
968 begin |
968 begin |
969 (*>*) |
969 (*>*) |
970 text {* |
970 text {* |
971 \noindent |
971 \noindent |
972 @{term "Exit th"}: We again assume that the current state @{text s'} and |
972 \colorbox{mygrey}{@{term "Exit th"}:} We again assume that the current state @{text s'} and |
973 the next state @{term "s \<equiv> Exit th#s'"} are both valid. We can show that |
973 the next state @{term "s \<equiv> Exit th#s'"} are both valid. We can show that |
974 |
974 |
975 \begin{isabelle}\ \ \ \ \ %%% |
975 \begin{isabelle}\ \ \ \ \ %%% |
976 \begin{tabular}{@ {}l} |
976 \begin{tabular}{@ {}l} |
977 @{thm eq_dep}\\ |
977 @{thm eq_dep}, and\\ |
978 @{thm[mode=IfThen] eq_cp} |
978 @{thm[mode=IfThen] eq_cp} |
979 \end{tabular} |
979 \end{tabular} |
980 \end{isabelle} |
980 \end{isabelle} |
981 |
981 |
982 \noindent |
982 \noindent |
983 This means also we do not have to recalculate the @{text RAG} and |
983 This means again we do not have to recalculate the @{text RAG} and |
984 not the current precedences for the other threads. Since @{term th} is not |
984 also not the current precedences for the other threads. Since @{term th} is not |
985 alive anymore in state @{term "s"}, there is no need to calculate its |
985 alive anymore in state @{term "s"}, there is no need to calculate its |
986 current precedence. |
986 current precedence. |
987 \smallskip |
987 \smallskip |
988 *} |
988 *} |
989 (*<*) |
989 (*<*) |
991 context step_set_cps |
991 context step_set_cps |
992 begin |
992 begin |
993 (*>*) |
993 (*>*) |
994 text {* |
994 text {* |
995 \noindent |
995 \noindent |
996 @{term "Set th prio"}: We assume that @{text s'} and |
996 \colorbox{mygrey}{@{term "Set th prio"}:} We assume that @{text s'} and |
997 @{term "s \<equiv> Set th prio#s'"} are both valid. We can show that |
997 @{term "s \<equiv> Set th prio#s'"} are both valid. We can show that |
998 |
998 |
999 \begin{isabelle}\ \ \ \ \ %%% |
999 \begin{isabelle}\ \ \ \ \ %%% |
1000 \begin{tabular}{@ {}l} |
1000 \begin{tabular}{@ {}l} |
1001 @{thm[mode=IfThen] eq_dep}\\ |
1001 @{thm[mode=IfThen] eq_dep}, and\\ |
1002 @{thm[mode=IfThen] eq_cp} |
1002 @{thm[mode=IfThen] eq_cp} |
1003 \end{tabular} |
1003 \end{tabular} |
1004 \end{isabelle} |
1004 \end{isabelle} |
1005 |
1005 |
1006 \noindent |
1006 \noindent |
1007 The first is again telling us we do not need to change the @{text RAG}. The second |
1007 The first property is again telling us we do not need to change the @{text RAG}. The second |
1008 however states that only threads that are \emph{not} dependent on @{text th} have their |
1008 however states that only threads that are \emph{not} dependants of @{text th} have their |
1009 current precedence unchanged. For the others we have to recalculate the current |
1009 current precedence unchanged. For the others we have to recalculate the current |
1010 precedence. To do this we can start from @{term "th"} |
1010 precedence. To do this we can start from @{term "th"} |
1011 and follow the @{term "depend"}-chains to recompute the @{term "cp"} of every |
1011 and follow the @{term "depend"}-chains to recompute the @{term "cp"} of every |
1012 thread encountered on the way using Lemma~\ref{childrenlem}. Since the @{term "depend"} |
1012 thread encountered on the way using Lemma~\ref{childrenlem}. Since the @{term "depend"} |
1013 is loop free, this procedure always stop. The the following two lemmas show this |
1013 is loop free, this procedure will always stop. The following two lemmas show, however, |
1014 procedure can actually stop often earlier. |
1014 that this procedure can actually stop often earlier without having to consider all |
|
1015 dependants. |
1015 |
1016 |
1016 \begin{isabelle}\ \ \ \ \ %%% |
1017 \begin{isabelle}\ \ \ \ \ %%% |
1017 \begin{tabular}{@ {}l} |
1018 \begin{tabular}{@ {}l} |
1018 @{thm[mode=IfThen] eq_up_self}\\ |
1019 @{thm[mode=IfThen] eq_up_self}\\ |
1019 @{text "If"} @{thm (prem 1) eq_up}, @{thm (prem 2) eq_up} and @{thm (prem 3) eq_up}\\ |
1020 @{text "If"} @{thm (prem 1) eq_up}, @{thm (prem 2) eq_up} and @{thm (prem 3) eq_up}\\ |
1027 The second states that if an intermediate @{term cp}-value does not change, then |
1028 The second states that if an intermediate @{term cp}-value does not change, then |
1028 the procedure can also stop, because none of its dependent threads will |
1029 the procedure can also stop, because none of its dependent threads will |
1029 have their current precedence changed. |
1030 have their current precedence changed. |
1030 \smallskip |
1031 \smallskip |
1031 *} |
1032 *} |
1032 |
|
1033 (*<*) |
1033 (*<*) |
1034 end |
1034 end |
1035 context step_v_cps_nt |
1035 context step_v_cps_nt |
1036 begin |
1036 begin |
1037 (*>*) |
1037 (*>*) |
1038 text {* |
1038 text {* |
1039 \noindent |
1039 \noindent |
1040 @{term "V th cs"}: We assume that @{text s'} and |
1040 \colorbox{mygrey}{@{term "V th cs"}:} We assume that @{text s'} and |
1041 @{term "s \<equiv> V th cs#s'"} are both valid. We have to consider two |
1041 @{term "s \<equiv> V th cs#s'"} are both valid. We have to consider two |
1042 subcases: one where there is a thread to ``take over'' the released |
1042 subcases: one where there is a thread to ``take over'' the released |
1043 resource @{text cs}, and where there is not. Let us consider them |
1043 resource @{text cs}, and one where there is not. Let us consider them |
1044 in turn. Suppose in state @{text s}, the thread @{text th'} takes over |
1044 in turn. Suppose in state @{text s}, the thread @{text th'} takes over |
1045 resource @{text cs} from thread @{text th}. We can show |
1045 resource @{text cs} from thread @{text th}. We can show |
1046 |
1046 |
1047 |
1047 |
1048 \begin{isabelle}\ \ \ \ \ %%% |
1048 \begin{isabelle}\ \ \ \ \ %%% |
1063 For @{text th} and @{text th'} we need to use Lemma~\ref{childrenlem} to |
1063 For @{text th} and @{text th'} we need to use Lemma~\ref{childrenlem} to |
1064 recalculate their current prcedence since their children have changed. *}(*<*)end context step_v_cps_nnt begin (*>*)text {* |
1064 recalculate their current prcedence since their children have changed. *}(*<*)end context step_v_cps_nnt begin (*>*)text {* |
1065 \noindent |
1065 \noindent |
1066 In the other case where there is no thread that takes over @{text cs}, we can show how |
1066 In the other case where there is no thread that takes over @{text cs}, we can show how |
1067 to recalculate the @{text RAG} and also show that no current precedence needs |
1067 to recalculate the @{text RAG} and also show that no current precedence needs |
1068 to be recalculated, except for @{text th} (like in the case above). |
1068 to be recalculated. |
1069 |
1069 |
1070 \begin{isabelle}\ \ \ \ \ %%% |
1070 \begin{isabelle}\ \ \ \ \ %%% |
1071 \begin{tabular}{@ {}l} |
1071 \begin{tabular}{@ {}l} |
1072 @{thm depend_s}\\ |
1072 @{thm depend_s}\\ |
1073 @{thm eq_cp} |
1073 @{thm eq_cp} |
1107 \end{tabular} |
1107 \end{tabular} |
1108 \end{isabelle} |
1108 \end{isabelle} |
1109 |
1109 |
1110 \noindent |
1110 \noindent |
1111 That means we have to add a waiting edge to the @{text RAG}. Furthermore |
1111 That means we have to add a waiting edge to the @{text RAG}. Furthermore |
1112 the current precedence for all threads that are not dependent on @{text th} |
1112 the current precedence for all threads that are not dependants of @{text th} |
1113 are unchanged. For the others we need to follow the @{term "depend"}-chains |
1113 are unchanged. For the others we need to follow the edges |
1114 in the @{text RAG} and recompute the @{term "cp"}. However, like in the |
1114 in the @{text RAG} and recompute the @{term "cp"}. However, like in the |
1115 @{text Set}-event, this operation can stop often earlier, namely when intermediate |
1115 @case of {text Set}, this operation can stop often earlier, namely when intermediate |
1116 values do not change. |
1116 values do not change. |
1117 *} |
1117 *} |
1118 (*<*) |
1118 (*<*) |
1119 end |
1119 end |
1120 (*>*) |
1120 (*>*) |
1121 |
|
1122 text {* |
1121 text {* |
1123 \noindent |
1122 \noindent |
1124 TO DO a few sentences summarising what has been achieved. |
1123 A pleasing result of our formalisation is that the properties in |
|
1124 this section closely inform an implementation of PIP: Whether the |
|
1125 @{text RAG} needs to be reconfigured or current precedences need to |
|
1126 recalculated for an event is given by a lemma we proved. |
1125 *} |
1127 *} |
1126 |
1128 |
1127 section {* Conclusion *} |
1129 section {* Conclusion *} |
1128 |
1130 |
1129 text {* |
1131 text {* |
1139 that a mechanically checked proof avoids the flaws that crept into their |
1141 that a mechanically checked proof avoids the flaws that crept into their |
1140 informal reasoning. We achieved this goal: The correctness of PIP now |
1142 informal reasoning. We achieved this goal: The correctness of PIP now |
1141 only hinges on the assumptions behind our formal model. The reasoning, which is |
1143 only hinges on the assumptions behind our formal model. The reasoning, which is |
1142 sometimes quite intricate and tedious, has been checked beyond any |
1144 sometimes quite intricate and tedious, has been checked beyond any |
1143 reasonable doubt by Isabelle/HOL. We can also confirm that Paulson's |
1145 reasonable doubt by Isabelle/HOL. We can also confirm that Paulson's |
1144 inductive method to protocol verification~\cite{Paulson98} is quite |
1146 inductive method for protocol verification~\cite{Paulson98} is quite |
1145 suitable for our formal model and proof. The traditional application |
1147 suitable for our formal model and proof. The traditional application |
1146 area of this method is security protocols. The only other |
1148 area of this method is security protocols. The only other |
1147 application of Paulson's method we know of outside this area is |
1149 application of Paulson's method we know of outside this area is |
1148 \cite{Wang09}. |
1150 \cite{Wang09}. |
1149 |
1151 |
1167 |
1169 |
1168 PIP is a scheduling algorithm for single-processor systems. We are |
1170 PIP is a scheduling algorithm for single-processor systems. We are |
1169 now living in a multi-processor world. So the question naturally |
1171 now living in a multi-processor world. So the question naturally |
1170 arises whether PIP has any relevance in such a world beyond |
1172 arises whether PIP has any relevance in such a world beyond |
1171 teaching. Priority Inversion certainly occurs also in |
1173 teaching. Priority Inversion certainly occurs also in |
1172 multi-processor systems. However, the surprising answer, according to |
1174 multi-processor systems. However, the surprising answer, according |
1173 \cite{Steinberg10}, is that except for one unsatisfactory proposal |
1175 to \cite{Steinberg10}, is that except for one unsatisfactory |
1174 nobody has a good idea for how PIP should be modified to work |
1176 proposal nobody has a good idea for how PIP should be modified to |
1175 correctly on multi-processor systems. The difficulties become clear |
1177 work correctly on multi-processor systems. The difficulties become |
1176 when considering that locking and releasing a resource always |
1178 clear when considering that locking and releasing a resource always |
1177 requires a some small amount of time. If processes work independently, then a |
1179 requires a small amount of time. If processes work independently, |
1178 low priority process can ``steal'' in this unguarded moment a lock for a |
1180 then a low priority process can ``steal'' in such an unguarded |
1179 resource that was supposed allow a high-priority process to run next. Thus |
1181 moment a lock for a resource that was supposed allow a high-priority |
1180 the problem of Priority Inversion is not really prevented. It seems |
1182 process to run next. Thus the problem of Priority Inversion is not |
1181 difficult to design a PIP-algorithm with a meaningful correctness |
1183 really prevented. It seems difficult to design a PIP-algorithm with |
1182 property on independent multi-processor systems. We can imagine PIP |
1184 a meaningful correctness property on a multi-processor systems where |
1183 to be of use in a situation where |
1185 processes work independently. We can imagine PIP to be of use in |
1184 processes are not independent, but coordinated via a master |
1186 situations where processes are \emph{not} independent, but |
1185 process that distributes work over some slave processes. However a |
1187 coordinated via a master process that distributes work over some |
1186 formal investigation of this is beyond the scope of this paper. |
1188 slave processes. However, a formal investigation of this is beyond |
1187 We are not aware of any proofs in this area, not even informal ones. |
1189 the scope of this paper. We are not aware of any proofs in this |
1188 |
1190 area, not even informal ones. |
1189 Our formalisation consists of 6894 of readable Isabelle/Isar code, with some |
1191 |
1190 apply-scripts interspersed. The formal model is 385 lines long; the |
1192 The most closely related work to ours is the formal verification in |
1191 formal correctness proof 3777 lines. The properties relevant for an |
1193 PVS for Priority Ceiling done by Dutertre \cite{dutertre99b}. His formalisation |
1192 implementation are 1964 lines long; Auxlliary definitions and notions are |
1194 consists of 407 lemmas and 2500 lines of ``specification'' (we do not |
1193 768 lines. |
1195 know whether this includes also code for proofs). Our formalisation |
1194 |
1196 consists of around 210 lemmas and overall 6950 lines of readable Isabelle/Isar |
1195 |
1197 code with a few apply-scripts interspersed. The formal model of PIP |
|
1198 is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary |
|
1199 definitions and proofs took 770 lines of code. The properties relevant |
|
1200 for an implementation took 2000 lines. Our code can be downloaded from |
|
1201 ... |
|
1202 |
|
1203 \bibliographystyle{plain} |
|
1204 \bibliography{root} |
1196 *} |
1205 *} |
1197 |
1206 |
1198 section {* Key properties \label{extension} *} |
1207 section {* Key properties \label{extension} *} |
1199 |
1208 |
1200 (*<*) |
1209 (*<*) |
1309 then. |
1318 then. |
1310 *} |
1319 *} |
1311 |
1320 |
1312 (*<*) |
1321 (*<*) |
1313 end |
1322 end |
1314 (*>*) |
1323 |
1315 |
|
1316 |
|
1317 section {* Related works \label{related} *} |
|
1318 |
|
1319 text {* |
|
1320 \begin{enumerate} |
|
1321 \item {\em Integrating Priority Inheritance Algorithms in the Real-Time Specification for Java} |
|
1322 \cite{Wellings07} models and verifies the combination of Priority Inheritance (PI) and |
|
1323 Priority Ceiling Emulation (PCE) protocols in the setting of Java virtual machine |
|
1324 using extended Timed Automata(TA) formalism of the UPPAAL tool. Although a detailed |
|
1325 formal model of combined PI and PCE is given, the number of properties is quite |
|
1326 small and the focus is put on the harmonious working of PI and PCE. Most key features of PI |
|
1327 (as well as PCE) are not shown. Because of the limitation of the model checking technique |
|
1328 used there, properties are shown only for a small number of scenarios. Therefore, |
|
1329 the verification does not show the correctness of the formal model itself in a |
|
1330 convincing way. |
|
1331 \item {\em Formal Development of Solutions for Real-Time Operating Systems with TLA+/TLC} |
|
1332 \cite{Faria08}. A formal model of PI is given in TLA+. Only 3 properties are shown |
|
1333 for PI using model checking. The limitation of model checking is intrinsic to the work. |
|
1334 \item {\em Synchronous modeling and validation of priority inheritance schedulers} |
|
1335 \cite{Jahier09}. Gives a formal model |
|
1336 of PI and PCE in AADL (Architecture Analysis \& Design Language) and checked |
|
1337 several properties using model checking. The number of properties shown there is |
|
1338 less than here and the scale is also limited by the model checking technique. |
|
1339 \item {\em The Priority Ceiling Protocol: Formalization and Analysis Using PVS} |
|
1340 \cite{dutertre99b}. Formalized another protocol for Priority Inversion in the |
|
1341 interactive theorem proving system PVS. |
|
1342 \end{enumerate} |
|
1343 |
|
1344 |
|
1345 There are several works on inversion avoidance: |
|
1346 \begin{enumerate} |
|
1347 \item {\em Solving the group priority inversion problem in a timed asynchronous system} |
|
1348 \cite{Wang:2002:SGP}. The notion of Group Priority Inversion is introduced. The main |
|
1349 strategy is still inversion avoidance. The method is by reordering requests |
|
1350 in the setting of Client-Server. |
|
1351 \item {\em A Formalization of Priority Inversion} \cite{journals/rts/BabaogluMS93}. |
|
1352 Formalized the notion of Priority |
|
1353 Inversion and proposes methods to avoid it. |
|
1354 \end{enumerate} |
|
1355 |
|
1356 {\em Examples of inaccurate specification of the protocol ???}. |
|
1357 |
|
1358 *} |
|
1359 |
|
1360 |
|
1361 (*<*) |
|
1362 end |
1324 end |
1363 (*>*) |
1325 (*>*) |