Pages

Thursday, March 3, 2016

Mel Priorities

Welcome » NERWous C » Mel
  1. Mel Access Priority
  2. Mel Priority Queues
  3. Mel Default Priority
  4. Mel Priority Settings
  5. Mel Priority Property


Mel Access Priority

The following example shows the use of priority for a mel read and write:
#include 
main () {
    <mel> int store;
    <!> Producer (store);
    <!> Consumer (store);
    <!> ProducerPrio (store);
    <!> ConsumerPrio (store);
}
void Producer (<mel> int store) {
    while ( <?>store = Produce() );
    <close>store;
}
void Consumer (<mel> int store) {
    while ( 1 ) {
       try {  Consume(<?>store); }
       catch ( store<CLOSED> ) { break; }
    }
}
void ProducerPrio (<mel> int store) {
   int myprio = NERW_PRIORITY_DEFAULT;
   while ( 1 ) {
      try {
         <? timeout priority=myprio>store = Produce();
      }
      catch ( store<TIMEDOUT> ) { ++myprio; }
   }
   <close>store;
}
void ConsumerPrio (<mel> int store) {
   int myprio = NERW_PRIORITY_DEFAULT;
   while ( 1 ) {
      try {
         Consume (<? timeout priority=myprio>store;
      }
      catch ( store<TIMEDOUT> ) { ++myprio; }
      catch ( store<CLOSED> ) { break; }
   }
}
The same mel store is shared between all the tasks that the main task pels out. The Producer and Consumer tasks use the default priority since they do not specify any. The ProducerPrio and ConsumerPrio tasks make use the priority attribute to specify the mel access priority. Both tasks start out with the same default priority (as indicated by the NERW_PRIOIRTY_DEFAULT value). If they fail to access the mel store within the timeout period, they will increment their priority value so they have the "upper hand" in the mel access as compared with the plain Producer and Consumer.

The pump-up-the-priority strategy that ProducerPrio and ConsumerPrio use above may not work if Producer and Consumer also adopt the same strategy. The management of the priorities is not part of the NERW model. It is the responsibility of the code developers to engineer the mel access priorities to fit the problem on hand with the underlying run-time platform.


Mel Priority Queues

With a couple of exceptions, accesses to mel variables are though mel queues. The queues serialize the access to the mel shared resource so that all waiting tasks have a chance. All the queues are First-In-First-Out (FIFO) so that tasks that request access first will be served first. However, all the tasks at the higher priority queue must be served first before any task at the lower priority queue.

Read access uses readers' queues which are separate from writers' queues used for write access. Each mel variable has one default readers' queue and one default writers' queue. These queues have the default priority. When a task requests a mel access and does not specify a priority or specifies the NERW_PRIORITY_DEFAULT priority, the default queue is used. If a task comes in with a different priority, then the <?> operation will find a queue with that priority or creates one if not found, to put the task in.

Once a mel variable is closed, all the queues are deleted allowing the resources used to be recollected. These are the queues:
  1. The default readers' queue
  2. The default writers' queue
  3. Any priority queues
  4. The readonly queue if exists



Mel Default Priority

Although the NERW Concurrency Model does not limit the possible range of priority values, the NERWous C limits priorities to a positive integer range, with 0 as the lowest priority, known as the base priority. The CHAOS runtime environment may further limit the possible values to a discreet number of values (for example, just HIGH, NORMAL and LOW) to reflect the actual physical platform.

The default priority is the priority used by the default readers' queue and writers' queue, and can be set to any non-negative value. It can be preset at compile-time, or customized at program invocation via a configuration file, or fixed by the CHAOS runtime environment. If the default priority is set to a non-0 value, it allows tasks to have a lower priority than the default priority. If no default priority is configured, it is set to be 0, and tasks can only have higher priorities than the default priority.

The following mel accesses use the default priority;
<?>store;    /* no prority read */
<? priority>store;   /* read with priority attribute without value */
<? priority=NERW_PRIORITY_DEFAULT>store;    /* read with priority set to default */

><?>store = 10;    /* no prority write */
<? priority>store = 10;   /* write with priority attribute without value */
<? priority=NERW_PRIORITY_DEFAULT>store = 10;    /* write with priority set to default */


Mel Priority Settings

Priorities can be set via calculations. When calculating a subsequent priority, the keyword priority stands for the current priority, not the default priority as in the original setting. Any calculation resulting in a negative priority will cause the priority to be reset to the base priority which is 0.

In the example below, let's assume that the default priority is 5.
    int n = 10;
    <? priority>store;    // access with default priority 5
    <? priority=n>store;    // access with new priority 10
    <? priority+n>store;    // access with current priority plus 10, thus 20
    <? priority+priority>store;    // access with double the current priority, thus 40
    <? priority-100>store;    // access with the base priority 0 since 40-100 is negative
    <? priority=-100>store;    // access with same base priority 0 due to negative assignment
    <? priority=100>store;    // access with new priority 100
    int priority = 20;
    <? priority+priority>store;    // access with double the current priority, thus 200
The keyword priority represents the current priority within the < and > NERW markers when used in calculation. Thus the C variable priority is ignored, while the variable n is accepted.


Mel Priority Property

After a successful mel access, a program can check the priority used via the <priority> property of the mel.
     <? priority>store;
     int defprio = store<priority>;
     printf ("The default priority used is %d", defprio);
     <? priority+20>store;
     printf ("The last access has default priority + 20 or %d", store<priority>);
Whenever a mel is accessed, the run-time environment stores the priority value used (or 0 if no priority) in the local <priority> property,


Previous Next Top

No comments:

Post a Comment