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 bufferbto 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,
aandb. The local eponymous variableacontains the value of the mel variableainitialized as part of the reader zone checkin. The local eponymous variablebis 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
bis assigned the value of the eponymous variablea. The remote mel variablesaandbare 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
ais emptied of its value, and the mel variablebreceives 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 foraare satisfied, the task enters the mixed zone at the<case> acode block.
- If the mel zone read conditions for
aare not satisfied, the task puts itself onto the mel variableb's writer queue. If the mel writer zone conditions forbare satisfied, the task enters the mixed zone at the<case> bcode 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> aand<case> bcode blocks, we want to write to the mel variablebthe 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 variableais transferred to the eponymous local variablea. There is no eponymous local variablebfor the mel variableb. To write to the mel variableb, the mel write wait construct<?>bmust be used. In other words, the task has to contend with any other writer tasks for the write access to the mel variablebsince it does not have exclusive access tob.
- For
<case> b, the eponymous local variablebstands for the mel variableb. There is no eponymous local variablea. To access the mel variableato read its value, the mel read wait construct<?>amust 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 explicitcheckoutstatement. 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