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--