gettimeofday seconds rollover problem?
Chris Johns
chrisj at rtems.org
Wed Feb 22 23:27:03 UTC 2006
Joel Sherrill wrote:
>
> The seconds and nanoseconds values are grabbed/computed with interrupts
> disabled so I don't think that would be the problem.
No they are not and it is the problem. The interrupts are being enable
just after they are being disabled. Here is the code:
00000000 <gettimeofday>:
gettimeofday():
../../../../../head/cpukit/libcsupport/src/__gettod.c:50
0: 4e56 0000 linkw %fp,#0
4: 206e 0008 moveal %fp@(8),%a0
../../../../../head/cpukit/libcsupport/src/__gettod.c:55
8: 4a88 tstl %a0
a: 6736 beqs 42 <gettimeofday+0x42>
../../../../../head/cpukit/libcsupport/src/__gettod.c:67
c: 203c 0000 0700 movel #1792,%d0
12: 2200 movel %d0,%d1
14: 40c0 movew %sr,%d0
16: 8280 orl %d0,%d1
18: 46c1 movew %d1,%sr
^^^^^^^^^^^^^ DISABLED
../../../../../head/cpukit/libcsupport/src/__gettod.c:70
1a: 46c0 movew %d0,%sr
^^^^^^^^^^^^^ ENABLED
The remainder of the code is the reading of the time:
../../../../../head/cpukit/libcsupport/src/__gettod.c:72
1c: 2039 0000 0000 movel 0 <gettimeofday>,%d0
22: 0680 21da e500 addil #567993600,%d0
28: 2080 movel %d0,%a0@
../../../../../head/cpukit/libcsupport/src/__gettod.c:73
2a: 2239 0000 0000 movel 0 <gettimeofday>,%d1
30: 2039 0000 0000 movel 0 <gettimeofday>,%d0
36: 4c00 1800 mulsl %d0,%d1
3a: 2141 0004 movel %d1,%a0@(4)
3e: 4280 clrl %d0
40: 6010 bras 52 <gettimeofday+0x52>
../../../../../head/cpukit/libcsupport/src/__gettod.c:56
42: 4eb9 0000 0000 jsr 0 <gettimeofday>
48: 2040 moveal %d0,%a0
4a: 20bc 0000 000e movel #14,%a0@
50: 70ff moveq #-1,%d0
52: 4e5e unlk %fp
54: 4e75 rts
I wonder where else in the kernel this is happening and to which other
targets. I see the i386 also has problems. In the i386 only one value is
being read with interrupts masked:
rtems_interrupt_disable(level);
c: 9c pushf
d: fa cli
e: 58 pop %eax
cpukit/libcsupport/src/__gettod.c:69
seconds = _TOD_Seconds_since_epoch;
microseconds = _TOD_Current.ticks;
f: 8b 15 18 00 00 00 mov 0x18,%edx
^^^^^^^^^^^^^^^^ ONLY ONE READ
cpukit/libcsupport/src/__gettod.c:70
rtems_interrupt_enable(level);
15: 50 push %eax
16: 9d popf
cpukit/libcsupport/src/__gettod.c:72
tp->tv_sec = seconds + POSIX_TIME_SECONDS_1970_THROUGH_1988;
17: a1 00 00 00 00 mov 0x0,%eax
^^^^^^^^^^^^^^^ THE OTHER READ
1c: 05 00 e5 da 21 add $0x21dae500,%eax
21: 89 01 mov %eax,(%ecx)
> The asm volatile statements
> should provide sync points for the compiler if a partial read of memory were
> an issue.
If this is the case it would seem we have a problem with our asm
statements or the compiler has a bug.
Regards
Chris
More information about the users
mailing list