gettimeofday seconds rollover problem?
Till Straumann
strauman at slac.stanford.edu
Fri Feb 24 19:09:57 UTC 2006
Joel Sherrill wrote:
> Till Straumann wrote:
>
>> Eric Norum wrote:
>>
>>> On Feb 24, 2006, at 1:16 AM, Andrew Sinclair wrote:
>>>
>>>>
>>>> 1) interesting...
>>>> 2) I think an alternative here is adding all the registers to the
>>>> clobber list in the "barrier", we can force the compiler to reload any
>>>> data into registers, and perform stores within the critical sections.
>>>>
>>>> 3) Yes, on second thoughts I think you have something here. It is
>>>> safer
>>>> as one single asm volatile statement.
>>>>
>>>>
>>>> For example on the Coldfire...
>>>>
>>>> #define m68k_disable_interrupts( _level ) \
>>>> do { register unsigned32 _tmpsr = 0x0700; \
>>>> asm __volatile__ ( "move.w %%sr,%0\n\t" \
>>>> "or.l %0,%1\n\t" \
>>>> "move.w %1,%%sr" \
>>>> : "=d" (_level), "=d"(_tmpsr) : "1"(_tmpsr) \
>>>> :"cc","d0","d1","d2","d3","d4","d5", \
>>>> "a0","a1","a2","a3","a4","a5","a6","memory" ); \
>>>> } while( 0 )
>>>>
>>>> #define m68k_enable_interrupts( _level ) \
>>>> do { asm __volatile__ ( "move.w %0,%%sr " : : "d" (_level) \
>>>> :"cc","d0","d1","d2","d3","d4","d5", \
>>>> "a0","a1","a2","a3","a4","a5","a6","memory" ); \
>>>> } while( 0 )
>>>>
>>>> #define m68k_flash_interrupts( _level ) \
>>>> do { register unsigned32 _tmpsr = 0x0700; \
>>>> asm __volatile__ ( "move.w %2,%%sr\n\t" \
>>>> "or.l %2,%1\n\t" \
>>>> "move.w %1,%%sr" \
>>>> : "=d"(_tmpsr) : "0"(_tmpsr), "d"(_level) \
>>>> :"cc","d0","d1","d2","d3","d4","d5", \
>>>> "a0","a1","a2","a3","a4","a5","a6","memory" ); \
>>>> } while( 0 )
>>>
>>>
>>>
>>>
>>> I *really* don't like this.
>>> Given that the assembly instructions in question don't affect d0-d5/
>>> a0-a6 why would you want to place them in the clobber list?
>>>
>>> To summarize my position:
>>> 1) The _TOD_* variables must be declared as volatile since their
>>> values can change in a fashion (Deus ex machina) not apparent to
>>> compiler.
>>> 2) The M68K_BARRIER macro, or its equivalent addition to the enable/
>>> disable macros, is required to keep the optimizer from hoisting/
>>> sinking any code beyond the interrupt disable/enable operations.
>>> My feeling is that it's clearer and simpler to just add the
>>> "memory", "cc" to the disable/enable macros, but I'm not dogmatic
>>> about this.
>>>
>>> These two steps seem very clear to me since they impart to the
>>> compiler exactly the information needed. Both steps are necessary
>>
>>
>>
>> This is not true. Only the 'volatile' declaration of global variables
>> that are accessed during any kind of 'inlined' protection mechanism
>> (be it interrupts, thread-dispatching, mutex, ...) is necessary
>> (and sufficient).
>>
>> Nobody has addressed my point # 1: adding a memory barrier
>> to rtems_interrupt_disable/enable does not address
>> thread-dispatch-disable
>> protected code. If we're going to add this safe-guard, it should
>> be introduced to thread_dispatch_disable/enable, too.
>>
> Nearly every operation in RTEMS is protected by one of those mechanisms.
> I think you are only concerned with asynchronous modifications
> relative to
> the current thread of execution.
Not sure I understand exactly what you mean. Assume a (global) variable X
that is not touched by an ISR. If some operation does
_Thread_Disable_dispatch();
X++;
_Thread_Enable_dispatch();
Then, for sure, X is not modified by any ISR. However, the compiler could
still move X outside of the safe region (because the dispatch-disable/enable
ops are inlines) so it effectively looks like this
X++
_Thread_Disable_dispatch();
_Thread_Enable_dispatch();
with obvious consequences if a context switch occurs while X++ is in
progress.
T.
> That should mean only variables modified
> during an interrupt handler. This would eliminate _Thread_Executing
> which
> is only modified during startup and in _Thread_Dispatch. That should
> narrow it down to mostly:
>
> _Thread_Heir
> _Context_Switch_necessary
> _Thread_Dispatch_disable_level
> priority bit maps
> whatever clock tick hits
>
>>
>> BTW: I don't think we should modify all the ports!
>
>
> Well I for one am glad to hear a solution that doesn't involve mucking
> around
> with each port. :)
>
>> We should just
>> change score/isr.h:
>>
>> #define _ISR_Disable( _level ) \
>> _CPU_ISR_Disable( _level ) \
>> asm volatile("":::"memory")
>>
>> #define _ISR_Enable( _level ) \
>> asm volatile("":::"memory") \
>> _CPU_ISR_Enable()
>>
>> #define _ISR_Flash( _level ) \
>> asm volatile("":::"memory") \
>> _CPU_ISR_Flash( _level ) \
>> asm volatile("":::"memory")
>>
>> _Thread_Disable_dispatch() should be treated alike.
>>
>> -- Till
>>
>>> and together they should be sufficient.
>>>
>>
>>
>>
>>
>
More information about the users
mailing list