80 locking a resource prevented a high priority thread from running in |
80 locking a resource prevented a high priority thread from running in |
81 time, leading to a system reset. Once the problem was found, it was |
81 time, leading to a system reset. Once the problem was found, it was |
82 rectified by enabling the \emph{Priority Inheritance Protocol} (PIP) |
82 rectified by enabling the \emph{Priority Inheritance Protocol} (PIP) |
83 \cite{Sha90}\footnote{Sha et al.~call it the \emph{Basic Priority |
83 \cite{Sha90}\footnote{Sha et al.~call it the \emph{Basic Priority |
84 Inheritance Protocol} \cite{Sha90} and others sometimes also call it |
84 Inheritance Protocol} \cite{Sha90} and others sometimes also call it |
85 \emph{Priority Boosting}.} in the scheduling software. |
85 \emph{Priority Boosting} or \emph{Priority Donation}.} in the scheduling software. |
86 |
86 |
87 The idea behind PIP is to let the thread $L$ temporarily inherit |
87 The idea behind PIP is to let the thread $L$ temporarily inherit |
88 the high priority from $H$ until $L$ leaves the critical section |
88 the high priority from $H$ until $L$ leaves the critical section |
89 unlocking the resource. This solves the problem of $H$ having to |
89 unlocking the resource. This solves the problem of $H$ having to |
90 wait indefinitely, because $L$ cannot be blocked by threads having |
90 wait indefinitely, because $L$ cannot be blocked by threads having |
165 \noindent |
165 \noindent |
166 {\bf Contributions:} There have been earlier formal investigations |
166 {\bf Contributions:} There have been earlier formal investigations |
167 into PIP \cite{Faria08,Jahier09,Wellings07}, but they employ model |
167 into PIP \cite{Faria08,Jahier09,Wellings07}, but they employ model |
168 checking techniques. This paper presents a formalised and |
168 checking techniques. This paper presents a formalised and |
169 mechanically checked proof for the correctness of PIP (to our |
169 mechanically checked proof for the correctness of PIP (to our |
170 knowledge the first one). |
170 knowledge the first one). In contrast to model checking, our |
171 In contrast to model checking, our |
|
172 formalisation provides insight into why PIP is correct and allows us |
171 formalisation provides insight into why PIP is correct and allows us |
173 to prove stronger properties that, as we will show, can inform an |
172 to prove stronger properties that, as we will show, can help with an |
174 efficient implementation. For example, we found by ``playing'' with the formalisation |
173 efficient implementation of PIP in the educational PINTOS operating |
175 that the choice of the next thread to take over a lock when a |
174 system \cite{PINTOS}. For example, we found by ``playing'' with the |
176 resource is released is irrelevant for PIP being correct---a fact |
175 formalisation that the choice of the next thread to take over a lock |
177 that has not been mentioned in the literature. This is important |
176 when a resource is released is irrelevant for PIP being correct---a |
178 for an efficient implementation, because we can give the lock to the |
177 fact that has not been mentioned in the literature and not been used |
179 thread with the highest priority so that it terminates more quickly. |
178 in the reference implementation of PIP in PINTOS. This is important |
|
179 for an efficient implementation of PIP, because we can give the lock |
|
180 to the thread with the highest priority so that it terminates more |
|
181 quickly. |
180 *} |
182 *} |
181 |
183 |
182 section {* Formal Model of the Priority Inheritance Protocol *} |
184 section {* Formal Model of the Priority Inheritance Protocol *} |
183 |
185 |
184 text {* |
186 text {* |
1210 \noindent |
1212 \noindent |
1211 As can be seen, a pleasing byproduct of our formalisation is that the properties in |
1213 As can be seen, a pleasing byproduct of our formalisation is that the properties in |
1212 this section closely inform an implementation of PIP, namely whether the |
1214 this section closely inform an implementation of PIP, namely whether the |
1213 @{text RAG} needs to be reconfigured or current precedences need to |
1215 @{text RAG} needs to be reconfigured or current precedences need to |
1214 be recalculated for an event. This information is provided by the lemmas we proved. |
1216 be recalculated for an event. This information is provided by the lemmas we proved. |
1215 We confirmened that our observations translate into practice by implementing |
1217 We confirmed that our observations translate into practice by implementing |
1216 a PIP-scheduler on top of PINTOS, a small operating system for teaching purposes \cite{PINTOS}. |
1218 our version of PIP on top of PINTOS, a small operating system written in C and used for teaching at |
1217 Our events translate in PINTOS to the following function interface: |
1219 Stanford University \cite{PINTOS}. To implement PIP, we only need to modify the kernel |
|
1220 functions corresponding to the events in our formal model. The events translate to the following |
|
1221 function interface in PINTOS: |
1218 |
1222 |
1219 \begin{center} |
1223 \begin{center} |
1220 \begin{tabular}{|l|l|} |
1224 \begin{tabular}{|l@ {\hspace{2mm}}|l@ {\hspace{2mm}}|} |
1221 \hline |
1225 \hline |
1222 {\bf Event} & {\bf PINTOS function} \\ |
1226 {\bf Event} & {\bf PINTOS function} \\ |
1223 \hline |
1227 \hline |
1224 @{text Create} & \\ |
1228 @{text Create} & @{text "thread_create"}\\ |
1225 @{text Exit} & \\ |
1229 @{text Exit} & @{text "thread_exit"}\\ |
|
1230 @{text Set} & @{text "thread_set_priority"}\\ |
|
1231 @{text P} & @{text "lock_acquire"}\\ |
|
1232 @{text V} & @{text "lock_release"}\\ |
|
1233 \hline |
1226 \end{tabular} |
1234 \end{tabular} |
1227 \end{center} |
1235 \end{center} |
1228 |
1236 |
|
1237 \noindent |
|
1238 Our assumption that every event is an atomic operation is ensured by the architecture of |
|
1239 PINTOS. The case where an unlocked resource is given next to the waiting thread with the |
|
1240 highest precedence is realised in our implementation by priority queues. We implemented |
|
1241 them as \emph{Braun trees} \cite{Paulson96}, which provide efficient @{text "O(log n)"}-operations |
|
1242 for accessing and restructuring. Apart from having to implement complex datastructures in C |
|
1243 using pointers, our experience with the implementation has been very positive: our specification |
|
1244 and formalisation of PIP translates smoothly to an efficent implementation. |
1229 *} |
1245 *} |
1230 |
1246 |
1231 section {* Conclusion *} |
1247 section {* Conclusion *} |
1232 |
1248 |
1233 text {* |
1249 text {* |
1263 design choices for the PIP scheduler are backed up with a proved |
1279 design choices for the PIP scheduler are backed up with a proved |
1264 lemma. We were also able to establish the property that the choice of |
1280 lemma. We were also able to establish the property that the choice of |
1265 the next thread which takes over a lock is irrelevant for the correctness |
1281 the next thread which takes over a lock is irrelevant for the correctness |
1266 of PIP. |
1282 of PIP. |
1267 |
1283 |
1268 {\bf ??? rewrite the following slightly} |
|
1269 |
|
1270 PIP is a scheduling algorithm for single-processor systems. We are |
1284 PIP is a scheduling algorithm for single-processor systems. We are |
1271 now living in a multi-processor world. So the question naturally |
1285 now living in a multi-processor world. So the question naturally |
1272 arises whether PIP has any relevance in such a world beyond |
1286 arises whether PIP has any relevance in such a world beyond |
1273 teaching. Priority Inversion certainly occurs also in |
1287 teaching. Priority Inversion certainly occurs also in |
1274 multi-processor systems. However, the surprising answer, according |
1288 multi-processor systems. However, the answer is that |
1275 to \cite{Steinberg10}, is that except for one unsatisfactory |
1289 there is very little work about PIP and multi-processors in the literature. |
1276 proposal nobody has a good idea for how PIP should be modified to |
1290 We are not aware of any proofs in this area, not even informal ones. There |
1277 work correctly on multi-processor systems. The difficulties become |
1291 is an implementation of PIP on multi-processors in Linux as part of the ``real-time'' effort, |
1278 clear when considering the fact that releasing and re-locking a resource always |
1292 with an informal description given in \cite{LINUX}. |
1279 requires a small amount of time. If processes work independently, |
1293 We estimate that the formal verification of this algorithm, involving more |
1280 then a low priority process can ``steal'' in such an unguarded |
1294 fine-grained events, is a magnitude harder than the one we presented here, but |
1281 moment a lock for a resource that was supposed to allow a high-priority |
1295 still within reach of current theorem proving technology. We leave this for future |
1282 process to run next. Thus the problem of Priority Inversion is not |
1296 work. |
1283 really prevented by the classic PIP. It seems difficult to design a PIP-algorithm with |
|
1284 a meaningful correctness property on a multi-processor systems where |
|
1285 processes work independently. We can imagine PIP to be of use in |
|
1286 situations where processes are \emph{not} independent, but |
|
1287 coordinated via a master process that distributes work over some |
|
1288 slave processes. However, a formal investigation of this idea is beyond |
|
1289 the scope of this paper. We are not aware of any proofs in this |
|
1290 area, not even informal or flawed ones. |
|
1291 |
1297 |
1292 The most closely related work to ours is the formal verification in |
1298 The most closely related work to ours is the formal verification in |
1293 PVS of the Priority Ceiling Protocol done by Dutertre |
1299 PVS of the Priority Ceiling Protocol done by Dutertre |
1294 \cite{dutertre99b}---another solution to the Priority Inversion |
1300 \cite{dutertre99b}---another solution to the Priority Inversion |
1295 problem, which however needs static analysis of programs in order to |
1301 problem, which however needs static analysis of programs in order to |