<!–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()
–>
<I>mpres</I><IMG
STYLE="height: 196.25ex; vertical-align: -0.12ex; " SRC="img11.png"
ALT="
">()) and give or release
(<!– MATH
mpres
()
–>
<I>mpres</I><IMG
STYLE="height: 2.17ex; vertical-align: 177.13ex; " SRC="img12.png"
ALT="
">()) a source of a resource; they are implemented directly
with <!– MATH
mptsk
()
–>
<I>mptsk</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img13.png"
ALT="
">() and <!– MATH
mptsk
()
–>
<I>mptsk</I><IMG
STYLE="height: 2.17ex; vertical-align: 177.13ex; " SRC="img12.png"
ALT="
">(). 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="
<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
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.10ex; " SRC="img15.png"
ALT="
">. With memory contention management, we
can finally write a one-argument <!– MATH
mpthd
()
–>
<I>mpthd</I><IMG
STYLE="height: 38.40ex; vertical-align: 134.33ex; " SRC="img16.png"
ALT="
">():
<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()
–>
<I>mpres</I><IMG
STYLE="height: 1.54ex; vertical-align: 177.76ex; " SRC="img17.png"
ALT="
">()). 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
–>
<I>mpres</I><IMG
STYLE="height: 1.61ex; vertical-align: 177.62ex; " SRC="img18.png"
ALT="
">,
<!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img19.png"
ALT="
">, and <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img20.png"
ALT="
">. On the middle component level
are standard operating system components: <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.10ex; " SRC="img21.png"
ALT="
">,
<!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img22.png"
ALT="
">, <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 2.17ex; vertical-align: 177.13ex; " SRC="img23.png"
ALT="
"> and <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img24.png"
ALT="
">. And on
the low device level are standard devices: <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img25.png"
ALT="
">,
<!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.10ex; " SRC="img26.png"
ALT="
">, <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.55ex; " SRC="img27.png"
ALT="
">, <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 2.17ex; vertical-align: 176.68ex; " SRC="img28.png"
ALT="
">, <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 1.68ex; vertical-align: 177.10ex; " SRC="img29.png"
ALT="
">,
and <!– MATH
mpres
–>
<I>mpres</I><IMG
STYLE="height: 2.03ex; vertical-align: 177.20ex; " SRC="img30.png"
ALT="
">. 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>