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