From: Konstantin Belousov <k...@freebsd.org>

Tested by:      O'Connor, Daniel <dar...@dons.net.au>
Sponsored by:   The FreeBSD Foundation
MFC after:      1 week
Differential revision:  https://reviews.freebsd.org/D21563

This patch was modified by Sebastian Huber
<sebastian.hu...@embedded-brains.de> to adjust it for RTEMS.  See
comment in the patch.
---
 cpukit/score/src/kern_tc.c | 50 ++++++++++++++++++++++++++++++++++----
 1 file changed, 45 insertions(+), 5 deletions(-)

diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c
index 21d018a671..3aa68f7595 100644
--- a/cpukit/score/src/kern_tc.c
+++ b/cpukit/score/src/kern_tc.c
@@ -167,6 +167,35 @@ struct timehands {
        struct timehands        *th_next;
 };
 
+#ifndef __rtems__
+static struct timehands ths[16] = {
+    [0] =  {
+       .th_counter = &dummy_timecounter,
+       .th_scale = (uint64_t)-1 / 1000000,
+       .th_offset = { .sec = 1 },
+       .th_generation = 1,
+    },
+};
+
+static struct timehands *volatile timehands = &ths[0];
+struct timecounter *timecounter = &dummy_timecounter;
+static struct timecounter *timecounters = &dummy_timecounter;
+
+int tc_min_ticktock_freq = 1;
+#else /* __rtems__ */
+/*
+ * In FreeBSD, the timehands count is a tuning option from two to 16.  The
+ * tuning option was added since it is inexpensive and some FreeBSD users asked
+ * for it to play around.  The default value is two.  One system which did not
+ * work with two timehands was a system with one processor and a specific PPS
+ * device.
+ *
+ * For RTEMS, in uniprocessor configurations, just use one timehand since the
+ * update is done with interrupt disabled.
+ *
+ * In SMP configurations, use a fixed set of two timehands until someone
+ * reports an issue.
+ */
 #if defined(RTEMS_SMP)
 static struct timehands th0;
 static struct timehands th1 = {
@@ -193,10 +222,6 @@ static struct timehands th0 = {
 
 static struct timehands *volatile timehands = &th0;
 struct timecounter *timecounter = &dummy_timecounter;
-#ifndef __rtems__
-static struct timecounter *timecounters = &dummy_timecounter;
-
-int tc_min_ticktock_freq = 1;
 #endif /* __rtems__ */
 
 #ifndef __rtems__
@@ -219,6 +244,10 @@ static int timestepwarnings;
 SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW,
     &timestepwarnings, 0, "Log time steps");
 
+static int timehands_count = 2;
+SYSCTL_INT(_kern_timecounter, OID_AUTO, timehands_count, CTLFLAG_RDTUN,
+    &timehands_count, 0, "Count of timehands in rotation");
+
 struct bintime bt_timethreshold;
 struct bintime bt_tickthreshold;
 sbintime_t sbt_timethreshold;
@@ -2216,8 +2245,9 @@ done:
 static void
 inittimecounter(void *dummy)
 {
+       struct timehands *thp;
        u_int p;
-       int tick_rate;
+       int i, tick_rate;
 
        /*
         * Set the initial timeout to
@@ -2243,6 +2273,16 @@ inittimecounter(void *dummy)
 #ifdef FFCLOCK
        ffclock_init();
 #endif
+
+       /* Set up the requested number of timehands. */
+       if (timehands_count < 1)
+               timehands_count = 1;
+       if (timehands_count > nitems(ths))
+               timehands_count = nitems(ths);
+       for (i = 1, thp = &ths[0]; i < timehands_count;  thp = &ths[i++])
+               thp->th_next = &ths[i];
+       thp->th_next = &ths[0];
+
        /* warm up new timecounter (again) and get rolling. */
        (void)timecounter->tc_get_timecount(timecounter);
        (void)timecounter->tc_get_timecount(timecounter);
-- 
2.17.1

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to