clock_systimer: 64-bit timer accesses are not atomic. Noted by Freddie Chopin.

This commit is contained in:
Gregory Nutt
2016-01-22 12:24:36 -06:00
parent 7ead6b4972
commit 84d4cb007b
3 changed files with 33 additions and 9 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
############################################################################
# sched/clock/Make.defs
#
# Copyright (C) 2014 Gregory Nutt. All rights reserved.
# Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
+24 -6
View File
@@ -80,7 +80,8 @@
systime_t clock_systimer(void)
{
#ifdef CONFIG_SCHED_TICKLESS
#ifdef CONFIG_SYSTEM_TIME64
# ifdef CONFIG_SYSTEM_TIME64
struct timespec ts;
/* Get the time from the platform specific hardware */
@@ -90,7 +91,9 @@ systime_t clock_systimer(void)
/* Convert to a 64-bit value in microseconds, then in clock tick units */
return USEC2TICK(1000000 * (uint64_t)ts.tv_sec + (uint64_t)ts.tv_nsec / 1000);
#else
# else /* CONFIG_SYSTEM_TIME64 */
struct timespec ts;
uint64_t tmp;
@@ -98,16 +101,31 @@ systime_t clock_systimer(void)
(void)up_timer_gettime(&ts);
/* Convert to a 64- then 32-bit value */
/* Convert to a 64- then a 32-bit value */
tmp = MSEC2TICK(1000 * (uint64_t)ts.tv_sec + (uint64_t)ts.tv_nsec / 1000000);
return (systime_t)(tmp & 0x00000000ffffffff);
#endif
#else
# endif /* CONFIG_SYSTEM_TIME64 */
#else /* CONFIG_SCHED_TICKLESS */
# ifdef CONFIG_SYSTEM_TIME64
irqstate_t flags;
systime_t sample;
/* 64-bit accesses are not atomic on most architectures. */
flags = irqsave();
sample = g_system_timer;
irqrestore(flags);
return sample;
# else /* CONFIG_SYSTEM_TIME64 */
/* Return the current system time */
return g_system_timer;
#endif
# endif /* CONFIG_SYSTEM_TIME64 */
#endif /* CONFIG_SCHED_TICKLESS */
}