Concurrency and Atomicity
The language nesC directly reflects the TinyOS execution model
through the notion of command and event contexts. Figure 7.11 shows a section of the component SenseAndSend to illustrate some
language features to support concurrency in nesC and the effort to
reduce race conditions. The SenseAndSend component is intended to
be built on top of the Timer component (described in the previous
section), an ADC component, which can provide sensor readings,
and a communication component, which can send (or, more precisely,
broadcast) a packet. When responding to a timer0Fire event,
the SenseAndSend component invokes the ADC to poll a sensor reading.
Since polling a sensor reading can take a long time, a split-phase
operation is implemented for getting sensor readings. The call to
ADC.getData() returns immediately, and the completion of the operation
is signaled by an ADC.dataReady() event. A busy flag is used
to explicitly reject new requests while the ADC is fulfilling an existing
request. The ADC.getData() method sets the flag to true, while
the ADC.dataReady() method sets it back to false. Sending the sensor
reading to the next-hop neighbor via wireless communication is also
a long operation. To make sure that it does not block the processing
of the ADC.dataReady() event, a separate task is posted to the scheduler.
A task is a method defined using the task keyword. In order to simplify the data structures inside the scheduler, a task cannot
have arguments. Thus the sensor reading to be sent is put into a
sensorReading variable.