1619 s}. Otherwise our PIP scheduler could be ``swamped'' with @{text |
1620 s}. Otherwise our PIP scheduler could be ``swamped'' with @{text |
1620 "Create"}-requests. So our first assumption states: |
1621 "Create"}-requests. So our first assumption states: |
1621 |
1622 |
1622 \begin{quote} {\bf Assumption on the number of threads created |
1623 \begin{quote} {\bf Assumption on the number of threads created |
1623 after the state {\boldmath@{text s}}:} Given the |
1624 after the state {\boldmath@{text s}}:} Given the |
1624 state @{text s}, in every ``future'' valid state @{text "t @ s"}, we |
1625 state @{text s}, in every ``future'' valid state @{text "es @ s"}, we |
1625 require that the number of created threads is less than |
1626 require that the number of created threads is less than |
1626 a bound @{text "BC"}, that is |
1627 a bound @{text "BC"}, that is |
1627 |
1628 |
1628 \[@{text "len (filter isCreate t) < BC"}\;.\] |
1629 \[@{text "len (filter isCreate es) < BC"}\;\] |
|
1630 |
|
1631 wherby @{text es} is a list of events. |
1629 \end{quote} |
1632 \end{quote} |
1630 |
1633 |
1631 \noindent Note that it is not enough to just to state that there are |
1634 \noindent Note that it is not enough to just to state that there are |
1632 only finite number of threads created up until a single state @{text |
1635 only finite number of threads created up until a single state @{text |
1633 "s' @ s"} after @{text s}. Instead, we need to put this bound on |
1636 "s' @ s"} after @{text s}. Instead, we need to put this bound on |
1634 the @{text "Create"} events for all valid states after @{text s}. |
1637 the @{text "Create"} events for all valid states after @{text s}. |
1635 This ensures that no matter which ``future'' state is reached, the number |
1638 This ensures that no matter which ``future'' state is reached, the |
1636 of @{text "Create"}-events is finite. |
1639 number of @{text "Create"}-events is finite. We use @{text "es @ s"} |
|
1640 to stand for \emph{future states} after @{text s}---it is @{text s} |
|
1641 extended with some list of events. |
1637 |
1642 |
1638 For our second assumption about giving up resources after a finite |
1643 For our second assumption about giving up resources after a finite |
1639 amount of ``time'', let us introduce the following definition about |
1644 amount of ``time'', let us introduce the following definition about |
1640 threads that can potentially block @{text th}: |
1645 threads that can potentially block @{text th}: |
1641 |
1646 |
1652 |
1657 |
1653 \begin{quote} |
1658 \begin{quote} |
1654 {\bf Assumptions on the threads {\boldmath{@{term "th' \<in> blockers"}}}:} |
1659 {\bf Assumptions on the threads {\boldmath{@{term "th' \<in> blockers"}}}:} |
1655 For each such @{text "th'"} there exists a finite bound @{text "BND(th')"} |
1660 For each such @{text "th'"} there exists a finite bound @{text "BND(th')"} |
1656 such that for all future |
1661 such that for all future |
1657 valid states @{text "t @ s"}, |
1662 valid states @{text "es @ s"}, |
1658 we have that if \mbox{@{term "\<not>(detached (t @ s) th')"}}, then |
1663 we have that if \mbox{@{term "\<not>(detached (es @ s) th')"}}, then |
1659 \[@{text "len (actions_of {th'} t) < BND(th')"}\] |
1664 \[@{text "len (actions_of {th'} es) < BND(th')"}\] |
1660 \end{quote} |
1665 \end{quote} |
1661 |
1666 |
1662 \noindent By this assumption we enforce that any thread potentially |
1667 \noindent By this assumption we enforce that any thread potentially |
1663 blocking @{term th} must become detached (that is lock no resource |
1668 blocking @{term th} must become detached (that is lock no resource |
1664 anymore) after a finite number of events in @{text "t @ s"}. Again |
1669 anymore) after a finite number of events in @{text "es @ s"}. Again |
1665 we have to state this bound to hold in all valid states after @{text |
1670 we have to state this bound to hold in all valid states after @{text |
1666 s}. The bound reflects how each thread @{text "th'"} is programmed: |
1671 s}. The bound reflects how each thread @{text "th'"} is programmed: |
1667 Though we cannot express what instructions a thread is executing, |
1672 Though we cannot express what instructions a thread is executing, |
1668 the events in our model correspond to the system calls made by |
1673 the events in our model correspond to the system calls made by |
1669 thread. Our @{text "BND(th')"} binds the number of these ``calls''. |
1674 thread. Our @{text "BND(th')"} binds the number of these ``calls''. |
1673 @{text th} is not running (that is where Priority Inversion occurs) |
1678 @{text th} is not running (that is where Priority Inversion occurs) |
1674 can be bounded by the number of actions the threads in @{text |
1679 can be bounded by the number of actions the threads in @{text |
1675 blockers} perform and how many threads are newly created. To state |
1680 blockers} perform and how many threads are newly created. To state |
1676 our bound formally, we need to make a definition of what we mean by |
1681 our bound formally, we need to make a definition of what we mean by |
1677 intermediate states; it will be the list of states starting from |
1682 intermediate states; it will be the list of states starting from |
1678 @{text s} upto the state @{text "t @ s"}. For example, suppose |
1683 @{text s} upto the state @{text "es @ s"}. For example, suppose |
1679 $\textit{t} = [\textit{e}_n, \textit{e}_{n-1}, \ldots, \textit{e}_2, |
1684 $\textit{es} = [\textit{e}_n, \textit{e}_{n-1}, \ldots, \textit{e}_2, |
1680 \textit{e}_1]$, then the intermediate states from @{text s} upto |
1685 \textit{e}_1]$, then the intermediate states from @{text s} upto |
1681 @{text "t @ s"} are |
1686 @{text "es @ s"} are |
1682 |
1687 |
1683 \begin{center} |
1688 \begin{center} |
1684 \begin{tabular}{l} |
1689 \begin{tabular}{l} |
1685 $\textit{s}$\\ |
1690 $\textit{s}$\\ |
1686 $\textit{e}_1 :: \textit{s}$\\ |
1691 $\textit{e}_1 :: \textit{s}$\\ |
1695 the following recursive function |
1700 the following recursive function |
1696 |
1701 |
1697 \begin{center} |
1702 \begin{center} |
1698 \begin{tabular}{lcl} |
1703 \begin{tabular}{lcl} |
1699 @{text "s upto []"} & $\dn$ & $[]$\\ |
1704 @{text "s upto []"} & $\dn$ & $[]$\\ |
1700 @{text "s upto (e::es)"} & $\dn$ & @{text "(es @ s) :: s upto es"} |
1705 @{text "s upto (_::es)"} & $\dn$ & @{text "(es @ s) :: s upto es"} |
1701 \end{tabular} |
1706 \end{tabular} |
1702 \end{center} |
1707 \end{center} |
1703 |
1708 |
1704 |
1709 \noindent |
1705 \noindent Assume you have an extension @{text t}, this essentially |
1710 Our theorem can then be stated as follows: |
1706 defines in out list representation of states all the postfixes of |
|
1707 @{text t}. |
|
1708 |
1711 |
1709 \begin{theorem} |
1712 \begin{theorem} |
1710 Given our assumptions about bounds, we have that |
1713 Given our assumptions about bounds, we have that |
1711 |
1714 |
1712 \[ |
1715 \[ |
1713 @{text "len"}\,[@{text "s'"} |
1716 @{text "len"}\,[@{text "s'"} |
1714 \leftarrow @{text "s upto t"}.\;\; @{text "th"} \not\in @{text "running s'"}] \leq 1 + |
1717 \leftarrow @{text "s upto es"}.\;\; @{text "th"} \not\in @{text "running s'"}] \;\;\leq\;\; |
|
1718 @{text "BC"} + \sum @{text "th'"} \in @{text "blockers"}.\;\; @{text "BND(th')"}\;. |
1715 \] |
1719 \] |
1716 |
1720 |
1717 \[@{thm bounded_extend_highest.priority_inversion_is_finite_upto}\] |
|
1718 \end{theorem} |
1721 \end{theorem} |
1719 |
1722 |
1720 |
1723 \begin{proof} There are two characterisations for the number of |
1721 Theorem: |
1724 events in @{text es}: First, for each corresponding state in @{text |
1722 |
1725 "s upto es"}, either @{text th} is running or not running. That |
1723 \begin{isabelle}\ \ \ \ \ %%% |
1726 means |
1724 @{text "len (filter (\<lambda>t'. th \<notin> running t') (s upto t)) \<le> |
1727 |
1725 1 + len (actions_of blockers t) + len (filter isCreate t)"} |
1728 \begin{equation}\label{firsteq} |
1726 \end{isabelle} |
1729 @{text "len es"} = |
1727 |
1730 @{text len} [@{text "s'"} \leftarrow @{text "s upto es"}.\;\; @{text "th"} \in @{text "running s'"}] + |
1728 Proof: |
1731 @{text len} [@{text "s'"} \leftarrow @{text "s upto es"}.\;\; @{text "th"} \not\in @{text "running s'"}] |
1729 |
1732 \end{equation} |
1730 Consider the states @{text "s upto t"}. It holds that all the states where |
1733 |
1731 @{text "th"} runs and all the states where @{text "th"} does not run is |
1734 \noindent Second by Thm~\ref{mainthm}, the events are either the |
1732 equalt to @{text "len t"}. That means |
1735 actions of @{text th} or @{text "Create"}-events or actions of the |
1733 |
1736 threads in blockers. That is |
1734 \begin{center} |
1737 |
1735 @{text "states where th does not run = len t - states where th runs"} (*) |
1738 \begin{equation}\label{secondeq} |
1736 \end{center} |
1739 @{text "len es"} = @{text "len (actions_of {th} es)"} + |
1737 |
1740 @{text "len (filter isCreate es)"} + |
1738 It also holds that all the actions of @{text "th"} are less or equal to |
1741 @{text "len (actions_of blockers es)"} |
1739 the states where @{text th} runs. That is |
1742 \end{equation} |
1740 |
1743 |
1741 \begin{center} |
1744 \noindent |
1742 @{text "len (actions_of {th} t) \<le> states where th runs"} |
1745 Further we know that an action of @{text th} can only be taken when @{text th} is running. Therefore |
1743 \end{center} |
1746 |
1744 |
1747 \[ |
1745 That means in $(*)$ we have |
1748 @{text "len (actions_of {th} es)"} \leq |
1746 |
1749 @{text len} [@{text "s'"} \leftarrow @{text "s upto es"}.\;\; @{text "th"} \in @{text "running s'"}] |
1747 \begin{center} |
1750 \] |
1748 @{text "states where th does not run \<le> len t - len (actions_of {th} t)"} |
1751 |
1749 \end{center} |
1752 \noindent Substituting this into \eqref{firsteq} gives |
1750 |
1753 |
1751 If we look at all the events that can occur in @{text "s upto t"}, we have that |
1754 \[ |
1752 |
1755 @{text len} [@{text "s'"} \leftarrow @{text "s upto es"}.\;\; @{text "th"} \not\in @{text "running s'"}] |
1753 \begin{center} |
1756 \leq @{text "len es"} - @{text "len (actions_of {th} es)"} |
1754 @{text "len t = len (action_of {th}) + len (action_of blockers t) + |
1757 \] |
1755 len (filter isCreate t)"} |
1758 |
1756 \end{center} |
1759 into which we can substitute \eqref{secondeq} yielding |
1757 |
1760 |
1758 This gives us finally our theorem. \hfill\qed\medskip |
1761 \[ |
1759 |
1762 @{text len} [@{text "s'"} \leftarrow @{text "s upto es"}.\;\; @{text "th"} \not\in @{text "running s'"}] \leq |
1760 \noindent In order to now show the absence of indefinite Priority |
1763 @{text "len (filter isCreate es)"} + @{text "len (actions_of blockers es)"} |
1761 Inversion, we need to show that the number of actions of the @{text |
1764 \] |
1762 "blockers"} is bounded---the number of @{text "Creates"} is clearly |
1765 |
1763 bounded by our first assumption. The number of actions of each |
1766 \noindent By our first assumption we know that the @{text |
1764 individual thread in @{text "blockers"} is bound by our second |
1767 "Create"}-events are bounded by the bound @{text BC}. By our second |
1765 assumption. Since there can only be a finite number of @{text |
1768 assumption we can prove that the actions of all blockers is bounded |
1766 blockers} in state @{text s} their overall sum is also bounded. |
1769 by the sum of bounds of the individual blocking threads, that is |
1767 This is actually the main conclusion we obtain for the Priority |
1770 |
1768 Inheritance Protocol: this above theorem shows is that set of @{text |
1771 \[ |
1769 blockers} is fixed at state @{text s} when the Priority Inversion |
1772 @{text "len (actions_of blockers es)"} \;\;\leq\;\; |
1770 occured and no additional blocker of @{text th} can appear after the |
1773 \sum @{text "th'"} \in @{text "blockers"}.\;\; @{text "BND(th')"} |
1771 state @{text s}. And in this way we can bound the number of states |
1774 \] |
1772 where the thread @{text th} with the highest priority is prevented |
1775 |
1773 fropm running. |
1776 \noindent With this in place we can conclude our theorem.\hfill\qed |
1774 |
1777 \end{proof} |
1775 |
1778 |
|
1779 \noindent This theorem is the main conclusion we obtain for the |
|
1780 Priority Inheritance Protocol: it shows that set of @{text blockers} |
|
1781 is fixed at state @{text s} when @{text th} becomes the thread with |
|
1782 highest priority. Then no additional blocker of @{text th} can |
|
1783 appear after the state @{text s}. And in this way we can bound the |
|
1784 number of states where the thread @{text th} with the highest |
|
1785 priority is prevented from running. |
1776 *} |
1786 *} |
1777 (*<*) |
1787 (*<*) |
1778 end |
1788 end |
1779 (*>*) |
1789 (*>*) |
1780 |
1790 |