Module Name:    src
Committed By:   christos
Date:           Thu Oct  3 16:50:52 UTC 2024

Modified Files:
        src/sys/kern: syscalls.master sysv_sem.c
        src/sys/sys: sem.h

Log Message:
Add semtimedop GSoC 2024 (Shivraj Jamgade)


To generate a diff of this commit:
cvs rdiff -u -r1.313 -r1.314 src/sys/kern/syscalls.master
cvs rdiff -u -r1.98 -r1.99 src/sys/kern/sysv_sem.c
cvs rdiff -u -r1.35 -r1.36 src/sys/sys/sem.h

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

Modified files:

Index: src/sys/kern/syscalls.master
diff -u src/sys/kern/syscalls.master:1.313 src/sys/kern/syscalls.master:1.314
--- src/sys/kern/syscalls.master:1.313	Sun May 19 21:30:34 2024
+++ src/sys/kern/syscalls.master	Thu Oct  3 12:50:52 2024
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.313 2024/05/20 01:30:34 christos Exp $
+	$NetBSD: syscalls.master,v 1.314 2024/10/03 16:50:52 christos Exp $
 
 ;	@(#)syscalls.master	8.2 (Berkeley) 1/13/94
 
@@ -1065,3 +1065,6 @@
 			    const struct timespec *timeout, \
 			    const sigset_t *sigmask); }
 505	STD	RUMP	{ int|sys|100|dup3(int from, int to, int flags); }
+506	STD 		{ int|sys||semtimedop(int semid, \
+			    struct sembuf *sops, size_t nsops, \
+			    struct timespec *timeout); }

Index: src/sys/kern/sysv_sem.c
diff -u src/sys/kern/sysv_sem.c:1.98 src/sys/kern/sysv_sem.c:1.99
--- src/sys/kern/sysv_sem.c:1.98	Tue Aug  6 20:38:02 2019
+++ src/sys/kern/sysv_sem.c	Thu Oct  3 12:50:52 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_sem.c,v 1.98 2019/08/07 00:38:02 pgoyette Exp $	*/
+/*	$NetBSD: sysv_sem.c,v 1.99 2024/10/03 16:50:52 christos Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v 1.98 2019/08/07 00:38:02 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v 1.99 2024/10/03 16:50:52 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -800,17 +800,12 @@ sys_semget(struct lwp *l, const struct s
 
 #define SMALL_SOPS 8
 
-int
-sys_semop(struct lwp *l, const struct sys_semop_args *uap, register_t *retval)
+static int
+do_semop(struct lwp *l, int semid, struct sembuf *usops,
+    size_t nsops, struct timespec *utimeout, register_t *retval)
 {
-	/* {
-		syscallarg(int) semid;
-		syscallarg(struct sembuf *) sops;
-		syscallarg(size_t) nsops;
-	} */
 	struct proc *p = l->l_proc;
-	int semid = SCARG(uap, semid), seq;
-	size_t nsops = SCARG(uap, nsops);
+	int semid, seq;
 	struct sembuf small_sops[SMALL_SOPS];
 	struct sembuf *sops;
 	struct semid_ds *semaptr;
@@ -818,12 +813,14 @@ sys_semop(struct lwp *l, const struct sy
 	struct __sem *semptr = NULL;
 	struct sem_undo *suptr = NULL;
 	kauth_cred_t cred = l->l_cred;
+	struct timespec timeout;
+	int timo = 0;
 	int i, error;
 	int do_wakeup, do_undos;
 
 	RUN_ONCE(&exithook_control, seminit_exithook);
 
-	SEM_PRINTF(("call to semop(%d, %p, %zd)\n", semid, SCARG(uap,sops), nsops));
+	SEM_PRINTF(("call to semop(%d, %p, %zu)\n", semid, usops, nsops));
 
 	if (__predict_false((p->p_flag & PK_SYSVSEM) == 0)) {
 		mutex_enter(p->p_lock);
@@ -837,15 +834,15 @@ restart:
 	} else if (nsops <= seminfo.semopm) {
 		sops = kmem_alloc(nsops * sizeof(*sops), KM_SLEEP);
 	} else {
-		SEM_PRINTF(("too many sops (max=%d, nsops=%zd)\n",
+		SEM_PRINTF(("too many sops (max=%d, nsops=%zu)\n",
 		    seminfo.semopm, nsops));
 		return (E2BIG);
 	}
 
-	error = copyin(SCARG(uap, sops), sops, nsops * sizeof(sops[0]));
+	error = copyin(usops, sops, nsops * sizeof(sops[0]));
 	if (error) {
-		SEM_PRINTF(("error = %d from copyin(%p, %p, %zd)\n", error,
-		    SCARG(uap, sops), &sops, nsops * sizeof(sops[0])));
+		SEM_PRINTF(("error = %d from copyin(%p, %p, %zu)\n", error,
+		    usops, &sops, nsops * sizeof(sops[0])));
 		if (sops != small_sops)
 			kmem_free(sops, nsops * sizeof(*sops));
 		return error;
@@ -862,8 +859,21 @@ restart:
 		goto out;
 	}
 
+	if (utimeout) {
+		error = copyin(utimeout, &timeout, sizeof(timeout));
+		if (error) {
+			SEM_PRINTF(("error = %d from copyin(%p, %p, %zu)\n",
+			    error, utimeout, &timeout, sizeof(timeout)));
+			return error;
+		}
+		error = ts2timo(CLOCK_MONOTONIC, TIMER_RELTIME, &timeout,
+		    &timo, NULL);
+		if (error)
+			return error;
+	}
+
 	semaptr = &sema[semid];
-	seq = IPCID_TO_SEQ(SCARG(uap, semid));
+	seq = IPCID_TO_SEQ(semid);
 	if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
 	    semaptr->sem_perm._seq != seq) {
 		error = EINVAL;
@@ -880,7 +890,6 @@ restart:
 			error = EFBIG;
 			goto out;
 		}
-
 	/*
 	 * Loop trying to satisfy the vector of requests.
 	 * If we reach a point where we must wait, any requests already
@@ -964,7 +973,7 @@ restart:
 
 		sem_waiters++;
 		SEM_PRINTF(("semop:  good night!\n"));
-		error = cv_wait_sig(&semcv[semid], &semlock);
+		error = cv_timedwait_sig(&semcv[semid], &semlock, timo);
 		SEM_PRINTF(("semop:  good morning (error=%d)!\n", error));
 		sem_waiters--;
 
@@ -998,12 +1007,14 @@ restart:
 
 		/* Is it really morning, or was our sleep interrupted? */
 		if (error != 0) {
-			error = EINTR;
+			if (error == ERESTART)
+				error = EINTR;  // Simplify to just EINTR
+			else if (error == EWOULDBLOCK)
+				error = EAGAIN;  // Convert timeout to EAGAIN
 			goto out;
 		}
 		SEM_PRINTF(("semop:  good morning!\n"));
 	}
-
 done:
 	/*
 	 * Process any SEM_UNDO requests.
@@ -1074,13 +1085,46 @@ done:
 	SEM_PRINTF(("semop:  done\n"));
 	*retval = 0;
 
- out:
+out:
 	mutex_exit(&semlock);
 	if (sops != small_sops)
 		kmem_free(sops, nsops * sizeof(*sops));
 	return error;
 }
 
+int
+sys_semtimedop(struct lwp *l, const struct sys_semtimedop_args *uap,
+    register_t *retval)
+{
+	/* {
+		syscallarg(int) semid;
+		syscallarg(struct sembuf *) sops;
+		syscallarg(size_t) nsops;
+		syscallarg(struct timespec) timeout;
+	} */
+	int semid = SCARG(uap, semid);
+	struct sembuf *sops = SCARG(uap, sops);
+	size_t nsops = SCARG(uap, nsops);
+	struct timespec *utimeout = SCARG(uap, timeout);
+
+	return do_semop(l, semid, sops, nsops, utimeout, retval);
+}
+
+int
+sys_semop(struct lwp *l, const struct sys_semop_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(int) semid;
+		syscallarg(struct sembuf *) sops;
+		syscallarg(size_t) nsops;
+	} */
+	int semid = SCARG(uap, semid);
+	struct sembuf *sops = SCARG(uap, sops);
+	size_t nsops = SCARG(uap, nsops);
+
+	return do_semop(l, semid, sops, nsops, NULL, retval);
+}
+
 /*
  * Go through the undo structures for this process and apply the
  * adjustments to semaphores.

Index: src/sys/sys/sem.h
diff -u src/sys/sys/sem.h:1.35 src/sys/sys/sem.h:1.36
--- src/sys/sys/sem.h:1.35	Sun May 12 06:34:56 2024
+++ src/sys/sys/sem.h	Thu Oct  3 12:50:52 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: sem.h,v 1.35 2024/05/12 10:34:56 rillig Exp $	*/
+/*	$NetBSD: sem.h,v 1.36 2024/10/03 16:50:52 christos Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -217,6 +217,8 @@ int	semctl(int, int, int, ...) __RENAME(
 #endif
 int	semget(key_t, int, int);
 int	semop(int, struct sembuf *, size_t);
+struct timespec;
+int	semtimedop(int, struct sembuf *, size_t, struct timespec *);
 #if defined(_NETBSD_SOURCE)
 int	semconfig(int);
 #endif

Reply via email to