<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//en">

<!–Converted with LaTeX2HTML 2022 (Released January 1, 2022) –> <HTML lang="en"> <HEAD> <TITLE>Contents of Contention Management</TITLE>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <META NAME="viewport" CONTENT="width=device-width, initial-scale=1.0"> <META NAME="Generator" CONTENT="LaTeX2HTML v2022">

<LINK REL="STYLESHEET" HREF="MPTSK.css">

<LINK REL="next" HREF="node16_mn.html"> <LINK REL="previous" HREF="node14_mn.html"> <LINK REL="up" HREF="node14_mn.html"> <LINK REL="next" HREF="node16_mn.html"> </HEAD>

<BODY bgcolor="#ffffff" text="#000000" link="#9944EE" vlink="#0000ff" alink="#00ff00">

<H3><A ID="SECTION00045100000000000000"> Contention Management</A> </H3>

<P> MPRES introduces the resource and source datatypes. The resource is merely a mailbox datatype, used for storing the available sources of the resource as messages. The source datatype is a message with two extra fields. The first specifies the task which owns the source (or NIL if none) and the second is a double-pointer structure (same as the <I>mpmsg</I> header) which keeps all the sources of a resource in a ring. Operations are provided to take (<!– MATH mpres$\_take$() –> <I>mpres</I><IMG STYLE="height: 196.25ex; vertical-align: -0.12ex; " SRC="img11.png" ALT="$\_take$">()) and give or release (<!– MATH mpres$\_recv$() –> <I>mpres</I><IMG STYLE="height: 2.17ex; vertical-align: 177.13ex; " SRC="img12.png" ALT="$\_recv$">()) a source of a resource; they are implemented directly with <!– MATH mptsk$\_send$() –> <I>mptsk</I><IMG STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img13.png" ALT="$\_send$">() and <!– MATH mptsk$\_recv$() –> <I>mptsk</I><IMG STYLE="height: 2.17ex; vertical-align: 177.13ex; " SRC="img12.png" ALT="$\_recv$">(). Additional operations are provided to initialize a resource of a particular type, and to deinitialize it (see MAN page for exact details).

<P>

<DIV class="CENTER"><A ID="145"></A> <TABLE> <CAPTION class="BOTTOM"><STRONG>Figure:</STRONG> MPRES: Resource Datatype Internals</CAPTION> <TR><TD><IMG STYLE="height: 314.00ex; " SRC="img14.png" ALT="

\begin{figure}\par
\begin{verbatim}Message Header (for message manageme...
...urce
/
Task (if any) which Owns the Resource\end{verbatim}
\par
\end{figure}
"></TD></TR> </TABLE> </DIV>

<P> The two fields allow all sources (and users) of a resource to be located. Though this feature is not taken advantage of, it could be useful for reclaiming resources from crashed or discourteous tasks. By incorporating the knowledge gained from the waitingfor and owns field of tasks, its also possible to detect deadlock (a cycle of tasks waiting endlessly for each other) before it occurs; when a task is about to be suspended waitingfor a resource, it first checks if any other tasks which have the resource are directly or indirectly already waitingfor it. Because this check potentially involves a great deal of searching for every access to a resource, it is not implemented, but could be, if deadlock is a serious problem. (Nevertheless, users of Mailbox should beware of the base case of deadlock, where a task requests a resource that it already has.)

<P> The MPRES layer defines a few general resources. The most universal resource is <!– MATH mpres$\_memory$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.10ex; " SRC="img15.png" ALT="$\_memory$">. With memory contention management, we can finally write a one-argument <!– MATH mpthd$\_init$() –> <I>mpthd</I><IMG STYLE="height: 38.40ex; vertical-align: 134.33ex; " SRC="img16.png" ALT="$\_init$">():

<P> <PRE>

MPTHDID mpthd_create(MPTHDFN mpthdfn) int mydeftasksize= mpthd_mydef(mpdef_tasksize,int); MPTHDID mpthd;

mpres_take(mpres_memory); /* CLAIM MEMORY RESOURCE */ mpthd= (MPTHDID)malloc(mydeftasksize); mpres_give(mpres_memory); /* RELEASE MEMORY RESOURCE */

if (mpthd) mpthd_init(mpthd,mydeftasksize,mpthdfn); return(mpthd); </PRE>

<P> Notice how the resource must be claimed and released around the standard <I>malloc</I> memory allocation call. This insures no other task can allocate memory at the same time. Likewise protection must be taken around the <I>free</I> memory deallocation call and other memory management calls. In general, <EM>every ``C'' function which accesses resources must be executed within an appropriate resource lock.</EM> This is true for any concurrent system. To make the job easier, the MPRES package defines a macro which takes as arguments a resource and a block of code; it claims the resource, executes the code, then (remembers to) free the resource before exiting. MPRES also duplicates many of the common ``C'' function calls with this extra locking added (eg, <!– MATH mpres$\_malloc$() –> <I>mpres</I><IMG STYLE="height: 1.54ex; vertical-align: 177.76ex; " SRC="img17.png" ALT="$\_malloc$">()). Operations such as <I>malloc</I>(), which are completed in a single transaction, are well suited for this; in contrast, operations as <I>printf</I> usually require several calls (``or the'' ``Hello'' ``output may not stick'' ``Goodbye'' ``together''), and are best locked explicitly by the caller. Explicit locking is also necessary when calling (library) functions which use resources and are unaware they are executing in a concurrent environment.

<P> One way to simplify the complexities of having to lock and unlock resources is to assume a uniprocessor environment (often the case) and have tasks only yield control explicitly, when they are not holding resources. This may be an acceptable compromise in many circumstances, and Mailbox allows for this style of programming.

<P> MPRES also provides three levels of I/O <B>locking granularity</B>. On the high stream level are the standard streams: <!– MATH mpres$\_stdin$ –> <I>mpres</I><IMG STYLE="height: 1.61ex; vertical-align: 177.62ex; " SRC="img18.png" ALT="$\_stdin$">, <!– MATH mpres$\_stdout$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img19.png" ALT="$\_stdout$">, and <!– MATH mpres$\_stderr$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img20.png" ALT="$\_stderr$">. On the middle component level are standard operating system components: <!– MATH mpres$\_filesystem$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.10ex; " SRC="img21.png" ALT=" $\_filesystem$">, <!– MATH mpres$\_network$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img22.png" ALT="$\_network$">, <!– MATH mpres$\_terminalin$ –> <I>mpres</I><IMG STYLE="height: 2.17ex; vertical-align: 177.13ex; " SRC="img23.png" ALT=" $\_terminalin$"> and <!– MATH mpres$\_terminalout$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img24.png" ALT=" $\_terminalout$">. And on the low device level are standard devices: <!– MATH mpres$\_harddisk$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img25.png" ALT=" $\_harddisk$">, <!– MATH mpres$\_floppydisk$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.10ex; " SRC="img26.png" ALT=" $\_floppydisk$">, <!– MATH mpres$\_modem$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img27.png" ALT="$\_modem$">, <!– MATH mpres$\_printer$ –> <I>mpres</I><IMG STYLE="height: 2.17ex; vertical-align: 176.68ex; " SRC="img28.png" ALT="$\_printer$">, <!– MATH mpres$\_parallel$ –> <I>mpres</I><IMG STYLE="height: 1.68ex; vertical-align: 177.10ex; " SRC="img29.png" ALT=" $\_parallel$">, and <!– MATH mpres$\_serial$ –> <I>mpres</I><IMG STYLE="height: 2.03ex; vertical-align: 177.20ex; " SRC="img30.png" ALT="$\_serial$">. Locking at a lower granularity level allows for higher degree of concurrency at a cost of complexity and portability. These locking levels are likely to be incomplete and to overlap; more than anything else, they are merely suggested names for resources and their locks. It is up to the programmer to tailor the locking appropriate to his environment and task.

<P>

<HR>

</BODY> </HTML>