summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-10-11 17:10:29 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-10-12 13:54:23 +0200
commit9cc3b7466f3a516f290f8f11a2e0b80f9568b564 (patch)
tree7b886479a2433ad7db970f616cd6a0ed911ac2a8
parent9c21cfc1dc6f5c2980a692fdfc87f4e7cb3e8222 (diff)
score: Optimize timehand updates for non-SMP
In uniprocessor configurations, the timehand updates are done with interrupts disabled. So, it is impossible to observe a generation number of zero.
-rw-r--r--cpukit/score/src/kern_tc.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c
index c013c16f87..bfec55a0ba 100644
--- a/cpukit/score/src/kern_tc.c
+++ b/cpukit/score/src/kern_tc.c
@@ -398,7 +398,11 @@ bintime_off(struct bintime *bt, u_int off)
delta = tc_delta(th);
large_delta = th->th_large_delta;
atomic_thread_fence_acq();
+#if defined(RTEMS_SMP)
} while (gen == 0 || gen != th->th_generation);
+#else
+ } while (gen != th->th_generation);
+#endif
if (__predict_false(delta >= large_delta)) {
/* Avoid overflow for scale * delta. */
@@ -429,7 +433,11 @@ getthmember(void *out, size_t out_size, u_int off)
gen = atomic_load_acq_int(&th->th_generation);
memcpy(out, (char *)th + off, out_size);
atomic_thread_fence_acq();
+#if defined(RTEMS_SMP)
} while (gen == 0 || gen != th->th_generation);
+#else
+ } while (gen != th->th_generation);
+#endif
}
#define GETTHMEMBER(dst, member) \
do { \
@@ -564,7 +572,11 @@ _Timecounter_Sbinuptime(void)
delta = tc_delta(th);
large_delta = th->th_large_delta;
atomic_thread_fence_acq();
+#if defined(RTEMS_SMP)
} while (gen == 0 || gen != th->th_generation);
+#else
+ } while (gen != th->th_generation);
+#endif
if (__predict_false(delta >= large_delta)) {
/* Avoid overflow for scale * delta. */
@@ -1556,7 +1568,10 @@ _Timecounter_Windup(struct bintime *new_boottimebin,
struct bintime bt;
struct timehands *th, *tho;
uint64_t scale;
- uint32_t delta, ncount, ogen;
+ uint32_t delta, ncount;
+#if defined(RTEMS_SMP)
+ u_int ogen;
+#endif
#ifndef __rtems__
int i;
time_t t;
@@ -1574,14 +1589,12 @@ _Timecounter_Windup(struct bintime *new_boottimebin,
tho = timehands;
#if defined(RTEMS_SMP)
th = tho->th_next;
-#else
- th = tho;
-#endif
ogen = th->th_generation;
th->th_generation = 0;
atomic_thread_fence_rel();
-#if defined(RTEMS_SMP)
memcpy(th, tho, offsetof(struct timehands, th_generation));
+#else
+ th = tho;
#endif
if (new_boottimebin != NULL)
th->th_boottime = *new_boottimebin;
@@ -1718,6 +1731,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin,
/* See above "Now is a good time to change timecounters." */
#endif /* __rtems__ */
+#if defined(RTEMS_SMP)
/*
* Now that the struct timehands is again consistent, set the new
* generation number, making sure to not make it zero.
@@ -1725,6 +1739,9 @@ _Timecounter_Windup(struct bintime *new_boottimebin,
if (++ogen == 0)
ogen = 1;
atomic_store_rel_int(&th->th_generation, ogen);
+#else
+ atomic_store_rel_int(&th->th_generation, th->th_generation + 1);
+#endif
/* Go live with the new struct timehands. */
#ifdef FFCLOCK