Module Name:    src
Committed By:   thorpej
Date:           Fri Dec  4 00:26:16 UTC 2020

Modified Files:
        src/sys/compat/linux/common: linux_misc_notalpha.c

Log Message:
Rewrite linux_sys_alarm() to use dogetitimer() / dosetitimer(), rather
than fiddling with process timers directly.


To generate a diff of this commit:
cvs rdiff -u -r1.110 -r1.111 \
    src/sys/compat/linux/common/linux_misc_notalpha.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/compat/linux/common/linux_misc_notalpha.c
diff -u src/sys/compat/linux/common/linux_misc_notalpha.c:1.110 src/sys/compat/linux/common/linux_misc_notalpha.c:1.111
--- src/sys/compat/linux/common/linux_misc_notalpha.c:1.110	Thu Nov 29 17:40:12 2018
+++ src/sys/compat/linux/common/linux_misc_notalpha.c	Fri Dec  4 00:26:16 2020
@@ -1,7 +1,7 @@
-/*	$NetBSD: linux_misc_notalpha.c,v 1.110 2018/11/29 17:40:12 maxv Exp $	*/
+/*	$NetBSD: linux_misc_notalpha.c,v 1.111 2020/12/04 00:26:16 thorpej Exp $	*/
 
 /*-
- * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 1995, 1998, 2008, 2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.110 2018/11/29 17:40:12 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.111 2020/12/04 00:26:16 thorpej Exp $");
 
 /*
  * Note that we must NOT include "opt_compat_linux32.h" here,
@@ -88,9 +88,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_misc_n
 
 /*
  * Alarm. This is a libc call which uses setitimer(2) in NetBSD.
- * Fiddle with the timers to make it work.
- *
- * XXX This shouldn't be dicking about with the ptimer stuff directly.
+ * Do the same here.
  */
 int
 linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_t *retval)
@@ -99,98 +97,28 @@ linux_sys_alarm(struct lwp *l, const str
 		syscallarg(unsigned int) secs;
 	} */
 	struct proc *p = l->l_proc;
-	struct timespec now;
-	struct itimerspec *itp, it;
-	struct ptimer *ptp, *spare;
-	extern kmutex_t timer_lock;
-	struct ptimers *pts;
-
-	if ((pts = p->p_timers) == NULL)
-		pts = timers_alloc(p);
-	spare = NULL;
-
- retry:
-	mutex_spin_enter(&timer_lock);
-	if (pts && pts->pts_timers[ITIMER_REAL])
-		itp = &pts->pts_timers[ITIMER_REAL]->pt_time;
-	else
-		itp = NULL;
-	/*
-	 * Clear any pending timer alarms.
-	 */
-	if (itp) {
-		callout_stop(&pts->pts_timers[ITIMER_REAL]->pt_ch);
-		timespecclear(&itp->it_interval);
-		getnanotime(&now);
-		if (timespecisset(&itp->it_value) &&
-		    timespeccmp(&itp->it_value, &now, >))
-			timespecsub(&itp->it_value, &now, &itp->it_value);
-		/*
-		 * Return how many seconds were left (rounded up)
-		 */
-		retval[0] = itp->it_value.tv_sec;
-		if (itp->it_value.tv_nsec)
-			retval[0]++;
-	} else {
-		retval[0] = 0;
-	}
+	struct itimerval itv, oitv;
+	int error;
 
-	/*
-	 * alarm(0) just resets the timer.
-	 */
-	if (SCARG(uap, secs) == 0) {
-		if (itp)
-			timespecclear(&itp->it_value);
-		mutex_spin_exit(&timer_lock);
-		return 0;
+	timerclear(&itv.it_interval);
+	itv.it_value.tv_sec = SCARG(uap, secs);
+	itv.it_value.tv_usec = 0;
+	if (itv.it_value.tv_sec < 0) {
+		return EINVAL;
 	}
 
-	/*
-	 * Check the new alarm time for sanity, and set it.
-	 */
-	timespecclear(&it.it_interval);
-	it.it_value.tv_sec = SCARG(uap, secs);
-	it.it_value.tv_nsec = 0;
-	if (itimespecfix(&it.it_value) || itimespecfix(&it.it_interval)) {
-		mutex_spin_exit(&timer_lock);
-		return (EINVAL);
+	if ((error = dogetitimer(p, ITIMER_REAL, &oitv)) != 0) {
+		return error;
 	}
-
-	ptp = pts->pts_timers[ITIMER_REAL];
-	if (ptp == NULL) {
-		if (spare == NULL) {
-			mutex_spin_exit(&timer_lock);
-			spare = pool_get(&ptimer_pool, PR_WAITOK);
-			memset(spare, 0, sizeof(*spare));
-			goto retry;
-		}
-		ptp = spare;
-		spare = NULL;
-		ptp->pt_ev.sigev_notify = SIGEV_SIGNAL;
-		ptp->pt_ev.sigev_signo = SIGALRM;
-		ptp->pt_overruns = 0;
-		ptp->pt_proc = p;
-		ptp->pt_type = CLOCK_REALTIME;
-		ptp->pt_entry = CLOCK_REALTIME;
-		ptp->pt_active = 0;
-		ptp->pt_queued = 0;
-		callout_init(&ptp->pt_ch, CALLOUT_MPSAFE);
-		pts->pts_timers[ITIMER_REAL] = ptp;
+	if (oitv.it_value.tv_usec) {
+		oitv.it_value.tv_sec++;
 	}
 
-	if (timespecisset(&it.it_value)) {
-		/*
-		 * Don't need to check tvhzto() return value, here.
-		 * callout_reset() does it for us.
-		 */
-		getnanotime(&now);
-		timespecadd(&it.it_value, &now, &it.it_value);
-		callout_reset(&ptp->pt_ch, tshzto(&it.it_value),
-		    realtimerexpire, ptp);
+	if ((error = dosetitimer(p, ITIMER_REAL, &itv)) != 0) {
+		return error;
 	}
-	ptp->pt_time = it;
-	mutex_spin_exit(&timer_lock);
 
+	*retval = oitv.it_value.tv_sec;
 	return 0;
 }
 #endif /* !COMPAT_LINUX32 */

Reply via email to