summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/kern_tc.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2019-09-09 11:29:58 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-15 08:56:53 +0100
commit71b71d6ad2733f60845938cac3d51b9010d6f840 (patch)
tree1f8c4de8a6fc9825419c8c50f2d9e1b1a8a286c9 /cpukit/score/src/kern_tc.c
parentInstead of using an incomplete list of platforms (diff)
downloadrtems-71b71d6ad2733f60845938cac3d51b9010d6f840.tar.bz2
Make timehands count selectable at boottime.
Tested by: O'Connor, Daniel <darius@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.huber@embedded-brains.de> to adjust it for RTEMS. See comment in the patch.
Diffstat (limited to '')
-rw-r--r--cpukit/score/src/kern_tc.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c
index cc2b47aeb8..88680db2c3 100644
--- a/cpukit/score/src/kern_tc.c
+++ b/cpukit/score/src/kern_tc.c
@@ -184,6 +184,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 = {
@@ -210,10 +239,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__
@@ -236,6 +261,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;
@@ -2233,8 +2262,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
@@ -2260,6 +2290,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);