diff options
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/Makefile.inc | 1 | ||||
-rw-r--r-- | lib/libc/gen/Symbol.map | 4 | ||||
-rw-r--r-- | lib/libc/gen/sem_new.c | 53 | ||||
-rw-r--r-- | lib/libc/gen/sem_timedwait.3 | 62 | ||||
-rw-r--r-- | lib/libc/include/namespace.h | 1 | ||||
-rw-r--r-- | lib/libc/include/un-namespace.h | 1 |
6 files changed, 97 insertions, 25 deletions
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index a75a0d1..f1d1378 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -461,6 +461,7 @@ MLINKS+=scandir.3 alphasort.3 MLINKS+=sem_open.3 sem_close.3 \ sem_open.3 sem_unlink.3 MLINKS+=sem_wait.3 sem_trywait.3 +MLINKS+=sem_timedwait.3 sem_clockwait_np.3 MLINKS+=send.2 sendmmsg.2 MLINKS+=setjmp.3 _longjmp.3 \ setjmp.3 _setjmp.3 \ diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 0d5dfec..f452297 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -418,6 +418,10 @@ FBSD_1.4 { stravis; }; +FBSD_1.5 { + sem_clockwait_np; +}; + FBSDprivate_1.0 { /* needed by thread libraries */ __thr_jtable; diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c index 8fe027f..d36d1e2 100644 --- a/lib/libc/gen/sem_new.c +++ b/lib/libc/gen/sem_new.c @@ -56,6 +56,7 @@ __weak_reference(_sem_init, sem_init); __weak_reference(_sem_open, sem_open); __weak_reference(_sem_post, sem_post); __weak_reference(_sem_timedwait, sem_timedwait); +__weak_reference(_sem_clockwait_np, sem_clockwait_np); __weak_reference(_sem_trywait, sem_trywait); __weak_reference(_sem_unlink, sem_unlink); __weak_reference(_sem_wait, sem_wait); @@ -345,23 +346,34 @@ usem_wake(struct _usem2 *sem) } static __inline int -usem_wait(struct _usem2 *sem, const struct timespec *abstime) +usem_wait(struct _usem2 *sem, clockid_t clock_id, int flags, + const struct timespec *rqtp, struct timespec *rmtp) { - struct _umtx_time *tm_p, timeout; + struct { + struct _umtx_time timeout; + struct timespec remain; + } tms; + void *tm_p; size_t tm_size; + int retval; - if (abstime == NULL) { + if (rqtp == NULL) { tm_p = NULL; tm_size = 0; } else { - timeout._clockid = CLOCK_REALTIME; - timeout._flags = UMTX_ABSTIME; - timeout._timeout = *abstime; - tm_p = &timeout; - tm_size = sizeof(timeout); + tms.timeout._clockid = clock_id; + tms.timeout._flags = (flags & TIMER_ABSTIME) ? UMTX_ABSTIME : 0; + tms.timeout._timeout = *rqtp; + tm_p = &tms; + tm_size = sizeof(tms); } - return _umtx_op(sem, UMTX_OP_SEM2_WAIT, 0, - (void *)tm_size, __DECONST(void*, tm_p)); + retval = _umtx_op(sem, UMTX_OP_SEM2_WAIT, 0, (void *)tm_size, tm_p); + if (retval == -1 && errno == EINTR && (flags & TIMER_ABSTIME) == 0 && + rqtp != NULL && rmtp != NULL) { + *rmtp = tms.remain; + } + + return (retval); } int @@ -381,8 +393,8 @@ _sem_trywait(sem_t *sem) } int -_sem_timedwait(sem_t * __restrict sem, - const struct timespec * __restrict abstime) +_sem_clockwait_np(sem_t * __restrict sem, clockid_t clock_id, int flags, + const struct timespec *rqtp, struct timespec *rmtp) { int val, retval; @@ -393,7 +405,8 @@ _sem_timedwait(sem_t * __restrict sem, _pthread_testcancel(); for (;;) { while (USEM_COUNT(val = sem->_kern._count) > 0) { - if (atomic_cmpset_acq_int(&sem->_kern._count, val, val - 1)) + if (atomic_cmpset_acq_int(&sem->_kern._count, val, + val - 1)) return (0); } @@ -406,20 +419,28 @@ _sem_timedwait(sem_t * __restrict sem, * The timeout argument is only supposed to * be checked if the thread would have blocked. */ - if (abstime != NULL) { - if (abstime->tv_nsec >= 1000000000 || abstime->tv_nsec < 0) { + if (rqtp != NULL) { + if (rqtp->tv_nsec >= 1000000000 || rqtp->tv_nsec < 0) { errno = EINVAL; return (-1); } } _pthread_cancel_enter(1); - retval = usem_wait(&sem->_kern, abstime); + retval = usem_wait(&sem->_kern, clock_id, flags, rqtp, rmtp); _pthread_cancel_leave(0); } return (retval); } int +_sem_timedwait(sem_t * __restrict sem, + const struct timespec * __restrict abstime) +{ + return (_sem_clockwait_np(sem, CLOCK_REALTIME, TIMER_ABSTIME, abstime, + NULL)); +}; + +int _sem_wait(sem_t *sem) { return _sem_timedwait(sem, NULL); diff --git a/lib/libc/gen/sem_timedwait.3 b/lib/libc/gen/sem_timedwait.3 index 254af60..1623ebe 100644 --- a/lib/libc/gen/sem_timedwait.3 +++ b/lib/libc/gen/sem_timedwait.3 @@ -34,18 +34,22 @@ .\" .\" $FreeBSD$ .\" -.Dd March 3, 2008 +.Dd March 10, 2017 .Dt SEM_TIMEDWAIT 3 .Os .Sh NAME -.Nm sem_timedwait +.Nm sem_timedwait , +.Nm sem_clockwait_np .Nd "lock a semaphore" .Sh LIBRARY .Lb libpthread .Sh SYNOPSIS .In semaphore.h +.In time.h .Ft int .Fn sem_timedwait "sem_t *sem" "const struct timespec *abs_timeout" +.Ft int +.Fn sem_clockwait_np "sem_t * restrict sem" "clockid_t clock_id" "int flags" "const struct timespec * rqtp" "struct timespec * rmtp" .Sh DESCRIPTION The .Fn sem_timedwait @@ -77,10 +81,40 @@ clock. The validity of the .Fa abs_timeout is not checked if the semaphore can be locked immediately. -.Sh RETURN VALUES +.Pp The -.Fn sem_timedwait -function returns zero if the calling process successfully performed the +.Fn sem_clockwait_np +function is a more flexible variant of +.Fn sem_timedwait . +The +.Fa clock_id +parameter specifies the reference clock. +If the +.Fa flags +parameter contains +.Dv TIMER_ABSTIME , +then the requested timeout +.Pq Fa rqtp +is an absolute timeout; otherwise, +the timeout is relative. +If this function fails with +.Er EINTR +and the timeout is relative, +a non-NULL +.Fa rmtp +will be updated to contain the amount of time remaining in the interval +.Po +the requested time minus the time actually slept +.Pc . +An absolute timeout has no effect on +.Fa rmtp . +A single structure can be used for both +.Fa rqtp +and +.Fa rmtp . +.Sh RETURN VALUES +These +functions return zero if the calling process successfully performed the semaphore lock operation on the semaphore designated by .Fa sem . If the call was unsuccessful, the state of the semaphore is unchanged, @@ -88,9 +122,7 @@ and the function returns a value of \-1 and sets the global variable .Va errno to indicate the error. .Sh ERRORS -The -.Fn sem_timedwait -function will fail if: +These functions will fail if: .Bl -tag -width Er .It Bq Er EINVAL The @@ -114,6 +146,18 @@ The .Fn sem_timedwait function conforms to .St -p1003.1-2004 . +The +.Fn sem_clockwait_np +function is not specified by any standard; +it exists only on +.Fx +at the time of this writing. .Sh HISTORY -The function first appeared in +The +.Fn sem_timedwait +function first appeared in .Fx 5.0 . +The +.Fn sem_clockwait_np +function first appeared in +.Fx 12.0 . diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h index c95829e..52e9b25 100644 --- a/lib/libc/include/namespace.h +++ b/lib/libc/include/namespace.h @@ -217,6 +217,7 @@ #define sem_open _sem_open #define sem_post _sem_post #define sem_timedwait _sem_timedwait +#define sem_clockwait_np _sem_clockwait_np #define sem_trywait _sem_trywait #define sem_unlink _sem_unlink #define sem_wait _sem_wait diff --git a/lib/libc/include/un-namespace.h b/lib/libc/include/un-namespace.h index 0233348..e40e6fd 100644 --- a/lib/libc/include/un-namespace.h +++ b/lib/libc/include/un-namespace.h @@ -198,6 +198,7 @@ #undef sem_open #undef sem_post #undef sem_timedwait +#undef sem_clockwait_np #undef sem_trywait #undef sem_unlink #undef sem_wait |