249 in PINTOS. This fact, however, is important for an efficient |
249 in PINTOS. This fact, however, is important for an efficient |
250 implementation of PIP, because we can give the lock to the thread |
250 implementation of PIP, because we can give the lock to the thread |
251 with the highest priority so that it terminates more quickly. We |
251 with the highest priority so that it terminates more quickly. We |
252 are also able to generalise the scheduler of Sha et |
252 are also able to generalise the scheduler of Sha et |
253 al.~\cite{Sha90} to the practically relevant case where critical |
253 al.~\cite{Sha90} to the practically relevant case where critical |
254 sections can overlap; see Figure~\ref{overlap} \emph{a)} below for |
254 sections can overlap; see Fig.~\ref{overlap} \emph{a)} for |
255 an example of this restriction. In the existing literature there is |
255 an example of this restriction. In the existing literature there is |
256 no proof and also no method for proving which covers this generalised |
256 no proof and also no proof method that covers this generalised |
257 case. |
257 case. |
258 |
258 |
259 \begin{figure} |
259 \begin{figure} |
260 \begin{center} |
260 \begin{center} |
261 \begin{tikzpicture}[scale=1] |
261 \begin{tikzpicture}[scale=1] |
425 @{thm actions_of_def[where ?s="s" and ?ths="ths", THEN eq_reflection]}. |
425 @{thm actions_of_def[where ?s="s" and ?ths="ths", THEN eq_reflection]}. |
426 \end{isabelle} |
426 \end{isabelle} |
427 |
427 |
428 \noindent |
428 \noindent |
429 where we use Isabelle's notation for list-comprehensions. This |
429 where we use Isabelle's notation for list-comprehensions. This |
430 notation is very similar to notation used in Haskell for list-comprehensions. |
430 notation is very similar to the notation used in Haskell for list-comprehensions. |
431 A \emph{precedence} of a thread @{text th} in a |
431 A \emph{precedence} of a thread @{text th} in a |
432 state @{text s} is the pair of natural numbers defined as |
432 state @{text s} is the pair of natural numbers defined as |
433 |
433 |
434 \begin{isabelle}\ \ \ \ \ %%% |
434 \begin{isabelle}\ \ \ \ \ %%% |
435 @{thm preced_def} |
435 @{thm preced_def} |
560 \caption{An instance of a Resource Allocation Graph (RAG).\label{RAGgraph}} |
560 \caption{An instance of a Resource Allocation Graph (RAG).\label{RAGgraph}} |
561 \end{figure} |
561 \end{figure} |
562 |
562 |
563 \noindent |
563 \noindent |
564 If there is no cycle, then every @{text RAG} can be pictured as a forest of trees, as |
564 If there is no cycle, then every @{text RAG} can be pictured as a forest of trees, as |
565 for example in Figure~\ref{RAGgraph}. |
565 for example in Fig.~\ref{RAGgraph}. |
566 |
566 |
567 Because of the @{text RAG}s, we will need to formalise some results |
567 Because of the @{text RAG}s, we will need to formalise some results |
568 about graphs. |
568 about graphs. |
569 It |
569 It |
570 seems for our purposes the most convenient representation of |
570 seems for our purposes the most convenient representation of |
607 @{thm ancestors_def[where ?r="rel" and ?x="node", THEN eq_reflection]}\\ |
607 @{thm ancestors_def[where ?r="rel" and ?x="node", THEN eq_reflection]}\\ |
608 \end{tabular}\\ |
608 \end{tabular}\\ |
609 \mbox{}\hfill\numbered{children} |
609 \mbox{}\hfill\numbered{children} |
610 \end{isabelle} |
610 \end{isabelle} |
611 |
611 |
612 \noindent Note that forests can have trees with infinte depth and |
612 \noindent Note that forests can have trees with infinite depth and |
613 containing nodes with infinitely many children. A \emph{finite |
613 containing nodes with infinitely many children. A \emph{finite |
614 forest} is a forest whose underlying relation is |
614 forest} is a forest whose underlying relation is |
615 well-founded\footnote{For \emph{well-founded} we use the quite natural |
615 well-founded\footnote{For \emph{well-founded} we use the quite natural |
616 definition from Isabelle/HOL.} |
616 definition from Isabelle/HOL.} |
617 and every node has finitely many children (is only finitely |
617 and every node has finitely many children (is only finitely |
650 \end{isabelle} |
650 \end{isabelle} |
651 |
651 |
652 \noindent This definition is the relation that one thread is waiting for |
652 \noindent This definition is the relation that one thread is waiting for |
653 another to release a resource, but the corresponding |
653 another to release a resource, but the corresponding |
654 resource is ``hidden''. |
654 resource is ``hidden''. |
655 In Figure~\ref{RAGgraph} this means the @{text TDG} connects |
655 In Fig.~\ref{RAGgraph} this means the @{text TDG} connects |
656 @{text "th\<^sub>1"} and @{text "th\<^sub>2"} to @{text "th\<^sub>0"}, which both wait for |
656 @{text "th\<^sub>1"} and @{text "th\<^sub>2"} to @{text "th\<^sub>0"}, which both wait for |
657 resource @{text "cs\<^sub>1"} to be released; and @{text "th\<^sub>3"} to @{text "th\<^sub>2"}, which |
657 resource @{text "cs\<^sub>1"} to be released; and @{text "th\<^sub>3"} to @{text "th\<^sub>2"}, which |
658 cannot make any progress unless @{text "th\<^sub>2"} makes progress. |
658 cannot make any progress unless @{text "th\<^sub>2"} makes progress. |
659 Similarly for the other threads. |
659 Similarly for the other threads. |
660 If |
660 If |
710 |
710 |
711 In the initial state, the scheduler starts with all resources unlocked (the corresponding |
711 In the initial state, the scheduler starts with all resources unlocked (the corresponding |
712 function is defined in \eqref{allunlocked}) and the |
712 function is defined in \eqref{allunlocked}) and the |
713 current precedence of every thread is initialised with @{term "Prc 0 0"}; that means |
713 current precedence of every thread is initialised with @{term "Prc 0 0"}; that means |
714 \mbox{@{abbrev initial_cprec}}. Therefore |
714 \mbox{@{abbrev initial_cprec}}. Therefore |
715 we have for the initial shedule state |
715 we have for the initial schedule state |
716 |
716 |
717 \begin{isabelle}\ \ \ \ \ %%% |
717 \begin{isabelle}\ \ \ \ \ %%% |
718 \begin{tabular}{@ {}l} |
718 \begin{tabular}{@ {}l} |
719 @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ |
719 @{thm (lhs) schs.simps(1)} @{text "\<equiv>"}\\ |
720 \hspace{5mm}@{term "(|wq_fun = all_unlocked, cprec_fun = (\<lambda>_::thread. Prc 0 0)|)"} |
720 \hspace{5mm}@{term "(|wq_fun = all_unlocked, cprec_fun = (\<lambda>_::thread. Prc 0 0)|)"} |
1242 %%%} |
1242 %%%} |
1243 |
1243 |
1244 % \endnote{{\bf OUTLINE} |
1244 % \endnote{{\bf OUTLINE} |
1245 |
1245 |
1246 % Since @{term "th"} is the most urgent thread, if it is somehow |
1246 % Since @{term "th"} is the most urgent thread, if it is somehow |
1247 % blocked, people want to know why and wether this blocking is |
1247 % blocked, people want to know why and whether this blocking is |
1248 % reasonable. |
1248 % reasonable. |
1249 |
1249 |
1250 % @{thm [source] th_blockedE} @{thm th_blockedE} |
1250 % @{thm [source] th_blockedE} @{thm th_blockedE} |
1251 |
1251 |
1252 % if @{term "th"} is blocked, then there is a path leading from |
1252 % if @{term "th"} is blocked, then there is a path leading from |
1340 % to @{term "preced th (t @ s)"}. |
1340 % to @{term "preced th (t @ s)"}. |
1341 |
1341 |
1342 %Let me distinguish between cp (current precedence) and assigned precedence (the precedence the |
1342 %Let me distinguish between cp (current precedence) and assigned precedence (the precedence the |
1343 %thread ``normally'' has). |
1343 %thread ``normally'' has). |
1344 %So we want to show what the cp of th' is in state t @ s. |
1344 %So we want to show what the cp of th' is in state t @ s. |
1345 %We look at all the assingned precedences in the subgraph starting from th' |
1345 %We look at all the assigned precedences in the subgraph starting from th' |
1346 %We are looking for the maximum of these assigned precedences. |
1346 %We are looking for the maximum of these assigned precedences. |
1347 %This subgraph must contain the thread th, which actually has the highest precednence |
1347 %This subgraph must contain the thread th, which actually has the highest precedence |
1348 %so cp of th' in t @ s has this (assigned) precedence of th |
1348 %so cp of th' in t @ s has this (assigned) precedence of th |
1349 %We know that cp (t @ s) th' |
1349 %We know that cp (t @ s) th' |
1350 %is the Maximum of the threads in the subgraph starting from th' |
1350 %is the Maximum of the threads in the subgraph starting from th' |
1351 %this happens to be the precedence of th |
1351 %this happens to be the precedence of th |
1352 %th has the highest precedence of all threads |
1352 %th has the highest precedence of all threads |
1431 % we have @{term "cp (s' @ s) th' < prec th (s' @ s)"}. |
1431 % we have @{term "cp (s' @ s) th' < prec th (s' @ s)"}. |
1432 % Since @{text "prec th (s' @ s)"} is already the highest |
1432 % Since @{text "prec th (s' @ s)"} is already the highest |
1433 % @{term "cp (s' @ s) th"} can not be higher than this and can not be lower either (by |
1433 % @{term "cp (s' @ s) th"} can not be higher than this and can not be lower either (by |
1434 % definition of @{term "cp"}). Consequently, we have @{term "prec th (s' @ s) = cp (s' @ s) th"}. |
1434 % definition of @{term "cp"}). Consequently, we have @{term "prec th (s' @ s) = cp (s' @ s) th"}. |
1435 % Finally we have @{term "cp (s' @ s) th' < cp (s' @ s) th"}. |
1435 % Finally we have @{term "cp (s' @ s) th' < cp (s' @ s) th"}. |
1436 % By defintion of @{text "running"}, @{text "th'"} can not be running in state |
1436 % By definition of @{text "running"}, @{text "th'"} can not be running in state |
1437 % @{text "s' @ s"}, as we had to show.\qed |
1437 % @{text "s' @ s"}, as we had to show.\qed |
1438 % \end{proof} |
1438 % \end{proof} |
1439 |
1439 |
1440 % \noindent |
1440 % \noindent |
1441 % Since @{text "th'"} is not able to run in state @{text "s' @ s"}, it is not able to |
1441 % Since @{text "th'"} is not able to run in state @{text "s' @ s"}, it is not able to |
1509 % thread does not hold any critical resource, therefore no thread can depend on it |
1509 % thread does not hold any critical resource, therefore no thread can depend on it |
1510 % (@{text "count_eq_dependants"}): |
1510 % (@{text "count_eq_dependants"}): |
1511 % @ {thm [display] count_eq_dependants} |
1511 % @ {thm [display] count_eq_dependants} |
1512 %\end{enumerate} |
1512 %\end{enumerate} |
1513 |
1513 |
1514 %The reason that only threads which already held some resoures |
1514 %The reason that only threads which already held some resources |
1515 %can be running and block @{text "th"} is that if , otherwise, one thread |
1515 %can be running and block @{text "th"} is that if , otherwise, one thread |
1516 %does not hold any resource, it may never have its prioirty raised |
1516 %does not hold any resource, it may never have its priority raised |
1517 %and will not get a chance to run. This fact is supported by |
1517 %and will not get a chance to run. This fact is supported by |
1518 %lemma @{text "moment_blocked"}: |
1518 %lemma @{text "moment_blocked"}: |
1519 %@ {thm [display] moment_blocked} |
1519 %@ {thm [display] moment_blocked} |
1520 %When instantiating @{text "i"} to @{text "0"}, the lemma means threads which did not hold any |
1520 %When instantiating @{text "i"} to @{text "0"}, the lemma means threads which did not hold any |
1521 %resource in state @{text "s"} will not have a change to run latter. Rephrased, it means |
1521 %resource in state @{text "s"} will not have a change to run latter. Rephrased, it means |
1577 %if every such thread can release all its resources in finite duration, then after finite |
1577 %if every such thread can release all its resources in finite duration, then after finite |
1578 %duration, none of them may block @{term "th"} anymore. So, no priority inversion may happen |
1578 %duration, none of them may block @{term "th"} anymore. So, no priority inversion may happen |
1579 %then. |
1579 %then. |
1580 |
1580 |
1581 % NOTE: about bounds in sha et al and ours: they prove a bound on the length of individual |
1581 % NOTE: about bounds in sha et al and ours: they prove a bound on the length of individual |
1582 % blocages. We prove a bound for the overall-blockage. |
1582 % blockages. We prove a bound for the overall-blockage. |
1583 |
1583 |
1584 % There are low priority threads, |
1584 % There are low priority threads, |
1585 % which do not hold any resources, |
1585 % which do not hold any resources, |
1586 % such thread will not block th. |
1586 % such thread will not block th. |
1587 % Their Theorem 3 does not exclude such threads. |
1587 % Their Theorem 3 does not exclude such threads. |
1588 |
1588 |
1589 % There are resources, which are not held by any low prioirty threads, |
1589 % There are resources, which are not held by any low priority threads, |
1590 % such resources can not cause blockage of th neither. And similiary, |
1590 % such resources can not cause blockage of th neither. And similiary, |
1591 % theorem 6 does not exlude them. |
1591 % theorem 6 does not exclude them. |
1592 |
1592 |
1593 % Our one bound excudle them by using a different formaulation. " |
1593 % Our one bound exclude them by using a different formulation. " |
1594 |
1594 |
1595 *} |
1595 *} |
1596 (*<*) |
1596 (*<*) |
1597 end |
1597 end |
1598 (*>*) |
1598 (*>*) |
1682 \begin{isabelle}\ \ \ \ \ %%% |
1682 \begin{isabelle}\ \ \ \ \ %%% |
1683 @{thm blockers_def[THEN eq_reflection]} |
1683 @{thm blockers_def[THEN eq_reflection]} |
1684 \end{isabelle} |
1684 \end{isabelle} |
1685 |
1685 |
1686 \noindent This set contains all threads that are not detached in |
1686 \noindent This set contains all threads that are not detached in |
1687 state @{text s}. According to our definiton of @{text "detached"}, |
1687 state @{text s}. According to our definition of @{text "detached"}, |
1688 this means a thread in @{text "blockers"} either holds or waits for |
1688 this means a thread in @{text "blockers"} either holds or waits for |
1689 some resource in state @{text s} . Our Thm.~1 implies that only |
1689 some resource in state @{text s} . Our Thm.~1 implies that only |
1690 these threads can all potentially block @{text th} after state |
1690 these threads can all potentially block @{text th} after state |
1691 @{text s}. We need to make the following assumption about the |
1691 @{text s}. We need to make the following assumption about the |
1692 threads in the @{text "blockers"}-set: |
1692 threads in the @{text "blockers"}-set: |
1835 \end{proof} |
1835 \end{proof} |
1836 |
1836 |
1837 \noindent This theorem is the main conclusion we obtain for the |
1837 \noindent This theorem is the main conclusion we obtain for the |
1838 Priority Inheritance Protocol. It is based on the fact that the set of |
1838 Priority Inheritance Protocol. It is based on the fact that the set of |
1839 @{text blockers} is fixed at state @{text s} when @{text th} becomes |
1839 @{text blockers} is fixed at state @{text s} when @{text th} becomes |
1840 the thread with highest priority. Then no additional blocker of |
1840 the thread with the highest priority. Then no additional blocker of |
1841 @{text th} can appear after the state @{text s}. And in this way we |
1841 @{text th} can appear after the state @{text s}. And in this way we |
1842 can bound the number of states where the thread @{text th} with the |
1842 can bound the number of states where the thread @{text th} with the |
1843 highest priority is prevented from running. |
1843 highest priority is prevented from running. |
1844 Our bound does not depend on the restriction of well-nested critical |
1844 Our bound does not depend on the restriction of well-nested critical |
1845 sections in the Priority Inheritance Protocol as imposed by Sha et al. |
1845 sections in the Priority Inheritance Protocol as imposed by Sha et al. |
1873 \noindent |
1873 \noindent |
1874 That means the current precedence of a thread @{text th} can be |
1874 That means the current precedence of a thread @{text th} can be |
1875 computed by considering the static precedence of @{text th} |
1875 computed by considering the static precedence of @{text th} |
1876 and |
1876 and |
1877 the current precedences of the children of @{text th}. Their |
1877 the current precedences of the children of @{text th}. Their |
1878 @{text "cprec"}s, in general, need to be computed by recursively decending into |
1878 @{text "cprec"}s, in general, need to be computed by recursively descending into |
1879 deeper ``levels'' of the @{text TDG}. |
1879 deeper ``levels'' of the @{text TDG}. |
1880 However, the current precedence of a thread @{text th}, say, |
1880 However, the current precedence of a thread @{text th}, say, |
1881 only needs to be recomputed when @{text "(i)"} its static |
1881 only needs to be recomputed when @{text "(i)"} its static |
1882 precedence is re-set or when @{text "(ii)"} one of |
1882 precedence is re-set or when @{text "(ii)"} one of |
1883 its children changes its current precedence or when @{text "(iii)"} the children set changes |
1883 its children changes its current precedence or when @{text "(iii)"} the children set changes |
1897 in response to each kind of events.\smallskip |
1897 in response to each kind of events.\smallskip |
1898 *} |
1898 *} |
1899 |
1899 |
1900 text {* |
1900 text {* |
1901 \noindent |
1901 \noindent |
1902 \colorbox{mygrey}{@{term "Create th prio"}:} We assume that the current state @{text s} and |
1902 \colorbox{mygrey}{@{term "Create th prio"}:} \\ We assume that the current state @{text s} and |
1903 the next state @{term "e#s"}, whereby \mbox{@{term "e \<equiv> Create th prio"}}, are both valid (meaning the event |
1903 the next state @{term "e#s"}, whereby \mbox{@{term "e \<equiv> Create th prio"}}, are both valid (meaning the event |
1904 @{text "Create"} is allowed to occur in @{text s}). In this situation we can show that |
1904 @{text "Create"} is allowed to occur in @{text s}). In this situation we can show that |
1905 |
1905 |
1906 \begin{isabelle}\ \ \ \ \ %%% |
1906 \begin{isabelle}\ \ \ \ \ %%% |
1907 \begin{tabular}{@ {}l} |
1907 \begin{tabular}{@ {}l} |
1918 \smallskip |
1918 \smallskip |
1919 *} |
1919 *} |
1920 |
1920 |
1921 text {* |
1921 text {* |
1922 \noindent |
1922 \noindent |
1923 \colorbox{mygrey}{@{term "Exit th"}:} We again assume that the current state @{text s} and |
1923 \colorbox{mygrey}{@{term "Exit th"}:}\\ We again assume that the current state @{text s} and |
1924 the next state @{term "e#s"}, whereby this time @{term "e \<equiv> Exit th"}, are both valid. We can show that |
1924 the next state @{term "e#s"}, whereby this time @{term "e \<equiv> Exit th"}, are both valid. We can show that |
1925 |
1925 |
1926 \begin{isabelle}\ \ \ \ \ %%% |
1926 \begin{isabelle}\ \ \ \ \ %%% |
1927 \begin{tabular}{@ {}l} |
1927 \begin{tabular}{@ {}l} |
1928 @{thm (concl) valid_trace_exit.RAG_es}, and\\ |
1928 @{thm (concl) valid_trace_exit.RAG_es}, and\\ |
1938 \smallskip |
1938 \smallskip |
1939 *} |
1939 *} |
1940 |
1940 |
1941 text {* |
1941 text {* |
1942 \noindent |
1942 \noindent |
1943 \colorbox{mygrey}{@{term "Set th prio"}:} We assume that @{text s} and |
1943 \colorbox{mygrey}{@{term "Set th prio"}:}\\ We assume that @{text s} and |
1944 @{term "e#s"} with @{term "e \<equiv> Set th prio"} are both valid. We can show that |
1944 @{term "e#s"} with @{term "e \<equiv> Set th prio"} are both valid. We can show that |
1945 |
1945 |
1946 \begin{isabelle}\ \ \ \ \ %%% |
1946 \begin{isabelle}\ \ \ \ \ %%% |
1947 \begin{tabular}{@ {}l} |
1947 \begin{tabular}{@ {}l} |
1948 @{thm (concl) valid_trace_set.RAG_es}, and\\ |
1948 @{thm (concl) valid_trace_set.RAG_es}, and\\ |
1987 \smallskip |
1987 \smallskip |
1988 *} |
1988 *} |
1989 |
1989 |
1990 text {* |
1990 text {* |
1991 \noindent |
1991 \noindent |
1992 \colorbox{mygrey}{@{term "V th cs"}:} We assume that @{text s} and |
1992 \colorbox{mygrey}{@{term "V th cs"}:}\\ We assume that @{text s} and |
1993 @{term "e#s"} with @{text e} being @{term "V th cs"} are both valid. |
1993 @{term "e#s"} with @{text e} being @{term "V th cs"} are both valid. |
1994 We have to consider two |
1994 We have to consider two |
1995 subcases: one where there is a thread to ``take over'' the released |
1995 subcases: one where there is a thread to ``take over'' the released |
1996 resource @{text cs}, and one where there is not. Let us consider them |
1996 resource @{text cs}, and one where there is not. Let us consider them |
1997 in turn. Suppose in state @{text s}, the thread @{text th'} takes over |
1997 in turn. Suppose in state @{text s}, the thread @{text th'} takes over |
2055 \end{isabelle} |
2055 \end{isabelle} |
2056 *} |
2056 *} |
2057 |
2057 |
2058 text {* |
2058 text {* |
2059 \noindent |
2059 \noindent |
2060 \colorbox{mygrey}{@{term "P th cs"}:} We assume that @{text s} and |
2060 \colorbox{mygrey}{@{term "P th cs"}:}\\ We assume that @{text s} and |
2061 @{term "e#s"} with @{term "e \<equiv> P th cs"} are both valid. |
2061 @{term "e#s"} with @{term "e \<equiv> P th cs"} are both valid. |
2062 We again have to analyse two subcases, namely |
2062 We again have to analyse two subcases, namely |
2063 the one where @{text cs} is not locked, and one where it is. We |
2063 the one where @{text cs} is not locked, and one where it is. We |
2064 treat the former case |
2064 treat the former case |
2065 first by showing that |
2065 first by showing that |
2073 |
2073 |
2074 \noindent This means we need to add a holding edge to the @{text |
2074 \noindent This means we need to add a holding edge to the @{text |
2075 RAG}. However, note that while the @{text RAG} changes the corresponding |
2075 RAG}. However, note that while the @{text RAG} changes the corresponding |
2076 @{text TDG} does not change. Together with the fact that the |
2076 @{text TDG} does not change. Together with the fact that the |
2077 precedences of all threads are unchanged, no @{text cprec} value is |
2077 precedences of all threads are unchanged, no @{text cprec} value is |
2078 changed. Therefore, no recalucation of the @{text cprec} value |
2078 changed. Therefore, no recalculation of the @{text cprec} value |
2079 of any thread @{text "th''"} is needed. |
2079 of any thread @{text "th''"} is needed. |
2080 |
2080 |
2081 *} |
2081 *} |
2082 |
2082 |
2083 text {* |
2083 text {* |
2098 @{text th} we need |
2098 @{text th} we need |
2099 to follow the edges in the @{text TDG} and recompute the @{term |
2099 to follow the edges in the @{text TDG} and recompute the @{term |
2100 "cprecs"}. Whereas in all other event we might have to make |
2100 "cprecs"}. Whereas in all other event we might have to make |
2101 modifications to the @{text "RAG"}, no recalculation of @{text |
2101 modifications to the @{text "RAG"}, no recalculation of @{text |
2102 cprec} depends on the @{text RAG}. This is the only case where |
2102 cprec} depends on the @{text RAG}. This is the only case where |
2103 the recalulation needs to take the connections in the @{text RAG} into |
2103 the recalculation needs to take the connections in the @{text RAG} into |
2104 account. |
2104 account. |
2105 To do this we can start from @{term "th"} and follow the |
2105 To do this we can start from @{term "th"} and follow the |
2106 @{term "children"}-edges to recompute the @{term "cp"} of every |
2106 @{term "children"}-edges to recompute the @{term "cp"} of every |
2107 thread encountered on the way using Lemma~\ref{childrenlem}. |
2107 thread encountered on the way using Lemma~\ref{childrenlem}. |
2108 This means the recomputation can be done locally (level-by-level) |
2108 This means the recomputation can be done locally (level-by-level) |
2174 in a queue. Both functions take an extra argument that specifies the |
2174 in a queue. Both functions take an extra argument that specifies the |
2175 comparison function used for organising the priority queue. |
2175 comparison function used for organising the priority queue. |
2176 |
2176 |
2177 Apart from having to implement relatively complex data\-structures in C |
2177 Apart from having to implement relatively complex data\-structures in C |
2178 using pointers, our experience with the implementation has been very positive: our specification |
2178 using pointers, our experience with the implementation has been very positive: our specification |
2179 and formalisation of PIP translates smoothly to an efficent implementation in PINTOS. |
2179 and formalisation of PIP translates smoothly to an efficient implementation in PINTOS. |
2180 Let us illustrate this with the C-code for the function @{ML_text "lock_acquire"}, |
2180 Let us illustrate this with the C-code for the function @{ML_text "lock_acquire"}, |
2181 shown in Figure~\ref{code}. This function implements the operation of requesting and, if free, |
2181 shown in Figure~\ref{code}. This function implements the operation of requesting and, if free, |
2182 locking of a resource by the current running thread. The convention in the PINTOS |
2182 locking of a resource by the current running thread. The convention in the PINTOS |
2183 code is to use the terminology \emph{locks} rather than resources. |
2183 code is to use the terminology \emph{locks} rather than resources. |
2184 A lock is represented as a pointer to the structure {\tt lock} (Line 1). |
2184 A lock is represented as a pointer to the structure {\tt lock} (Line 1). |
2275 the lock (Line 28), and finally update the queue of locks the current |
2275 the lock (Line 28), and finally update the queue of locks the current |
2276 thread already possesses (Line 29). |
2276 thread already possesses (Line 29). |
2277 The very last step is to enable interrupts again thus leaving the protected section. |
2277 The very last step is to enable interrupts again thus leaving the protected section. |
2278 |
2278 |
2279 |
2279 |
2280 Similar operations need to be implementated for the @{ML_text lock_release} function, which |
2280 Similar operations need to be implemented for the @{ML_text lock_release} function, which |
2281 we however do not show. The reader should note though that we did \emph{not} verify our C-code. |
2281 we however do not show. The reader should note though that we did \emph{not} verify our C-code. |
2282 This is in contrast, for example, to the work on seL4, which actually verified in Isabelle/HOL |
2282 This is in contrast, for example, to the work on seL4, which actually verified in Isabelle/HOL |
2283 that their C-code satisfies its specification, though this specification does not contain |
2283 that their C-code satisfies its specification, though this specification does not contain |
2284 anything about PIP \cite{sel4}. |
2284 anything about PIP \cite{sel4}. |
2285 Our verification of PIP however provided us with (formally proven) insights on how to design |
2285 Our verification of PIP however provided us with (formally proven) insights on how to design |
2314 explain how to use various implementations of PIP and abstractly |
2314 explain how to use various implementations of PIP and abstractly |
2315 discuss their properties, but surprisingly lack most details important for a |
2315 discuss their properties, but surprisingly lack most details important for a |
2316 programmer who wants to implement PIP (similarly Sha et al.~\cite{Sha90}). |
2316 programmer who wants to implement PIP (similarly Sha et al.~\cite{Sha90}). |
2317 That this is an issue in practice is illustrated by the |
2317 That this is an issue in practice is illustrated by the |
2318 email from Baker we cited in the Introduction. We achieved also this |
2318 email from Baker we cited in the Introduction. We achieved also this |
2319 goal: The formalisation allowed us to efficently implement our version |
2319 goal: The formalisation allowed us to efficiently implement our version |
2320 of PIP on top of PINTOS, a simple instructional operating system for the x86 |
2320 of PIP on top of PINTOS, a simple instructional operating system for the x86 |
2321 architecture implemented by Pfaff \cite{PINTOS}. It also gives the first author enough data to enable |
2321 architecture implemented by Pfaff \cite{PINTOS}. It also gives the first author enough data to enable |
2322 his undergraduate students to implement PIP (as part of their OS course). |
2322 his undergraduate students to implement PIP (as part of their OS course). |
2323 A byproduct of our formalisation effort is that nearly all |
2323 A byproduct of our formalisation effort is that nearly all |
2324 design choices for the implementation of PIP scheduler are backed up with a proved |
2324 design choices for the implementation of PIP scheduler are backed up with a proved |