111 |
111 |
112 In our opinion, there is clearly a need for investigating correct |
112 In our opinion, there is clearly a need for investigating correct |
113 algorithms for PIP. A few specifications for PIP exist (in English) |
113 algorithms for PIP. A few specifications for PIP exist (in English) |
114 and also a few high-level descriptions of implementations (e.g.~in |
114 and also a few high-level descriptions of implementations (e.g.~in |
115 the textbook \cite[Section 5.6.5]{Vahalia96}), but they help little |
115 the textbook \cite[Section 5.6.5]{Vahalia96}), but they help little |
116 with actual implementations. That this is a problem in practise is |
116 with actual implementations. That this is a problem in practice is |
117 proved by an email from Baker, who wrote on 13 July 2009 on the Linux |
117 proved by an email from Baker, who wrote on 13 July 2009 on the Linux |
118 Kernel mailing list: |
118 Kernel mailing list: |
119 |
119 |
120 \begin{quote} |
120 \begin{quote} |
121 \it{}``I observed in the kernel code (to my disgust), the Linux PIP |
121 \it{}``I observed in the kernel code (to my disgust), the Linux PIP |
352 release a resource. This means we need to include threads that transitively |
352 release a resource. This means we need to include threads that transitively |
353 wait for a resource being released (in the picture above this means the dependants |
353 wait for a resource being released (in the picture above this means the dependants |
354 of @{text "th\<^isub>0"} are @{text "th\<^isub>1"} and @{text "th\<^isub>2"}, which wait for resource @{text "cs\<^isub>1"}, |
354 of @{text "th\<^isub>0"} are @{text "th\<^isub>1"} and @{text "th\<^isub>2"}, which wait for resource @{text "cs\<^isub>1"}, |
355 but also @{text "th\<^isub>3"}, |
355 but also @{text "th\<^isub>3"}, |
356 which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which |
356 which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which |
357 in turn needs to wait for @{text "th\<^isub>0"} to finish). If there is a circle in a RAG, then clearly |
357 in turn needs to wait for @{text "th\<^isub>0"} to finish). If there is a circle of dependencies |
|
358 in a RAG, then clearly |
358 we have a deadlock. Therefore when a thread requests a resource, |
359 we have a deadlock. Therefore when a thread requests a resource, |
359 we must ensure that the resulting RAG is not circular. |
360 we must ensure that the resulting RAG is not circular. |
360 |
361 |
361 Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a |
362 Next we introduce the notion of the \emph{current precedence} of a thread @{text th} in a |
362 state @{text s}. It is defined as |
363 state @{text s}. It is defined as |
389 \noindent |
390 \noindent |
390 The first function is a waiting queue function (that is, it takes a |
391 The first function is a waiting queue function (that is, it takes a |
391 resource @{text "cs"} and returns the corresponding list of threads |
392 resource @{text "cs"} and returns the corresponding list of threads |
392 that lock, respectively wait for, it); the second is a function that |
393 that lock, respectively wait for, it); the second is a function that |
393 takes a thread and returns its current precedence (see |
394 takes a thread and returns its current precedence (see |
394 \eqref{cpreced}). We assume the usual getter and setter methods for |
395 the definition in \eqref{cpreced}). We assume the usual getter and setter methods for |
395 such records. |
396 such records. |
396 |
397 |
397 In the initial state, the scheduler starts with all resources unlocked (the corresponding |
398 In the initial state, the scheduler starts with all resources unlocked (the corresponding |
398 function is defined in \eqref{allunlocked}) and the |
399 function is defined in \eqref{allunlocked}) and the |
399 current precedence of every thread is initialised with @{term "Prc 0 0"}; that means |
400 current precedence of every thread is initialised with @{term "Prc 0 0"}; that means |
400 \mbox{@{abbrev initial_cprec}}. Therefore |
401 \mbox{@{abbrev initial_cprec}}. Therefore |
401 we have for the initial state |
402 we have for the initial shedule state |
402 |
403 |
403 \begin{isabelle}\ \ \ \ \ %%% |
404 \begin{isabelle}\ \ \ \ \ %%% |
404 \begin{tabular}{@ {}l} |
405 \begin{tabular}{@ {}l} |
405 @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ |
406 @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ |
406 \hspace{5mm}@{term "(|wq_fun = all_unlocked, cprec_fun = (\<lambda>_::thread. Prc 0 0)|)"} |
407 \hspace{5mm}@{term "(|wq_fun = all_unlocked, cprec_fun = (\<lambda>_::thread. Prc 0 0)|)"} |
599 text {* |
601 text {* |
600 Sha et al.~state their first correctness criterion for PIP in terms |
602 Sha et al.~state their first correctness criterion for PIP in terms |
601 of the number of low-priority threads \cite[Theorem 3]{Sha90}: if |
603 of the number of low-priority threads \cite[Theorem 3]{Sha90}: if |
602 there are @{text n} low-priority threads, then a blocked job with |
604 there are @{text n} low-priority threads, then a blocked job with |
603 high priority can only be blocked @{text n} times. |
605 high priority can only be blocked @{text n} times. |
604 Their second correctness criterion is stated |
606 Their second correctness criterion is given |
605 in terms of the number of critical resources \cite[Theorem 6]{Sha90}: if there are |
607 in terms of the number of critical resources \cite[Theorem 6]{Sha90}: if there are |
606 @{text m} critical resources, then a blocked job with high priority |
608 @{text m} critical resources, then a blocked job with high priority |
607 can only be blocked @{text m} times. Both results on their own, strictly speaking, do |
609 can only be blocked @{text m} times. Both results on their own, strictly speaking, do |
608 \emph{not} prevent indefinite, or unbounded, Priority Inversion, |
610 \emph{not} prevent indefinite, or unbounded, Priority Inversion, |
609 because if a low-priority thread does not give up its critical |
611 because if a low-priority thread does not give up its critical |
610 resource (the one the high-priority thread is waiting for), then the |
612 resource (the one the high-priority thread is waiting for), then the |
611 high-priority thread can never run. The argument of Sha et al.~is |
613 high-priority thread can never run. The argument of Sha et al.~is |
612 that \emph{if} threads release locked resources in a finite amount |
614 that \emph{if} threads release locked resources in a finite amount |
613 of time, then indefinite Priority Inversion cannot occur---the high-priority |
615 of time, then indefinite Priority Inversion cannot occur---the high-priority |
614 thread is guaranteed to run eventually. The assumption is that |
616 thread is guaranteed to run eventually. The assumption is that |
615 programmers always ensure that this is the case. However, even |
617 programmers must ensure that threads are programmed in this way. However, even |
616 taking this assumption into account, their correctness properties are |
618 taking this assumption into account, the correctness properties of |
617 \emph{not} true for their version of PIP. As Yodaiken |
619 Sha et al.~are |
|
620 \emph{not} true for their version of PIP---despide being ``proved''. As Yodaiken |
618 \cite{Yodaiken02} pointed out: If a low-priority thread possesses |
621 \cite{Yodaiken02} pointed out: If a low-priority thread possesses |
619 locks to two resources for which two high-priority threads are |
622 locks to two resources for which two high-priority threads are |
620 waiting for, then lowering the priority prematurely after giving up |
623 waiting for, then lowering the priority prematurely after giving up |
621 only one lock, can cause indefinite Priority Inversion for one of the |
624 only one lock, can cause indefinite Priority Inversion for one of the |
622 high-priority threads, invalidating their two bounds. |
625 high-priority threads, invalidating their two bounds. |
623 |
626 |
624 Even when fixed, their proof idea does not seem to go through for |
627 Even when fixed, their proof idea does not seem to go through for |
625 us, because of the way we have set up our formal model of PIP. The |
628 us, because of the way we have set up our formal model of PIP. One |
626 reason is that we allow that critical sections can intersect |
629 reason is that we allow that critical sections can intersect |
627 (something Sha et al.~explicitly exclude). Therefore we have a |
630 (something Sha et al.~explicitly exclude). Therefore we have designed a |
628 different correctness criterion for PIP. The idea behind our |
631 different correctness criterion for PIP. The idea behind our |
629 criterion is as follows: for all states @{text |
632 criterion is as follows: for all states @{text |
630 s}, we know the corresponding thread @{text th} with the highest |
633 s}, we know the corresponding thread @{text th} with the highest |
631 precedence; we show that in every future state (denoted by @{text |
634 precedence; we show that in every future state (denoted by @{text |
632 "s' @ s"}) in which @{text th} is still alive, either @{text th} is |
635 "s' @ s"}) in which @{text th} is still alive, either @{text th} is |
697 highest precedence in the state @{text s}, can only be blocked in |
701 highest precedence in the state @{text s}, can only be blocked in |
698 the state @{text "s' @ s"} by a thread @{text th'} that already |
702 the state @{text "s' @ s"} by a thread @{text th'} that already |
699 existed in @{text s} and requested or had a lock on at least |
703 existed in @{text s} and requested or had a lock on at least |
700 one resource---that means the thread was not \emph{detached} in @{text s}. |
704 one resource---that means the thread was not \emph{detached} in @{text s}. |
701 As we shall see shortly, that means there are only finitely |
705 As we shall see shortly, that means there are only finitely |
702 many threads that can block @{text th} and then need to run |
706 many threads that can block @{text th} in this way and then they |
703 with the same current precedence as @{text th}. |
707 need to run with the same current precedence as @{text th}. |
704 |
708 |
705 Like in the argument by Sha et al.~our |
709 Like in the argument by Sha et al.~our |
706 finite bound does not guarantee absence of indefinite Priority |
710 finite bound does not guarantee absence of indefinite Priority |
707 Inversion. For this we further have to assume that every thread |
711 Inversion. For this we further have to assume that every thread |
708 gives up its resources (that means get detached) after a finite amount of time. We found that |
712 gives up its resources after a finite amount of time. We found that |
709 this assumption is awkward to formalise in our model. Therefore we |
713 this assumption is awkward to formalise in our model. Therefore we |
710 leave it out and let the programmer assume the responsibility to |
714 leave it out and let the programmer assume the responsibility to |
711 program threads in such a benign manner (in addition to causing no |
715 program threads in such a benign manner (in addition to causing no |
712 circularity in the @{text RAG}). In this detail, we do not |
716 circularity in the @{text RAG}). In this detail, we do not |
713 make any progress in comparison with the work by Sha et al. |
717 make any progress in comparison with the work by Sha et al. |
714 However, we are able to combine their two separate bounds into a |
718 However, we are able to combine their two separate bounds into a |
715 single theorem. |
719 single theorem improving their bound. |
716 |
720 |
717 In what follows we will describe properties of PIP that allow us to prove |
721 In what follows we will describe properties of PIP that allow us to prove |
718 Theorem~\ref{mainthm} and, when instructive, briefly describe our argument. |
722 Theorem~\ref{mainthm} and, when instructive, briefly describe our argument. |
719 It is relatively easily to see that |
723 It is relatively easily to see that |
720 |
724 |
791 By defintion of @{text "running"}, @{text "th'"} can not be running in state |
795 By defintion of @{text "running"}, @{text "th'"} can not be running in state |
792 @{text "s' @ s"}, as we had to show.\qed |
796 @{text "s' @ s"}, as we had to show.\qed |
793 \end{proof} |
797 \end{proof} |
794 |
798 |
795 \noindent |
799 \noindent |
796 Since @{text "th'"} is not able to run at state @{text "s' @ s"}, it is not able to |
800 Since @{text "th'"} is not able to run in state @{text "s' @ s"}, it is not able to |
797 issue a @{text "P"} or @{text "V"} event. Therefore if @{text "s' @ s"} is extended |
801 issue a @{text "P"} or @{text "V"} event. Therefore if @{text "s' @ s"} is extended |
798 one step further, @{text "th'"} still cannot hold any resource. The situation will |
802 one step further, @{text "th'"} still cannot hold any resource. The situation will |
799 not change in further extensions as long as @{text "th"} holds the highest precedence. |
803 not change in further extensions as long as @{text "th"} holds the highest precedence. |
800 |
804 |
801 From this lemma we can deduce Theorem~\ref{mainthm}: that @{text th} can only be |
805 From this lemma we can deduce Theorem~\ref{mainthm}: that @{text th} can only be |
802 blocked by a thread @{text th'} that |
806 blocked by a thread @{text th'} that |
803 held some resource in state @{text s} (that is not @{text "detached"}). And furthermore |
807 held some resource in state @{text s} (that is not @{text "detached"}). And furthermore |
804 that the current precedence of @{text th'} in state @{text "(s' @ s)"} must be equal to the |
808 that the current precedence of @{text th'} in state @{text "(s' @ s)"} must be equal to the |
805 precedence of @{text th} in @{text "s"}. |
809 precedence of @{text th} in @{text "s"}. |
806 We show this theorem by induction on @{text "s'"} using Lemma~\ref{mainlem}. |
810 We show this theorem by induction on @{text "s'"} using Lemma~\ref{mainlem}. |
807 This theorem gives a stricter bound on the processes that can block @{text th}: |
811 This theorem gives a stricter bound on the processes that can block @{text th} than the |
|
812 one obtained by Sha et al.~\cite{Sha90}: |
808 only threads that were alive in state @{text s} and moreover held a resource. |
813 only threads that were alive in state @{text s} and moreover held a resource. |
809 This means our bound is in terms of both---alive threads in state @{text s} |
814 This means our bound is in terms of both---alive threads in state @{text s} |
810 and number of critical resources. Finally, the theorem establishes that the blocking threads have the |
815 and number of critical resources. Finally, the theorem establishes that the blocking threads have the |
811 current precedence raised to the precedence of @{text th}. |
816 current precedence raised to the precedence of @{text th}. |
812 |
817 |
944 al.~\cite{Sha90}), we found that the formalisation can even help us |
949 al.~\cite{Sha90}), we found that the formalisation can even help us |
945 with efficiently implementing PIP. |
950 with efficiently implementing PIP. |
946 |
951 |
947 For example Baker complained that calculating the current precedence |
952 For example Baker complained that calculating the current precedence |
948 in PIP is quite ``heavy weight'' in Linux (see the Introduction). |
953 in PIP is quite ``heavy weight'' in Linux (see the Introduction). |
949 In our model of PIP the current precedence of a thread in a state s |
954 In our model of PIP the current precedence of a thread in a state @{text s} |
950 depends on all its dependants---a ``global'' transitive notion, |
955 depends on all its dependants---a ``global'' transitive notion, |
951 which is indeed heavy weight (see Def.~shown in \eqref{cpreced}). |
956 which is indeed heavy weight (see Def.~shown in \eqref{cpreced}). |
952 We can however improve upon this. For this let us define the notion |
957 We can however improve upon this. For this let us define the notion |
953 of @{term children} of a thread @{text th} in a state @{text s} as |
958 of @{term children} of a thread @{text th} in a state @{text s} as |
954 |
959 |
1054 \noindent |
1059 \noindent |
1055 The first property is again telling us we do not need to change the @{text RAG}. The second |
1060 The first property is again telling us we do not need to change the @{text RAG}. The second |
1056 however states that only threads that are \emph{not} dependants of @{text th} have their |
1061 however states that only threads that are \emph{not} dependants of @{text th} have their |
1057 current precedence unchanged. For the others we have to recalculate the current |
1062 current precedence unchanged. For the others we have to recalculate the current |
1058 precedence. To do this we can start from @{term "th"} |
1063 precedence. To do this we can start from @{term "th"} |
1059 and follow the @{term "depend"}-chains to recompute the @{term "cp"} of every |
1064 and follow the @{term "depend"}-edges to recompute using Lemma~\ref{childrenlem} |
1060 thread encountered on the way using Lemma~\ref{childrenlem}. Since the @{term "depend"} |
1065 the @{term "cp"} of every |
|
1066 thread encountered on the way. Since the @{term "depend"} |
1061 is loop free, this procedure will always stop. The following two lemmas show, however, |
1067 is loop free, this procedure will always stop. The following two lemmas show, however, |
1062 that this procedure can actually stop often earlier without having to consider all |
1068 that this procedure can actually stop often earlier without having to consider all |
1063 dependants. |
1069 dependants. |
1064 |
1070 |
1065 \begin{isabelle}\ \ \ \ \ %%% |
1071 \begin{isabelle}\ \ \ \ \ %%% |
1088 \colorbox{mygrey}{@{term "V th cs"}:} We assume that @{text s'} and |
1094 \colorbox{mygrey}{@{term "V th cs"}:} We assume that @{text s'} and |
1089 @{term "s \<equiv> V th cs#s'"} are both valid. We have to consider two |
1095 @{term "s \<equiv> V th cs#s'"} are both valid. We have to consider two |
1090 subcases: one where there is a thread to ``take over'' the released |
1096 subcases: one where there is a thread to ``take over'' the released |
1091 resource @{text cs}, and one where there is not. Let us consider them |
1097 resource @{text cs}, and one where there is not. Let us consider them |
1092 in turn. Suppose in state @{text s}, the thread @{text th'} takes over |
1098 in turn. Suppose in state @{text s}, the thread @{text th'} takes over |
1093 resource @{text cs} from thread @{text th}. We can show |
1099 resource @{text cs} from thread @{text th}. We can prove |
1094 |
1100 |
1095 |
1101 |
1096 \begin{isabelle}\ \ \ \ \ %%% |
1102 \begin{isabelle}\ \ \ \ \ %%% |
1097 @{thm depend_s} |
1103 @{thm depend_s} |
1098 \end{isabelle} |
1104 \end{isabelle} |
1099 |
1105 |
1100 \noindent |
1106 \noindent |
1101 which shows how the @{text RAG} needs to be changed. This also suggests |
1107 which shows how the @{text RAG} needs to be changed. The next lemma suggests |
1102 how the current precedences need to be recalculated. For threads that are |
1108 how the current precedences need to be recalculated. For threads that are |
1103 not @{text "th"} and @{text "th'"} nothing needs to be changed, since we |
1109 not @{text "th"} and @{text "th'"} nothing needs to be changed, since we |
1104 can show |
1110 can show |
1105 |
1111 |
1106 \begin{isabelle}\ \ \ \ \ %%% |
1112 \begin{isabelle}\ \ \ \ \ %%% |
1158 \noindent |
1163 \noindent |
1159 That means we have to add a waiting edge to the @{text RAG}. Furthermore |
1164 That means we have to add a waiting edge to the @{text RAG}. Furthermore |
1160 the current precedence for all threads that are not dependants of @{text th} |
1165 the current precedence for all threads that are not dependants of @{text th} |
1161 are unchanged. For the others we need to follow the edges |
1166 are unchanged. For the others we need to follow the edges |
1162 in the @{text RAG} and recompute the @{term "cp"}. However, like in the |
1167 in the @{text RAG} and recompute the @{term "cp"}. However, like in the |
1163 @case of {text Set}, this operation can stop often earlier, namely when intermediate |
1168 case of @{text Set}, this operation can stop often earlier, namely when intermediate |
1164 values do not change. |
1169 values do not change. |
1165 *} |
1170 *} |
1166 (*<*) |
1171 (*<*) |
1167 end |
1172 end |
1168 (*>*) |
1173 (*>*) |
1169 text {* |
1174 text {* |
1170 \noindent |
1175 \noindent |
1171 A pleasing result of our formalisation is that the properties in |
1176 As can be seen, a pleasing byproduct of our formalisation is that the properties in |
1172 this section closely inform an implementation of PIP: Whether the |
1177 this section closely inform an implementation of PIP, namely whether the |
1173 @{text RAG} needs to be reconfigured or current precedences need to |
1178 @{text RAG} needs to be reconfigured or current precedences need to |
1174 recalculated for an event is given by a lemma we proved. |
1179 by recalculated for an event. This information is provided by the lemmas we proved. |
1175 *} |
1180 *} |
1176 |
1181 |
1177 section {* Conclusion *} |
1182 section {* Conclusion *} |
1178 |
1183 |
1179 text {* |
1184 text {* |
1180 The Priority Inheritance Protocol (PIP) is a classic textbook |
1185 The Priority Inheritance Protocol (PIP) is a classic textbook |
1181 algorithm used in real-time operating systems in order to avoid the problem of |
1186 algorithm used in many real-time operating systems in order to avoid the problem of |
1182 Priority Inversion. Although classic and widely used, PIP does have |
1187 Priority Inversion. Although classic and widely used, PIP does have |
1183 its faults: for example it does not prevent deadlocks in cases where threads |
1188 its faults: for example it does not prevent deadlocks in cases where threads |
1184 have circular lock dependencies. |
1189 have circular lock dependencies. |
1185 |
1190 |
1186 We had two goals in mind with our formalisation of PIP: One is to |
1191 We had two goals in mind with our formalisation of PIP: One is to |
1198 \cite{Wang09}. |
1203 \cite{Wang09}. |
1199 |
1204 |
1200 The second goal of our formalisation is to provide a specification for actually |
1205 The second goal of our formalisation is to provide a specification for actually |
1201 implementing PIP. Textbooks, for example \cite[Section 5.6.5]{Vahalia96}, |
1206 implementing PIP. Textbooks, for example \cite[Section 5.6.5]{Vahalia96}, |
1202 explain how to use various implementations of PIP and abstractly |
1207 explain how to use various implementations of PIP and abstractly |
1203 discuss their properties, but surprisingly lack most details for a |
1208 discuss their properties, but surprisingly lack most details important for a |
1204 programmer who wants to implement PIP. That this is an issue in practice is illustrated by the |
1209 programmer who wants to implement PIP (similarly Sha et al.~\cite{Sha90}). |
|
1210 That this is an issue in practice is illustrated by the |
1205 email from Baker we cited in the Introduction. We achieved also this |
1211 email from Baker we cited in the Introduction. We achieved also this |
1206 goal: The formalisation gives the first author enough data to enable |
1212 goal: The formalisation gives the first author enough data to enable |
1207 his undergraduate students to implement PIP (as part of their OS course) |
1213 his undergraduate students to implement PIP (as part of their OS course) |
1208 on top of PINTOS, a small operating system for teaching |
1214 on top of PINTOS, a small operating system for teaching |
1209 purposes. A byproduct of our formalisation effort is that nearly all |
1215 purposes. A byproduct of our formalisation effort is that nearly all |
1210 design choices for the PIP scheduler are backed up with a proved |
1216 design choices for the PIP scheduler are backed up with a proved |
1211 lemma. We were also able to establish the property that the choice of |
1217 lemma. We were also able to establish the property that the choice of |
1212 the next thread which takes over a lock is irrelevant for the correctness |
1218 the next thread which takes over a lock is irrelevant for the correctness |
1213 of PIP. Earlier model checking approaches which verified implementations |
1219 of PIP. Earlier model checking approaches which verified particular implementations |
1214 of PIP \cite{Faria08,Jahier09,Wellings07} cannot |
1220 of PIP \cite{Faria08,Jahier09,Wellings07} cannot |
1215 provide this kind of ``deep understanding'' about the principles behind |
1221 provide this kind of ``deep understanding'' about the principles behind |
1216 PIP and its correctness. |
1222 PIP and its correctness. |
1217 |
1223 |
1218 PIP is a scheduling algorithm for single-processor systems. We are |
1224 PIP is a scheduling algorithm for single-processor systems. We are |
1221 teaching. Priority Inversion certainly occurs also in |
1227 teaching. Priority Inversion certainly occurs also in |
1222 multi-processor systems. However, the surprising answer, according |
1228 multi-processor systems. However, the surprising answer, according |
1223 to \cite{Steinberg10}, is that except for one unsatisfactory |
1229 to \cite{Steinberg10}, is that except for one unsatisfactory |
1224 proposal nobody has a good idea for how PIP should be modified to |
1230 proposal nobody has a good idea for how PIP should be modified to |
1225 work correctly on multi-processor systems. The difficulties become |
1231 work correctly on multi-processor systems. The difficulties become |
1226 clear when considering that locking and releasing a resource always |
1232 clear when considering the fact that locking and releasing a resource always |
1227 requires a small amount of time. If processes work independently, |
1233 requires a small amount of time. If processes work independently, |
1228 then a low priority process can ``steal'' in such an unguarded |
1234 then a low priority process can ``steal'' in such an unguarded |
1229 moment a lock for a resource that was supposed allow a high-priority |
1235 moment a lock for a resource that was supposed to allow a high-priority |
1230 process to run next. Thus the problem of Priority Inversion is not |
1236 process to run next. Thus the problem of Priority Inversion is not |
1231 really prevented. It seems difficult to design a PIP-algorithm with |
1237 really prevented by the classic PIP. It seems difficult to design a PIP-algorithm with |
1232 a meaningful correctness property on a multi-processor systems where |
1238 a meaningful correctness property on a multi-processor systems where |
1233 processes work independently. We can imagine PIP to be of use in |
1239 processes work independently. We can imagine PIP to be of use in |
1234 situations where processes are \emph{not} independent, but |
1240 situations where processes are \emph{not} independent, but |
1235 coordinated via a master process that distributes work over some |
1241 coordinated via a master process that distributes work over some |
1236 slave processes. However, a formal investigation of this is beyond |
1242 slave processes. However, a formal investigation of this idea is beyond |
1237 the scope of this paper. We are not aware of any proofs in this |
1243 the scope of this paper. We are not aware of any proofs in this |
1238 area, not even informal ones. |
1244 area, not even informal or flawed ones. |
1239 |
1245 |
1240 The most closely related work to ours is the formal verification in |
1246 The most closely related work to ours is the formal verification in |
1241 PVS for Priority Ceiling done by Dutertre \cite{dutertre99b}. His formalisation |
1247 PVS of the Priority Ceiling Protocol done by Dutertre |
1242 consists of 407 lemmas and 2500 lines of ``specification'' (we do not |
1248 \cite{dutertre99b}---another solution to the Priority Inversion |
1243 know whether this includes also code for proofs). Our formalisation |
1249 problem, which however needs |
|
1250 static analysis of programs in order to avoid it. |
|
1251 His formalisation consists of 407 lemmas and 2500 lines of (PVS) code. Our formalisation |
1244 consists of around 210 lemmas and overall 6950 lines of readable Isabelle/Isar |
1252 consists of around 210 lemmas and overall 6950 lines of readable Isabelle/Isar |
1245 code with a few apply-scripts interspersed. The formal model of PIP |
1253 code with a few apply-scripts interspersed. The formal model of PIP |
1246 is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary |
1254 is 385 lines long; the formal correctness proof 3800 lines. Some auxiliary |
1247 definitions and proofs took 770 lines of code. The properties relevant |
1255 definitions and proofs span over 770 lines of code. The properties relevant |
1248 for an implementation took 2000 lines. The code of our formalisation |
1256 for an implementation require 2000 lines. The code of our formalisation |
1249 can be downloaded from\\ |
1257 can be downloaded from |
1250 \url{http://www.dcs.kcl.ac.uk/staff/urbanc/pip.html}. |
1258 \url{http://www.dcs.kcl.ac.uk/staff/urbanc/pip.html}. |
1251 |
1259 |
1252 \bibliographystyle{plain} |
1260 \bibliographystyle{plain} |
1253 \bibliography{root} |
1261 \bibliography{root} |
1254 *} |
1262 *} |