diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-10-11 17:10:29 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-10-12 13:54:23 +0200 |
commit | 9cc3b7466f3a516f290f8f11a2e0b80f9568b564 (patch) | |
tree | 7b886479a2433ad7db970f616cd6a0ed911ac2a8 | |
parent | 9c21cfc1dc6f5c2980a692fdfc87f4e7cb3e8222 (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.c | 27 |
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 |