[Tinyos-help] questions about usage of keyword atomic

Eric Decker cire831 at gmail.com
Wed Aug 29 17:38:23 PDT 2012


On Wed, Aug 29, 2012 at 4:40 PM, Xiaohui Liu <whulxh at gmail.com> wrote:

> Thank you both for sharing your insights. I still have a few comments, CIL.
>
> On Tue, Aug 28, 2012 at 3:52 AM, Eric Decker <cire831 at gmail.com> wrote:
>
>>
>>
>> On Mon, Aug 27, 2012 at 6:59 PM, Xiaohui Liu <whulxh at gmail.com> wrote:
>>
>>> Hello all,
>>>
>>> 1) I have the following code snippet:
>>> *uint8_t a;*
>>> *
>>> *
>>> *async event void Alarm1.fired() {*
>>> *   a = 0;*
>>> *}*
>>>
>>> This compiles successfully without any warning.
>>>
>>
>>
>>>  Isn't there a racing condition here, between Alarm1 and itself?
>>>
>>
>> I don't know what you mean by the above.   How can Alarm1 have a race
>> condition with itself?
>>
>> I was thinking the interrupt that generates Alarm1 can be nested, but
> turns out it is TOSH_SIGNAL and cannot be. What I actually want to express
> is that if Alarm1.fired() is replaced by another event generated by a
> nested interrupt TOSH_INTERRUPT, should *a* be protected?
>

If you do indeed cause the interrupts to be nested then yes it should be
protected.

Nested interrupts on the msp430s have lots of problems and you probably
don't want to do this.


>
> Looks to me like in the above program there is only one place where a is
>> accessed, so how can there be a race condition.
>>
>>
>>>
>>> 2) If the following is added.
>>> *async event void Alarm2.fired() {*
>>> *   a = 1;*
>>> *}*
>>> Still, this compiles successfully without any warning. Isn't there an
>>> additional racing condition here, between Alarm1 and Alarm2 (and Alarm2 and
>>> itself)?
>>>
>>
>> async is considered to be one level of execution.   So there still isn't
>> a race condition.   When Alarm1 fires, a gets set to 0.   Alarm2 can not
>> get in and thus there is not a race condition.
>>
>> this is a nesc assumption.   That async is one level of execution  (one
>> context).
>>
>>
> By assumption, you mean Alarm cannot be preempted?
>

Interrupted is the correct term.   Preemption is a  little bit different.
The assumption that nesc  makes is that there are two levels of context and
that the async context doesn't get interrupted.   So if two async pieces
access the same variable it assumes that there isn't a race condition.


> I think the assumption holds just because the interrupt that generates
> Alarm is defined as TOSH_SIGNAL rather than TOSH_INTERRUPT.
>

That is why the assumption holds.   But it still is a nesc assumption and
if violated unless well understood can cause really nasty problems.
Typically intermittent failures.


> It is not a nesc assumption.
>

Sure it is.


> What is "one level of execution  (one context). ", a code snippet that
> cannot be preempted?
>

not sure what you are asking.


>
>>> 3) If the following is added.
>>> *event void Timer.fired() {*
>>> *  a = 2;*
>>> *}*
>>> Then there is a warning, "non-atomic accesses to shared variable `a'".
>>> Why is there no warning for
>>> *a = 0;*
>>> in Alarm1?
>>>
>>
>> Why do you expect a warning from Alarm1?
>>
>> Timer.fired is at sync level.   Sync level is the other nesc execution
>> context.   Because there is access to a from the async level nesc beleives
>> that there is a potential race condition between the Alarms (async level)
>> and Timer.fired (sync level).   Hence non-atomic accesses.
>>
>>
>>>
>>> According to the TinyOS book P196, a variable has to be protected by an
>>> atomic statement "*if it is accessed from an async function*". But
>>> seems to me, *"a"* is accessed from an async function in all 3 cases
>>> above and none is protected except
>>> *a = 0;*
>>> in Timer.
>>>
>>
>> The book isn't very clear.
>>
>> Typically async level is used for functions called from interrupt level
>> signals.
>>
>

> Can we replace the rule in the book by "*whenever accessing a shared
> variable introduces racing condition, it must be protected by atomic*"?
>

you can do that.   But....     atomic adds overhead.  I've looked carefully
at the code generated and introduced mechanisms for mitigating the
overhead, but there still is some overhead.   Basically, you are disabling
interrupts and then reenabling them if there were on to begin with.


>
>>
>>>
>>> Can anybody please share the experience on atomic? Thanks in advance.
>>>
>>> --
>>> -Xiaohui Liu
>>>
>>> _______________________________________________
>>> Tinyos-help mailing list
>>> Tinyos-help at millennium.berkeley.edu
>>> https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help
>>>
>>
>>
>>
>> --
>> Eric B. Decker
>> Senior (over 50 :-) Researcher
>>
>>
>>
>
>
> -- TelosB
> -Xiaohui Liu
>



-- 
Eric B. Decker
Senior (over 50 :-) Researcher
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://www.millennium.berkeley.edu/pipermail/tinyos-help/attachments/20120829/7788741e/attachment-0001.htm 


More information about the Tinyos-help mailing list