94 implemented. This includes VxWorks (a proprietary real-time OS used |
82 implemented. This includes VxWorks (a proprietary real-time OS used |
95 in the Mars Pathfinder mission, in Boeing's 787 Dreamliner, Honda's |
83 in the Mars Pathfinder mission, in Boeing's 787 Dreamliner, Honda's |
96 ASIMO robot, etc.), but also the POSIX 1003.1c Standard realised for |
84 ASIMO robot, etc.), but also the POSIX 1003.1c Standard realised for |
97 example in libraries for FreeBSD, Solaris and Linux. |
85 example in libraries for FreeBSD, Solaris and Linux. |
98 |
86 |
99 One advantage of PIP is that increasing the priority of a thread |
87 Two advantages of PIP are that increasing the priority of a thread |
100 can be performed dynamically by the scheduler. This is in contrast |
88 can be performed dynamically by the scheduler and is deterministic. |
101 to, for example, \emph{Priority Ceiling} \cite{Sha90}, another |
89 This is in contrast to \emph{Priority Ceiling} |
102 solution to the Priority Inversion problem, which requires static |
90 \cite{Sha90}, another solution to the Priority Inversion problem, |
103 analysis of the program in order to prevent Priority |
91 which requires static analysis of the program in order to prevent |
104 Inversion. However, there has also been strong criticism against |
92 Priority Inversion, and also to the Windows NT scheduler, which avoids |
|
93 this problem by randomly boosting the priority of ready (low priority) threads |
|
94 (e.g.~\cite{WINDOWSNT}). |
|
95 However, there has also been strong criticism against |
105 PIP. For instance, PIP cannot prevent deadlocks when lock |
96 PIP. For instance, PIP cannot prevent deadlocks when lock |
106 dependencies are circular, and also blocking times can be |
97 dependencies are circular, and also blocking times can be |
107 substantial (more than just the duration of a critical section). |
98 substantial (more than just the duration of a critical section). |
108 Though, most criticism against PIP centres around unreliable |
99 Though, most criticism against PIP centres around unreliable |
109 implementations and PIP being too complicated and too inefficient. |
100 implementations and PIP being too complicated and too inefficient. |
158 behaviour for $L$ is to switch to the highest remaining priority of |
149 behaviour for $L$ is to switch to the highest remaining priority of |
159 the threads that it blocks. The advantage of formalising the |
150 the threads that it blocks. The advantage of formalising the |
160 correctness of a high-level specification of PIP in a theorem prover |
151 correctness of a high-level specification of PIP in a theorem prover |
161 is that such issues clearly show up and cannot be overlooked as in |
152 is that such issues clearly show up and cannot be overlooked as in |
162 informal reasoning (since we have to analyse all possible behaviours |
153 informal reasoning (since we have to analyse all possible behaviours |
163 of threads, i.e.~\emph{traces}, that could possibly happen).\medskip |
154 of threads, i.e.~\emph{traces}, that could possibly happen).\footnote{While |
|
155 \cite{Sha90} is the only formal publication we have |
|
156 found that describes the incorrect behaviour, not all, but many |
|
157 informal descriptions of PIP overlook the case...}\medskip |
164 |
158 |
165 \noindent |
159 \noindent |
166 {\bf Contributions:} There have been earlier formal investigations |
160 {\bf Contributions:} There have been earlier formal investigations |
167 into PIP \cite{Faria08,Jahier09,Wellings07}, but they employ model |
161 into PIP \cite{Faria08,Jahier09,Wellings07}, but they employ model |
168 checking techniques. This paper presents a formalised and |
162 checking techniques. This paper presents a formalised and |
333 \end{isabelle} |
327 \end{isabelle} |
334 |
328 |
335 \noindent |
329 \noindent |
336 If there is no cycle, then every RAG can be pictured as a forrest of trees, for example as follows: |
330 If there is no cycle, then every RAG can be pictured as a forrest of trees, for example as follows: |
337 |
331 |
338 \begin{figure}[h] |
332 \begin{figure}[ph] |
339 \begin{center} |
333 \begin{center} |
340 \newcommand{\fnt}{\fontsize{7}{8}\selectfont} |
334 \newcommand{\fnt}{\fontsize{7}{8}\selectfont} |
341 \begin{tikzpicture}[scale=1] |
335 \begin{tikzpicture}[scale=1] |
342 %%\draw[step=2mm] (-3,2) grid (1,-1); |
336 %%\draw[step=2mm] (-3,2) grid (1,-1); |
343 |
337 |
344 \node (A) at (0,0) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>0"}}; |
338 \node (A) at (0,0) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^sub>0"}}; |
345 \node (B) at (2,0) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>1"}}; |
339 \node (B) at (2,0) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^sub>1"}}; |
346 \node (C) at (4,0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>1"}}; |
340 \node (C) at (4,0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^sub>1"}}; |
347 \node (D) at (4,-0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>2"}}; |
341 \node (D) at (4,-0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^sub>2"}}; |
348 \node (E) at (6,-0.7) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>2"}}; |
342 \node (E) at (6,-0.7) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^sub>2"}}; |
349 \node (E1) at (6, 0.2) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>3"}}; |
343 \node (E1) at (6, 0.2) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^sub>3"}}; |
350 \node (F) at (8,-0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>3"}}; |
344 \node (F) at (8,-0.7) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^sub>3"}}; |
351 |
345 |
352 \node (X) at (0,-2) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>4"}}; |
346 \node (X) at (0,-2) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^sub>4"}}; |
353 \node (Y) at (2,-2) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>4"}}; |
347 \node (Y) at (2,-2) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^sub>4"}}; |
354 \node (Z) at (2,-2.9) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>5"}}; |
348 \node (Z) at (2,-2.9) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^sub>5"}}; |
355 \node (U1) at (4,-2) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>5"}}; |
349 \node (U1) at (4,-2) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^sub>5"}}; |
356 \node (U2) at (4,-2.9) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^isub>6"}}; |
350 \node (U2) at (4,-2.9) [draw, rounded corners=1mm, rectangle, very thick] {@{text "th\<^sub>6"}}; |
357 \node (R) at (6,-2.9) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^isub>6"}}; |
351 \node (R) at (6,-2.9) [draw, circle, very thick, inner sep=0.4mm] {@{text "cs\<^sub>6"}}; |
358 |
352 |
359 \draw [<-,line width=0.6mm] (A) to node [pos=0.54,sloped,above=-0.5mm] {\fnt{}holding} (B); |
353 \draw [<-,line width=0.6mm] (A) to node [pos=0.54,sloped,above=-0.5mm] {\fnt{}holding} (B); |
360 \draw [->,line width=0.6mm] (C) to node [pos=0.4,sloped,above=-0.5mm] {\fnt{}waiting} (B); |
354 \draw [->,line width=0.6mm] (C) to node [pos=0.4,sloped,above=-0.5mm] {\fnt{}waiting} (B); |
361 \draw [->,line width=0.6mm] (D) to node [pos=0.4,sloped,below=-0.5mm] {\fnt{}waiting} (B); |
355 \draw [->,line width=0.6mm] (D) to node [pos=0.4,sloped,below=-0.5mm] {\fnt{}waiting} (B); |
362 \draw [<-,line width=0.6mm] (D) to node [pos=0.54,sloped,below=-0.5mm] {\fnt{}holding} (E); |
356 \draw [<-,line width=0.6mm] (D) to node [pos=0.54,sloped,below=-0.5mm] {\fnt{}holding} (E); |
395 |
389 |
396 \noindent |
390 \noindent |
397 This definition needs to account for all threads that wait for a thread to |
391 This definition needs to account for all threads that wait for a thread to |
398 release a resource. This means we need to include threads that transitively |
392 release a resource. This means we need to include threads that transitively |
399 wait for a resource being released (in the picture above this means the dependants |
393 wait for a resource being released (in the picture above this means the dependants |
400 of @{text "th\<^isub>0"} are @{text "th\<^isub>1"} and @{text "th\<^isub>2"}, which wait for resource @{text "cs\<^isub>1"}, |
394 of @{text "th\<^sub>0"} are @{text "th\<^sub>1"} and @{text "th\<^sub>2"}, which wait for resource @{text "cs\<^sub>1"}, |
401 but also @{text "th\<^isub>3"}, |
395 but also @{text "th\<^sub>3"}, |
402 which cannot make any progress unless @{text "th\<^isub>2"} makes progress, which |
396 which cannot make any progress unless @{text "th\<^sub>2"} makes progress, which |
403 in turn needs to wait for @{text "th\<^isub>0"} to finish). If there is a circle of dependencies |
397 in turn needs to wait for @{text "th\<^sub>0"} to finish). If there is a circle of dependencies |
404 in a RAG, then clearly |
398 in a RAG, then clearly |
405 we have a deadlock. Therefore when a thread requests a resource, |
399 we have a deadlock. Therefore when a thread requests a resource, |
406 we must ensure that the resulting RAG is not circular. In practice, the |
400 we must ensure that the resulting RAG is not circular. In practice, the |
407 programmer has to ensure this. |
401 programmer has to ensure this. |
408 |
402 |
1451 the proof of Sha et al.: they require that critical sections nest properly, |
1445 the proof of Sha et al.: they require that critical sections nest properly, |
1452 whereas our scheduler allows critical sections to overlap. |
1446 whereas our scheduler allows critical sections to overlap. |
1453 |
1447 |
1454 PIP is a scheduling algorithm for single-processor systems. We are |
1448 PIP is a scheduling algorithm for single-processor systems. We are |
1455 now living in a multi-processor world. Priority Inversion certainly |
1449 now living in a multi-processor world. Priority Inversion certainly |
1456 occurs also there, see for example \cite{Brandenburg11, Davis11}. |
1450 occurs also there, see for example \cite{Brandenburg11,Davis11}. |
1457 However, there is very little ``foundational'' |
1451 However, there is very little ``foundational'' |
1458 work about PIP-algorithms on multi-processor systems. We are not |
1452 work about PIP-algorithms on multi-processor systems. We are not |
1459 aware of any correctness proofs, not even informal ones. There is an |
1453 aware of any correctness proofs, not even informal ones. There is an |
1460 implementation of a PIP-algorithm for multi-processors as part of the |
1454 implementation of a PIP-algorithm for multi-processors as part of the |
1461 ``real-time'' effort in Linux, including an informal description of the implemented scheduling |
1455 ``real-time'' effort in Linux, including an informal description of the implemented scheduling |