On Sep 11, 2006, at 9:15 AM, Adam wrote:

Since variables in async function can be preempted by another interupt, then
we need add "atomic" keyword to protect them. Unfortunately, I notice
"atomic" section is ignored in "async" function when it is converted to
"app.c" -- see following instance:

I have tried to compare SurgeM.nc with app.c under build/telosb. I notice this "atomic" section is not atomic in app.c -- is this a bug? Or when the
atomic keyword will be ignored?

  async event result_t ADC.dataReady(uint16_t data) {
    atomic {
      if (!gfSendBusy) {
        gfSendBusy = TRUE;
        gSensorData = data;
        post SendData();
      }
    }
    return SUCCESS;
  }

The corresponding code in app.c is

# 222 "SurgeM.nc"
static inline   result_t SurgeM$Sensor$dataReady(uint16_t data)
#line 222
{

  {
  }
#line 224
  ;
  {
    if (!SurgeM$gfSendBusy) {
        SurgeM$gfSendBusy = TRUE;
        SurgeM$gSensorData = data;
        TOS_post(SurgeM$SendData);
      }
  }

  return SUCCESS;
}

There should be "__nesc_atomic_t __nesc_atomic = __nesc_atomic_start ();" to
replace "atomic". How to explain this? A bug???


Good question! It's not a bug: it's an optimization. :)

Atomic statements introduce a few cycle overhead. One statement isn't a big deal, but if you look through the code, there are a lot of them. If you have an interrupt handler that crosses several component boundaries, each of which has its own atomic statement, the overhead can begin to be large enough to warrant an optimization.

The nesC compiler detects when atomic calls are nested, and removes all but the top-level one. Here's a very simple example:

a() {
 atomic a++;
}

b() {
  atomic {
    b++;
    a();
  }
}

In this code, the atomic statement around a++ can be removed, because it is already called from an atomic block. In this code you can't remove it:

a() {
 atomic a++;
}

b() {
  atomic {
    b++;
    a();
  }
}

c() {  // Does not execute in an atomic block
  a();
}


This optimization is particularly valuable on the msp430 TinyOS code, as almost all of its interrupts keep interrupts disabled (execute within an atomic block). Therefore you can elide all atomic blocks within their code, as there's a top-level atomic block.

Basically, the nesC compiler will make sure that it keeps the atomic semantics, while minimizing the overhead.

Phil

_______________________________________________
Tinyos-help mailing list
[email protected]
https://mail.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help

Reply via email to