Welcome
» NERWous C
» Mel
Mixed LIST Zones
Now that we have got to know individually both the mel reader zones and writer zones, it is time to mix them up, by requesting both of them.
Let's start with this combination of a mel read and mel write, where we are transferring the value from one mel variable to another:
Checkout Operation
The checkout for a mixed zone can take many forms.
Default Checkout
If there is no explicit
The default checkout behavior can be customized for each mel zone wait:
Explicit Checkout
The default checkout behaviors will be overridden if the
The explicit
Mixed AND Zones
Let's get back to VERSION 2. There we used the LIST comma (
Mixed OR Zones
Mixed zones can also support the OR zone waits:
If the
Previous Next Top
Mixed LIST Zones
Now that we have got to know individually both the mel reader zones and writer zones, it is time to mix them up, by requesting both of them.
Let's start with this combination of a mel read and mel write, where we are transferring the value from one mel variable to another:
/* VERSION 1 */
<mel> int a, b;
<?>b = <?>a;
We now change the code to make use of exclusive zones. We enter such a zone with the mel variable a
on the reader side, and the mel variable b
on the writer side:
/* VERSION 2 */
<?reader> a, <?writer> b {
b = a;
}
The mode reader
for the mel variable a
zone wait is optional and can be omitted, although having an explicit reader
visually counter-balances the mode writer
which is required for the b
writer zone wait:
/* VERSION 3 - compact but looks visually "unbalanced" */
<?> a, <?writer> b {
b = a;
}
This is the behind-the-scene process:
- The task puts itself onto the mel variable
a
's reader queue, and onto the mel variableb
's writer queue.
- On
a
's reader queue, whenever the mel reader zone conditions are satisfied, the task will hold on toa
, preventing other reader tasks to read froma
, even if there are values to be read in the mel buffera
. The task now has exclusive read access toa
.
- On
b
's writer queue, whenever the mel writer zone conditions are satisfied, the task holds on tob
, preventing other writer tasks to write tob
, even if there are empty slots in the mel bufferb
to receive the writings. The task now has exclusive write access tob
.
- Once the task gets hold of both the required mels, the task checks into the mixed exclusive zone.
- In the exclusive zone, the task uses the local eponymous variables,
a
andb
. The local eponymous variablea
contains the value of the mel variablea
initialized as part of the reader zone checkin. The local eponymous variableb
is un-initialized since it comes from the writer zone checkin process which does not initialize the eponymous variable.
- Inside the exclusive zone, the local eponymous variable
b
is assigned the value of the eponymous variablea
. The remote mel variablesa
andb
are not touched.
- Once done with the work inside the exclusive zone, the task checks out of the zone. Since there is no special checkout instructions, the task does a default checkout. The mel variable
a
is emptied of its value, and the mel variableb
receives a new deposit from the eponymous variableb
.
- The task concludes the checkout process by removing itself from the reader queue of the mel variable
a
, and from the writer queue of the mel variableb
.
Checkout Operation
The checkout for a mixed zone can take many forms.
Default Checkout
If there is no explicit
checkout
command (as in VERSION 2 above) or if the checkout
statement was invoked without attributes (as in VERSION 4 below), the default checkout process for each zone will be carried out. For reader zones, it will be <checkout read>, and for writer zones, <checkout write>.
/* VERSION 4 - Checkout statement without attribute */
<?reader> a, <?writer> b {
b = a;
<checkout>;
}
Custom Checkout
The default checkout behavior can be customized for each mel zone wait:
/* VERSION 5 - Customized default */
<?reader+skip> a, <?writer> b {
b = a;
}
The checkout for the mel variable b
is still the checkout write
process. However the default checkout for the mel variable a
has been redefined to be the skip
behavior. The mel variable a
will not be emptied of its value. Instead this value is retained, and available for another reader task.
Explicit Checkout
The default checkout behaviors will be overridden if the
checkout
statement is used with an attribute:
/* VERSION 6 - Explicit checkout */
<?reader+skip> a, <?writer> b {
b = a;
<checkout skip>;
}
The skip
behavior applies to both a
and b
. For the mel variable a
, the explicit skip
behavior matches the custom skip
behavior, so there is no change. For the mel variable b
, the explicit skip
behavior overrides the default write
behavior. Thus, the mel variable b
will not be filled with the value of the eponymous local variable b
.
The explicit
checkout
can be customized for each mel variable:
/* VERSION 7 - Customized explicit checkout */
<?reader+skip> a, <?writer> b {
b = a;
if ( b == 0 ) <checkout a=read b=skip>;
}
Here, if the value of the mel variable a
is 0, not only we don't want to use it to fill the mel variable b
, we also want to remove it from the mel variable a
so that the next read will not have to see this 0 value. Since the default checkout behavior of a
is skip
, we have to override it back to the read
behavior.
Mixed AND Zones
Let's get back to VERSION 2. There we used the LIST comma (
,
) separator between the mel zone waits. We can also use the AND (&&
) separator:
/* VERSION 8 - Mixed AND zones */
<?reader> a && <?writer> b {
b = a;
}
We still end up with the mixed zone having exclusive read access to a
and exclusive write access to b
. The difference is that the AND wait requires both the read conditions for a
and the write conditions for b
to be true at the same time before the task can check into the mixed zone. Compared with the LIST wait, it is usually harder to satisfy an AND wait (i.e. the task may have to wait longer for all the conditions to be aligned), but this will prevent deadlocks when multiple tasks vie for the same resources in a round-robin fashion.
Mixed OR Zones
Mixed zones can also support the OR zone waits:
/* VERSION 9 - Mixed OR zone */
<?reader> a || <?writer> b {
<case> a:
<?b> = a;
<checkout>;
<case> b:
b = <?>a;
<checkout>;
}
This is the behind-the-scene process:
- The task puts itself onto the mel variable
a
's reader queue. If the mel reader zone conditions fora
are satisfied, the task enters the mixed zone at the<case> a
code block.
- If the mel zone read conditions for
a
are not satisfied, the task puts itself onto the mel variableb
's writer queue. If the mel writer zone conditions forb
are satisfied, the task enters the mixed zone at the<case> b
code block.
- If neither set of conditions can be satisfied, the task will wait at both mel queues until one set of conditions is met. The task then gets off the other mel queue, and enters the mixed zone at the appropriate
<case>
code block.
- In both
<case> a
and<case> b
code blocks, we want to write to the mel variableb
the read value of the mel variablea
. The code is different depending on which<case>
code block we get to use.
- For
<case> a
, the value of the mel variablea
is transferred to the eponymous local variablea
. There is no eponymous local variableb
for the mel variableb
. To write to the mel variableb
, the mel write wait construct<?>b
must be used. In other words, the task has to contend with any other writer tasks for the write access to the mel variableb
since it does not have exclusive access tob
.
- For
<case> b
, the eponymous local variableb
stands for the mel variableb
. There is no eponymous local variablea
. To access the mel variablea
to read its value, the mel read wait construct<?>a
must be used.
- Each
<case>
code block must end with a checkout statement. This statement can be explicit as in the above example, or implicit by running out of code in the code block. The implicit checkout will cover any missing explicitcheckout
statement. There is no code bleeding from one<case>
code block to the next.
If the
random
OR behavior is specified, the task will randomize the zone wait check, instead of always checking a
reader queue first then b
writer queue:
/* VERSION 10 - Random OR wait */
<?reader> a ||<random> <?writer> b {
<case> a:
<?b> = a;
<checkout>;
<case> b:
b = <?> a;
<checkout>;
}
Previous Next Top
No comments:
Post a Comment