Subject: detaching timecounters (patch)
To: None <tech-kern@netbsd.org>
From: David Young <dyoung@pobox.com>
List: tech-kern
Date: 12/31/2007 00:29:59
--NzB8fVQJ5HfG6fxh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

I'm writing a device detachment routine for geodecntr(4), which provides
a timecounter.  I've come up with the attached routine for detaching
a timecounter.  Is it ok?

Dave

-- 
David Young             OJC Technologies
dyoung@ojctech.com      Urbana, IL * (217) 278-3933 ext 24

--NzB8fVQJ5HfG6fxh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="tc_detach.patch"

Index: sys/kern/kern_tc.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_tc.c,v
retrieving revision 1.28
diff -p -u -u -p -r1.28 kern_tc.c
--- sys/kern/kern_tc.c	15 Dec 2007 18:20:11 -0000	1.28
+++ sys/kern/kern_tc.c	31 Dec 2007 06:23:34 -0000
@@ -466,6 +466,51 @@ tc_init(struct timecounter *tc)
 	mutex_exit(&time_lock);
 }
 
+/*
+ * Stop using a timecounter and remove it from the timecounters list.
+ */
+int
+tc_detach(struct timecounter *target)
+{
+	struct timecounter *best, *tc;
+	struct timecounter **tcp = NULL;
+	int rc = 0, s;
+
+	mutex_enter(&time_lock);
+	s = splsched();
+	for (tcp = &timecounters, tc = timecounters;
+	     tc != NULL;
+	     tcp = &tc->tc_next, tc = tc->tc_next) {
+		if (tc == target)
+			break;
+	}
+	if (tc == NULL) {
+		rc = ESRCH;
+		goto out;
+	}
+	*tcp = tc->tc_next;
+
+	if (timecounter != target)
+		goto out;
+
+	for (best = tc = timecounters; tc != NULL; tc = tc->tc_next) {
+		if (tc->tc_quality > best->tc_quality)
+			best = tc;
+		else if (tc->tc_quality < best->tc_quality)
+			continue;
+		else if (tc->tc_frequency > best->tc_frequency)
+			best = tc;
+	}
+	(void)best->tc_get_timecount(best);
+	(void)best->tc_get_timecount(best);
+	timecounter = best;
+	tc_windup();
+out:
+	splx(s);
+	mutex_exit(&time_lock);
+	return rc;
+}
+
 /* Report the frequency of the current timecounter. */
 u_int64_t
 tc_getfrequency(void)

--NzB8fVQJ5HfG6fxh--