Thanks again for your promptly reply. I still have a few follow-up questions, please CIL.
On Wed, Aug 29, 2012 at 8:38 PM, Eric Decker <[email protected]> wrote: > > > On Wed, Aug 29, 2012 at 4:40 PM, Xiaohui Liu <[email protected]> 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 <[email protected]> wrote: >> >>> >>> >>> On Mon, Aug 27, 2012 at 6:59 PM, Xiaohui Liu <[email protected]> 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. > 1) What is the difference? The assumption that nesc makes is that there are two levels of context and > that the async context doesn't get interrupted. > 2) If async context does not get interrupted, then there should never be atomic in async context, at least when no interrupt is TOSH_INTERRUPT. But this is clearly not the case. For instance, the following can be found in CC2420ReceiveP.nc * async event void InterruptFIFOP.fired() {* * if ( m_state == S_STARTED ) {* *#ifndef CC2420_HW_SECURITY* * m_state = S_RX_LENGTH;* * beginReceive();* *#else* * m_state = S_RX_DEC;* * atomic receivingPacket = TRUE;* * beginDec();* *#endif* * } else {* * m_missed_packets++;* * }* * }* So all such atomic are redundant? So if two async pieces access the same variable it assumes that there > isn't a race condition. > 3) What about async context cased by TOSH_INTERRUPT in msp430, or equivalently, by AVR_NONATOMIC_HANDLER in avr? For example, variable *a*is accessed both from AVR_NONATOMIC_HANDLER(SIG_OUTPUT_COMPARE3B) and AVR_NONATOMIC_HANDLER(SIG_OUTPUT_COMPARE3C) in HplAtm1281Timer3P.nc. There is a race condition here and it is compliant with nesc. 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 >>>> [email protected] >>>> 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 > > > -- -Xiaohui Liu
_______________________________________________ Tinyos-help mailing list [email protected] https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help
