Welcome
» NERWous C
» Mel
Mel Properties Cache
The NERW Concurrency Model posits that tasks run in processing elements (pel) and share data contained in memory elements (mel). The pels and mels are hosted on computer elements (cel). The cels are distributed over a network of execution, read and write (nerw). When accessing shared data, a pel may have to cross the nerw network to reach a different cel that hosts the requested mel. This effort is resource intensive and incurs latency, reducing the throughput of a concurrent program.
To minimize the nerw impediments, NERWous C supports the concept of properties. Whenever a task takes on an operation that reaches out to a mel, the data that is returned to the task not only contains the result of the operation, but also other information about the mel. This information is saved locally into a cache set up inside the mel variable of the same name as the remote mel element. This eponymous mel variable represents the connection from the task to the mel element. Pieces of information in that cache are called properties.
The properties cache is the view of the mel at the time of the last operation the task conducts against that mel. This view will eventually become stale when other tasks update the shared mel element. To refresh its properties cache, a task can do another altering mel read or write operation, or invoke the non-altering snapshot operation.
Mel Properties Categories
This section expands on the introduction of mel properties categories from the last chapter. As discussed, there are three types of properties:
IN Properties
The IN properties pertain solely to the requesting task. Unlike the OUT, SET and CORE properties, the IN properties do not belong to the mel element. They are attributes to the mel operation that the task initiates, and are specific to that mel operation. Another task may use different attributes in its own mel operation, and will have different IN properties values in its resident mel variable. These operational attributes are saved as properties so the program can refer back at them, for reporting, debugging, or subsequent invocations. As an example of the latter case, a task can adjust the priority of the next mel request based on the length of the wait from the previous request to average out the latency.
When a task does a new mel operation to the mel element, the IN properties in the mel variable are cleared, and re-initialized with the attributes of the new mel operation.
OUT Properties
The OUT properties cache the result returned by a mel operation.
The OUT properties reflect information about the mel element after the mel operation has completed for the task, either successfully or unsuccessfully. After awhile, this information becomes stale due to other tasks doing reads and writes on the mel element. To get the current information, the task must invoke a new read or write operation, or take a new snapshot of the OUT data via the snapshot operation.
SET Properties
The SET properties are additional information about the mel element that are piggy-backed on return of any mel operation. These properties are snapshots of the configuration setting of the mel element at the time of return. After awhile, these properties may be stale if other tasks have issued mel operations that change the configuration, such as the rebuffer operation. If up-to-date values are needed, the program should make another mel operation or use the snapshot operation to refresh the SET properties.
The SET properties are system properties that can be changed programmatically by using mel operations. The CORE properties that we will explore next are system properties that cannot be changed programmatically once they are assigned.
CORE Properties
The CORE properties are system values assigned by the CHAOS runtime to allow a task to reach out to a mel element. These values cannot be changed once a mel element has been created.
The CORE properties are identification properties. They are the same and remain constant in all the mel variables of all the tasks that refer to the same mel element.
Mel Properties Constants
Some mel properties have a wide range of application-specific values. Other mel properties, such as
For brevity, the inclusion of
Mel ID Property
The <id> property is assigned by the CHAOS runtime environment to uniquely identify a mel element. The type of this property is a
When a mel variable is declared, the associated mel element is also created. At this time the CHAOS runtime will assign a unique identification number to represent the mel element, and stores this value in the <id> property of the mel variable. If the task passes the mel variable to another task, the <id> property is passed verbatim. This allows both tasks to refer to the same mel element.
The <id> property is maintained by the CHAOS runtime, and cannot be assigned from a NERWous C program. Attempting to do so will trigger a compile-time error:
Mel URL Property
The <url> property is the string equivalent to the <id> property. It is assigned by the CHAOS runtime environment to uniquely identify a mel element. The equivalence between the <id> and <url> means that either of them can be used for identification. Which format to use depends on the actual implementation of the mel operation and most importantly to the physical nature of the mel element.
If in use, a string identifier is not any random string value, but structured in certain way to fit the underlying physical environment. For example, if a mel element is a shared file, then a <url> value will use a file structure, such as
Mel Value Property
Let's get back to the basic Producer/Consumer example, and change the
The mel read statement,
The <value> property contains the mel value of
The example above shows the <value> property as a simple entity (i.e. an
Mel Value Auto Operators
The auto operators are auto-increment and auto-decrement operators. For each auto operator, we also have the pre and post actions, resulting in four cases in total.
Let's take a look at this pre-auto-increment statement:
Now let's take a look at this post-auto-increment statement:
Mel Status Property
When a task does a read or write operation to a mel element, the status of the mel element after the operation is also returned and cached in the <status> property in the resident mel variable. Available statuses are:
The constant values can be bit-wise OR to form combinations. Some combinations are meaningful, such as a mel element can be both empty and vacant after a mel operation. Other combinations are not possible, such as being empty and full at the same time.
NERW_STATUS_OPEN
The OPEN status can be used to check if a mel creation has been successful or not. As discussed in Mel Creation, a programmer can check for the failure of a mel creation operation by using the <error> property or catching an exception. Checking the <status> for
NERW_STATUS_EMPTY / NERW_STATUS_FILLED
These two values reflect the status of the mel element for the next reading after a task's mel operation (read or write). With
The previous paragraph uses "most likely" in several places due to different implementations of the CHAOS runtime. If CHAOS also takes into account waiting tasks, the returned status of a mel element will be opportunistic. For example, on the case of an unbuffered mel element after a read operation, the returned status will be
It is worth reminding that the <status> property reflects the status of the mel element after a mel operation by a task. It is not the current status of the mel element. For example, some time after a task does a mel read and gets back a
It is also worth mentioning again that the <status> property is part of the mel variable and thus resident to a particular task. Two tasks, say
Let's change the Producer/Consumer example to illustrate the use of the <status> property for reading:
NERW_STATUS_FULL / NERW_STATUS_VACANT
These two values reflect the status of the mel element for the next writing after the task's mel operation (read or write). With
Let's modify the
NERW_STATUS_CLOSED
Any task can invoke the <close> operation to close a mel element. Once this operation is successful, the <status> property in the mel variable resident to the task invoking the <close> operation will have the
Mel Condition Property
The <condition> property is similar to the <status> property, but is taken before the read or write operation can be applied to the mel element. It has the same values as the <status> property; however their interpretations are different.
After a reader task retrieves a value from the mel element, it can check the <condition> property for post-mortem analysis. If
For a writer task, a
Let's modify the previous
Mel Name Property
While the <id> and <url> properties identify the remote mel element, the <name> property is a character string that belongs to the mel variable. It contains a unique name that identifies the mel variable within its given scope. Among all the properties of a mel variable, the <name> property is unusual in a sense that it is a compile-time property instead of being a run-time one like the others. This means that any errors in using this property must be resolved when the NERWous C is still being compiled or translated.
Let's look at this code example:
A programmer can change the default name by using the
Since the value of the
Mel Name Scope Rule
The names used as the values of the
The
As said before, the errors due to
Mel Name Reference
The use of the
There is no rule to keep the same name for mel variables. For example, there may be coding standards that dictate arguments to be named in a certain way; or some application programming interface (API) that suggests a certain consistency for argument naming. Thus, if the above example has to be written as follows:
Mel Name Usage
Besides the mel element reference, there are other uses for the mel
Previous Next Top
- Mel Properties Cache
- Mel Properties Categories
- Mel Properties Constants
- Mel ID Property
- Mel URL Property
- Mel Value Property
- Mel Value Auto Operators
- Mel Status Property
- Mel Condition Property
- Mel Name Property
Mel Properties Cache
The NERW Concurrency Model posits that tasks run in processing elements (pel) and share data contained in memory elements (mel). The pels and mels are hosted on computer elements (cel). The cels are distributed over a network of execution, read and write (nerw). When accessing shared data, a pel may have to cross the nerw network to reach a different cel that hosts the requested mel. This effort is resource intensive and incurs latency, reducing the throughput of a concurrent program.
To minimize the nerw impediments, NERWous C supports the concept of properties. Whenever a task takes on an operation that reaches out to a mel, the data that is returned to the task not only contains the result of the operation, but also other information about the mel. This information is saved locally into a cache set up inside the mel variable of the same name as the remote mel element. This eponymous mel variable represents the connection from the task to the mel element. Pieces of information in that cache are called properties.
The properties cache is the view of the mel at the time of the last operation the task conducts against that mel. This view will eventually become stale when other tasks update the shared mel element. To refresh its properties cache, a task can do another altering mel read or write operation, or invoke the non-altering snapshot operation.
Mel Properties Categories
This section expands on the introduction of mel properties categories from the last chapter. As discussed, there are three types of properties:
- IN properties are cached attributes from the last mel operation a task conducts against a mel
- OUT properties are results the task caches after receiving them from a mel operation
- SET properties are configuration information from the mel that are piggy-backed with each mel operation
- CORE properties are system values assigned by the CHAOS runtime to allow a task to reach out to a mel
store
as a stand-in.
IN Properties
The IN properties pertain solely to the requesting task. Unlike the OUT, SET and CORE properties, the IN properties do not belong to the mel element. They are attributes to the mel operation that the task initiates, and are specific to that mel operation. Another task may use different attributes in its own mel operation, and will have different IN properties values in its resident mel variable. These operational attributes are saved as properties so the program can refer back at them, for reporting, debugging, or subsequent invocations. As an example of the latter case, a task can adjust the priority of the next mel request based on the length of the wait from the previous request to average out the latency.
Property | Synopsis |
---|---|
store<priority> | Priority value used by the last mel operation |
store<timeout> | Timeout value used by the last mel operation |
store<name> | Scoped name of the mel variable set during creation |
store<agent> | Entity that executes a requested mel operation |
When a task does a new mel operation to the mel element, the IN properties in the mel variable are cleared, and re-initialized with the attributes of the new mel operation.
OUT Properties
The OUT properties cache the result returned by a mel operation.
Property | Synopsis |
---|---|
store<value> | Value returned by the mel read operation. This value can be a simple entity (like an int ), an array or a structured entity |
store<count> | Number of items in an array value |
store<sequence> | Version identifier of the value returned from a mel read operation |
store<status> | Status of the mel variable after the mel operation |
store<condition> | Status of the mel variable before the mel operation |
store<error> | A numerical value representing the error code of the last mel operation. A value of 0 means success and non-0 values mean failures. |
store<why> | Reason of a non-zero <error> value |
The OUT properties reflect information about the mel element after the mel operation has completed for the task, either successfully or unsuccessfully. After awhile, this information becomes stale due to other tasks doing reads and writes on the mel element. To get the current information, the task must invoke a new read or write operation, or take a new snapshot of the OUT data via the snapshot operation.
SET Properties
The SET properties are additional information about the mel element that are piggy-backed on return of any mel operation. These properties are snapshots of the configuration setting of the mel element at the time of return. After awhile, these properties may be stale if other tasks have issued mel operations that change the configuration, such as the rebuffer operation. If up-to-date values are needed, the program should make another mel operation or use the snapshot operation to refresh the SET properties.
Property | Synopsis |
---|---|
store<buffer> | Number of buffer slots of the mel element |
store<location> | Cel location of the mel element |
store<readers> | Number of reader tasks subscribing to the mel element |
store<writers> | Number of writer tasks subscribing to the mel element |
The SET properties are system properties that can be changed programmatically by using mel operations. The CORE properties that we will explore next are system properties that cannot be changed programmatically once they are assigned.
CORE Properties
The CORE properties are system values assigned by the CHAOS runtime to allow a task to reach out to a mel element. These values cannot be changed once a mel element has been created.
Property | Synopsis |
---|---|
store<id> | Mel variable numerical identification. This value is mostly used in environments where shared resources can be identified by a number, such as multi-CPUs shared-memory supercomputers. Otherwise this value is a perfect hash of the <url> property. |
store<url> | Mel element string identifier. This value is mostly used in distributed environments where shared resources are identified by a uniform resource locator. Otherwise this value is just a string representation of the numerical <id> property. |
The CORE properties are identification properties. They are the same and remain constant in all the mel variables of all the tasks that refer to the same mel element.
Mel Properties Constants
Some mel properties have a wide range of application-specific values. Other mel properties, such as
error
and status
have a fixed set of constant values. In NERWous C, these constant values are defined in the nerw.h
file that must be included in all NERWous C programs.
For brevity, the inclusion of
nerw.h
is mostly skipped in the code samples.
Mel ID Property
The <id> property is assigned by the CHAOS runtime environment to uniquely identify a mel element. The type of this property is a
long long
, allowing a theoretical limit of over 9 quintillion mel elements (i.e. 9 followed by 18 zeros). Although NERWous C does not specify how an <id> property is formatted, it requires that:
- The <id> property is assigned to a mel element when it is created
- No two mel elements within the same NERWous C program can have the same <id> property
<mel> int store; /* the <id> property is set */
printf ("Mel entity [%ll] created by declaration", store<id>);
Another use is to differentiate between the selected mel elements in a reader OR zone.
When a mel variable is declared, the associated mel element is also created. At this time the CHAOS runtime will assign a unique identification number to represent the mel element, and stores this value in the <id> property of the mel variable. If the task passes the mel variable to another task, the <id> property is passed verbatim. This allows both tasks to refer to the same mel element.
The <id> property is maintained by the CHAOS runtime, and cannot be assigned from a NERWous C program. Attempting to do so will trigger a compile-time error:
store<id> = 0LL; /* Compile-time ERROR */
In a distributed environment where a resource can be better identified via a universal resource locator (URL) string, the <id> can be the numerical perfect hash of the <url> property. The NERWous C language does not dictate a perfect hash algorithm, but with 9 quintillion numerical possibilities, it should be possible to hash structured <url> strings into unique numbers.
Mel URL Property
The <url> property is the string equivalent to the <id> property. It is assigned by the CHAOS runtime environment to uniquely identify a mel element. The equivalence between the <id> and <url> means that either of them can be used for identification. Which format to use depends on the actual implementation of the mel operation and most importantly to the physical nature of the mel element.
If in use, a string identifier is not any random string value, but structured in certain way to fit the underlying physical environment. For example, if a mel element is a shared file, then a <url> value will use a file structure, such as
/share/mel/store.dat
. If it is hosted on a web site, a <url> value for a mel element of name store
can be something like https://nerw.dom/mel/store
, and mel operations such as this creation mel statement:
<mel buffer=10> int store
can be translated into this URL
https://nerw.dom/mel/store?action=create&buffer=10
In environments where a numerical identifier is more compatible, the <url> string identifier is its alphanumerical equivalent. For example, if <id> were the number 123456790, then <url> would be the string "1234567890".
Mel Value Property
Let's get back to the basic Producer/Consumer example, and change the
Consumer
code to illustrate the use of the <value> property:
main () {
<mel> int store;
<!> Producer (store);
<!> Consumer (store);
}
void Producer (<mel> int store) {
while ( <?>store = Produce() );
}
void Consumer (<mel> int store) {
while ( <?>store )
Consume(store<value>);
}
In the original Consumer
, we use a local variable, c
, to temporarily hold the value read from the mel element store
before we Consume
it. In the above example, we skip this intermediary local variable, and access the read value directly via the <value> property.
The mel read statement,
<?>store
, suspends the Consumer
task until the Producer
task deposits a new item to the mel element. The Consumer
task then removes this item from the mel element, and saves it in the <value> property of its mel variable. It then uses that property implicitly for the while
checking for a zero value, and explicitly as argument for the Consume
serial function.
The <value> property contains the mel value of
Consumer
's last read from the mel element. Since then the mel element may have been updated with a new deposit from the Producer
task. Once this happens, the <value> property cached in the Consumer
mel variable store
will be different from the value at the mel element. To refresh its <value> property, the Consumer
task has to read the mel element again, or use the snapshot operation.
The example above shows the <value> property as a simple entity (i.e. an
int
eger). The <value> can represent more complex entities such as:
Mel Value Auto Operators
The auto operators are auto-increment and auto-decrement operators. For each auto operator, we also have the pre and post actions, resulting in four cases in total.
Let's take a look at this pre-auto-increment statement:
int c = ++<?>store;
These are the steps that are carried out:
- The task waits for the mel element represented by the mel variable
store
to be filled and available for the task to read. - The mel element is emptied and its value is transferred to the task's <value>property.
- The <value> property is incremented.
- The incremented <value> property is assigned to the
c
variable.
Now let's take a look at this post-auto-increment statement:
int c = <?>store++;
These are the steps that are carried out:
- The task waits for the mel element represented by the mel variable
store
to be filled and available for the task to read. - The mel element is emptied and its value is transferred to the task's <value>property.
- The <value> property is assigned to the
c
variable. - The <value> property is incremented.
int c = --<?>store;
int c = <?>store--;
In both the pre and post decrement cases, the <value> property is decremented by 1 from the original value read from the mel element. The difference is that the value assigned to the variable c
is after the decrement (for pre-auto-decrement) or before the decrement (for post-auto-decrement).
Mel Status Property
When a task does a read or write operation to a mel element, the status of the mel element after the operation is also returned and cached in the <status> property in the resident mel variable. Available statuses are:
Status | Constant | Synopsis |
---|---|---|
OPEN | NERW_STATUS_OPEN | The mel element has been successfully created, and can now be written or read. |
EMPTY | NERW_STATUS_EMPTY | When the mel element buffer does not contain any value to be read, the mel element is said to be empty. The reader task has to wait for the mel element to be filled in order to acquire a value from the reader's side of the buffer. |
FILLED | NERW_STATUS_FILLED | When the mel element buffer contains a value that can be read, the mel element is said to be filled. The reader task has been able to acquire this value from the reader's side of the buffer. |
FULL | NERW_STATUS_FULL | When the mel element cannot receive another value to be written into it because all the slots in its mel buffer already have a value, the mel element is said to be full. The writer task has to wait for the mel element to become vacant before it can deposit a new value in the writer's side of the buffer. |
VACANT | NERW_STATUS_VACANT | When the mel element has an available slot in its mel buffer for a value to be written into it, the mel element is said to be vacant. The writer task can deposit a new value in the writer's side of the buffer. |
CLOSED | NERW_STATUS_CLOSED | The mel element has been closed. The mel element cannot be read nor written any more. |
The constant values can be bit-wise OR to form combinations. Some combinations are meaningful, such as a mel element can be both empty and vacant after a mel operation. Other combinations are not possible, such as being empty and full at the same time.
NERW_STATUS_OPEN
The OPEN status can be used to check if a mel creation has been successful or not. As discussed in Mel Creation, a programmer can check for the failure of a mel creation operation by using the <error> property or catching an exception. Checking the <status> for
NERW_STATUS_OPEN
is another way to detect failure:
<mel> int store;
if ( (store<status> & NERW_STATUS_OPEN) == 0x0 )
printf ("Mel creation failed!\n");
The NERW_STATUS_OPEN
status always exists along with NERW_STATUS_EMPTY
, NERW_STATUS_FILLED
, NERW_STATUS_FULL
or NERW_STATUS_VACANT
. It is mutually exclusive with NERW_STATUS_CLOSED
since a mel element is either open or closed but not both.
NERW_STATUS_EMPTY / NERW_STATUS_FILLED
These two values reflect the status of the mel element for the next reading after a task's mel operation (read or write). With
NERW_STATUS_EMPTY
, the mel element does not have any value for the next reading. With NERW_STATUS_FILLED
, the mel element has a value for the next reading. If the <status> property is set to NERW_STATUS_FILLED
after a read operation, the mel element is most likely to be buffered, and that the next slot in the buffer already has a standing value. If the mel element is not buffered, after a read operation which removes the mel value, the return status is most likely be NERW_STATUS_EMPTY
.
The previous paragraph uses "most likely" in several places due to different implementations of the CHAOS runtime. If CHAOS also takes into account waiting tasks, the returned status of a mel element will be opportunistic. For example, on the case of an unbuffered mel element after a read operation, the returned status will be
NERW_STATUS_FILLED
(instead of NERW_STATUS_EMPTY
) if CHAOS detects that there is a writer task waiting to deposit its value and make the mel element filled again.
It is worth reminding that the <status> property reflects the status of the mel element after a mel operation by a task. It is not the current status of the mel element. For example, some time after a task does a mel read and gets back a
NERW_STATUS_EMPTY
status, a writer task has come in and deposit a new value, changing the current status of the mel element back to NERW_STATUS_FILLED
. To refresh its cached <status> property, a task has to do another intrusive mel operation (such as a read or write), or invoke the non-intrusive snapshot operation.
It is also worth mentioning again that the <status> property is part of the mel variable and thus resident to a particular task. Two tasks, say
A
and B
, access the same mel element and may end up with the same value for their <status> property; however these values represent different things: one is the status of the mel element after task A accesses the mel, and the other is the mel status after task B's access, which happens at a different time.
Let's change the Producer/Consumer example to illustrate the use of the <status> property for reading:
#define BUFFERSIZE 10
main () {
<mel buffer=BUFFERSIZE> int store;
<!> Producer (store);
<!> Consumer (store);
}
void Producer (<mel> int store) {
while ( <?>store = Produce() );
}
void Consumer (<mel> int store) {
int products[BUFFERSIZE];
int i, j;
while ( 1 ) {
for (i=0; i<BUFFERSIZE; ++i) {
products[i] = <?>store;
if ( store<status> & NERW_STATUS_EMPTY ) break;
}
for (j=0; j<=i; ++j) {
if ( !products[j] ) break;
Consume (products[i]);
}
if ( j != i ) break; /* detect 0 value, break out of while loop */
}
}
The mel element is now created with a buffer of BUFFERSIZE
slots. Unlike the previous Consumer
which does the consumption one product at a time, the new Consumer
reads in all available products that are currently buffered. It knows when to stop reading by checking the <status> property for the NERW_STATUS_EMPTY
condition. The Consumer
task then Consume
s all the collected products.
NERW_STATUS_FULL / NERW_STATUS_VACANT
These two values reflect the status of the mel element for the next writing after the task's mel operation (read or write). With
NERW_STATUS_FULL
, the mel element does not have an available slot to receive a new value. If the mel element is buffered, all of its slots currently contain a value. With NERW_STATUS_VACANT
, the mel element is either empty or is buffered and has at least an available slot to receive a new writing.
Let's modify the
Producer
task to illustrate the <status> property for writing:
void Producer (<mel> int store) {
int product = Produce();
while ( product ) {
<?>store = product;
if ( store<status> & NERW_STATUS_FULL) )
slowdown();
product = Produce();
}
}
After each writing, this Producer
checks the status of the mel element. If the mel element is not buffered (or in other words it has only one slot), and there is no reader task in the waiting, the status will be NERW_STATUS_FULL
. If there is a reader task in the waiting, the status can be either NERW_STATUS_FULL
or NERW_STATUS_VACANT
depending on the implementation of the CHAOS runtime. If the mel element is buffered (i.e. having multiple slots), a NERW_STATUS_FULL
means that all the slots have been filled up, and the next write can be hit by a wait for a slot to be freed. To allow a reader task to catch up, the Producer
task invokes the slowdown
function to slow down its production.
NERW_STATUS_CLOSED
Any task can invoke the <close> operation to close a mel element. Once this operation is successful, the <status> property in the mel variable resident to the task invoking the <close> operation will have the
NEWS_STATUS_CLOSED
bit set, due to the piggy-backing of the SET properties. Other tasks do not have their <status> property updated to NEWS_STATUS_CLOSED
until they make a mel operation to the mel element.
Mel Condition Property
The <condition> property is similar to the <status> property, but is taken before the read or write operation can be applied to the mel element. It has the same values as the <status> property; however their interpretations are different.
After a reader task retrieves a value from the mel element, it can check the <condition> property for post-mortem analysis. If
NERW_STATUS_FILLED
is set, the reader task after being granted access to the mel element based on the read operation requested priority, has found the mel element to already contain a value for it to read away. If the condition bit NERW_STATUS_EMPTY
is set instead, it means that the reader task has to wait for a writer task to deposit a value. It both cases, a read statement, such as <?>store
can eventually succeed, but in the latter case, the <?>
operator will suspend the reading task longer.
For a writer task, a
NERW_STATUS_FULL
<condition> means that the task has to wait in the mel writers' queue for a reader task to remove a value and make a slot available for deposit. On the other hand, a NERW_STATUS_VACANT
means that the writer task can find a vacant slot to deposit its value, and quickly gets off the <?>
wait operator and resumes its processing.
Let's modify the previous
Producer
task to use the <condition> property instead of the <status> property:
void Producer (<mel> int store) {
int product = Produce();
while ( product ) {
<?>store = product;
if ( store<condition> & NERW_STATUS_FULL )
slowdown();
product = Produce();
}
}
The use of the <condition> property seems to be a better fit for the decision to slowdown
the production than the use of the <status> property in the earlier example. No matter if the mel element is buffered or not, a mel wait in its just completed write means that the reader task (or tasks) cannot keep up with the writer task.
Mel Name Property
While the <id> and <url> properties identify the remote mel element, the <name> property is a character string that belongs to the mel variable. It contains a unique name that identifies the mel variable within its given scope. Among all the properties of a mel variable, the <name> property is unusual in a sense that it is a compile-time property instead of being a run-time one like the others. This means that any errors in using this property must be resolved when the NERWous C is still being compiled or translated.
Let's look at this code example:
<mel> int GlobStore1;
<mel as="Big Store"> int GlobStore2;
main () {
<mel> int mainStore1;
<mel as="Small Store"> int mainStore2;
printf ("<name> value [%s] should be [GlobStore1]\n", GlobStore1<name>);
printf ("<name> value [%s] should be [Big Store]\n", GlobStore2<name>);
printf ("<name> value [%s] should be [mainStore1]\n", mainStore1<name>);
printf ("<name> value [%s] should be [Small Store]\n", mainStore2<name>);
foo1 (<?>mainStore1, <?> mainStore2);
foo2 (<?>mainStore1, <?> mainStore2);
}
void foo1 (<mel> int argstore1, <mel as="Tiny Store"> int argstore2) {
printf ("<name> value [%s] should be [argstore1]\n", argstore1<name>);
printf ("<name> value [%s] should be [Tiny Store]\n", argstore2<name>);
}
void foo2 (<mel as="mainStore1"> int m1, <mel> int m2) {
printf ("<name> value [%s] should be [mainStore1]\n", m1<name>);
printf ("<name> value [%s] should be [m2]\n", m2<name>);
}
By default, the <name> property of a mel variable is simply its compile-time name under the scope rule. Mel variables with the default <name> property are GlobStore1
(in global scope), mainStore1
, argStore1
and m2
(in local scope).
A programmer can change the default name by using the
as
attribute, as seen in the declarations for GlobStore2
(in global scope), mainStore2
, argstore2
and m1
(in local scope).
Since the value of the
as
attribute must be resolved during compile time, it must be a constant value, and not a variable. For example, the code snippet below will generate a compilation error:
<mel as="MyMel1"> int store1; /* OK */
#define MYNAME2 "MyMel2"
<mel as=MYNAME2> int store2; /* OK */
char myname3[20] = {'M','y','M','e','l', '3', '\0' };
<mel as=myname3> int store2; /* ERROR */
Mel Name Scope Rule
The names used as the values of the
as
attribute must obey the mel scope rule. It means that the same name cannot be re-used in the same scope. The following example shows the good and bad usages of the as
name:
<mel> int GlobStore1;
<mel as="GlobStore1"> int GlobStore2; /* ERROR 1: GlobStore1 is in use */
main () {
<mel as="GlobStore1"> int mainStore1; /* ERROR 1: GlobStore1 is in use */
<mel as="mainStore1"> int mainStore2; /* ERROR 2: mainStore1 is in use */
foo1 (<?>mainStore1, <?> mainStore2);
foo2 (<?>mainStore1, <?> mainStore2);
}
void foo1 (<mel as="GlobStore1"> int argstore1, /* ERROR 1: GlobStore1 is in use */
<mel as="mainStore2"> int argstore2) { /* OK */
printf ("[argstore1] name is [%s]\n", argstore1<name>);
printf ("[argstore2] name is [%s]\n", argstore2<name>);
}
void foo2 (<mel as="mainStore1"> int argstore1, /* OK */
<mel as="mainStore2"> int argstore2) { /* OK */
printf ("[argstore1] name is [%s]\n", argstore1<name>);
printf ("[argstore2] name is [%s]\n", argstore2<name>);
}
The ERROR 1
occurrences are due to the names of global mel variables are reserved globally. They can be used to create other mel variables that point to the same remote mel element (as in <snapshot> operation with on
attribute), but not to assign as
names to mel variables that point to different mel elements.
The
ERROR 2
occurrence is due to the names of all local mel variables (such as mainStore1
in main
) are reserved in the local scope. This is even though mainStore1
is declared with the as
attribute to a different name. On the other hand, the argstore2
can use mainStore2
as name because mainStore2
is in the local scope of the main
task but not of the foo1
function.
As said before, the errors due to
as
name usage incongruities must be resolved at compilation time. They cannot be caught with the <error> property or mel operation exceptions since they do not appear when the program is run.
Mel Name Reference
The use of the
as
attribute in the mel argument declarations of the functions foo1
and foo2
shows the mel element reference reason for supporting the <name> mel variable property. In previous chapters, we would write:
main () {
<mel> int mainStore;
<!> runParallel (<?>mainStore);
runSerial (<?>mainStore);
}
void runParallel (<mel> int mainStore) {
printf ("<name> [%s] should be [mainStore]\n", mainStore<name>);
doThingsInParallel(<?>mainStore);
}
void runSerial (<mel> int mainStore) {
printf ("<name> [%s] should be [mainStore]\n", mainStore<name>);
doThingsInSerial(<?>mainStore);
}
Since a mel element, no matter in what compile-time scope it is created, is shared to all tasks during run time, it is customary (but not required) to use the same name for all the subsequent mel variables that access that common mel element. Thus, after the task main
creates the mel element mainStore
(and maintains the access via its resident eponymous mel variable mainStore
), the argument to the task runParallel
and to the function runSerial
are also named mainStore
. (See mel passing rule.)
There is no rule to keep the same name for mel variables. For example, there may be coding standards that dictate arguments to be named in a certain way; or some application programming interface (API) that suggests a certain consistency for argument naming. Thus, if the above example has to be written as follows:
main () {
<mel> int mainStore;
<!> runParallel (<?>mainStore);
runSerial (<?>mainStore);
}
void runParallel (<mel> int pararg) {
printf ("<name> [%s] should be [pararg]\n", pararg<name>);
doThingsInParallel(<pararg>);
}
void runSerial (<mel> int m) {
printf ("<name> [%s] should be [m]\n", m<name>);
doThingsInSerial(<m>);
}
then to keep the reference to the same mel element, we use the as
attribute as in this revised example:
main () {
<mel> int mainStore;
<!> runParallel (<?>mainStore);
runSerial (<?>mainStore);
}
void runParallel (<mel as="mainStore"> int pararg) {
printf ("<name> [%s] should be [mainStore]\n", pararg<name>);
doThingsInParallel(<pararg>);
}
void runSerial (<mel as="mainStore"> int m) {
printf ("<name> [%s] should be [mainStore]\n", m<name>);
doThingsInSerial(<m>);
}
The mel variables mainStore
, pararg
and m
, have the same CORE properties since they refer to the same remote mel element. To make this commonality visible at code level, the as
values for pararg
and m
are set to the name of the remote mel element (i.e. mainStore
).
Mel Name Usage
Besides the mel element reference, there are other uses for the mel
name
property. This list summarizes all of them:
In this chapter, we have discussed the mel name reference use. The other uses will be explored in subsequent chapters.
Previous Next Top
No comments:
Post a Comment