Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135925153
D9656.id25354.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D9656.id25354.diff
View Options
Index: include/semaphore.h
===================================================================
--- include/semaphore.h
+++ include/semaphore.h
@@ -59,6 +59,8 @@
sem_t *sem_open(const char *, int, ...);
int sem_post(sem_t *);
int sem_timedwait(sem_t * __restrict, const struct timespec * __restrict);
+int sem_timedwait5_np(sem_t * __restrict, __clockid_t, int,
+ const struct timespec *, struct timespec *);
int sem_trywait(sem_t *);
int sem_unlink(const char *);
int sem_wait(sem_t *);
Index: lib/libc/gen/Makefile.inc
===================================================================
--- lib/libc/gen/Makefile.inc
+++ lib/libc/gen/Makefile.inc
@@ -463,6 +463,7 @@
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_timedwait5_np.3
MLINKS+=send.2 sendmmsg.2
MLINKS+=setjmp.3 _longjmp.3 \
setjmp.3 _setjmp.3 \
Index: lib/libc/gen/Symbol.map
===================================================================
--- lib/libc/gen/Symbol.map
+++ lib/libc/gen/Symbol.map
@@ -415,6 +415,7 @@
FBSD_1.5 {
basename;
dirname;
+ sem_timedwait5_np;
};
FBSDprivate_1.0 {
Index: lib/libc/gen/sem_new.c
===================================================================
--- lib/libc/gen/sem_new.c
+++ lib/libc/gen/sem_new.c
@@ -56,6 +56,7 @@
__weak_reference(_sem_open, sem_open);
__weak_reference(_sem_post, sem_post);
__weak_reference(_sem_timedwait, sem_timedwait);
+__weak_reference(_sem_timedwait5_np, sem_timedwait5_np);
__weak_reference(_sem_trywait, sem_trywait);
__weak_reference(_sem_unlink, sem_unlink);
__weak_reference(_sem_wait, sem_wait);
@@ -345,23 +346,34 @@
}
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 @@
}
int
-_sem_timedwait(sem_t * __restrict sem,
- const struct timespec * __restrict abstime)
+_sem_timedwait5_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 @@
_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 @@
* 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_timedwait5_np(sem, CLOCK_REALTIME, TIMER_ABSTIME, abstime,
+ NULL));
+};
+
+int
_sem_wait(sem_t *sem)
{
return _sem_timedwait(sem, NULL);
Index: lib/libc/gen/sem_timedwait.3
===================================================================
--- lib/libc/gen/sem_timedwait.3
+++ lib/libc/gen/sem_timedwait.3
@@ -34,11 +34,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 17, 2016
+.Dd February 18, 2017
.Dt SEM_TIMEDWAIT 3
.Os
.Sh NAME
-.Nm sem_timedwait
+.Nm sem_timedwait ,
+.Nm sem_timedwait5_np
.Nd "lock a semaphore"
.Sh LIBRARY
.Lb libc
@@ -46,6 +47,8 @@
.In semaphore.h
.Ft int
.Fn sem_timedwait "sem_t * restrict sem" "const struct timespec * restrict abs_timeout"
+.Ft int
+.Fn sem_timedwait5_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 +80,40 @@
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_timedwait5_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 +121,7 @@
.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 +145,16 @@
.Fn sem_timedwait
function conforms to
.St -p1003.1-2004 .
+The
+.Fn sem_timedwait5_np
+function is not specified by any standard;
+it exists only on FreeBSD 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_timedwait5_np
+function first appeared in
+.Fx 12.0 .
Index: lib/libc/include/namespace.h
===================================================================
--- lib/libc/include/namespace.h
+++ 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_timedwait5_np _sem_timedwait5_np
#define sem_trywait _sem_trywait
#define sem_unlink _sem_unlink
#define sem_wait _sem_wait
Index: lib/libc/include/un-namespace.h
===================================================================
--- lib/libc/include/un-namespace.h
+++ lib/libc/include/un-namespace.h
@@ -198,6 +198,7 @@
#undef sem_open
#undef sem_post
#undef sem_timedwait
+#undef sem_timedwait5_np
#undef sem_trywait
#undef sem_unlink
#undef sem_wait
Index: share/man/man3/pthread_testcancel.3
===================================================================
--- share/man/man3/pthread_testcancel.3
+++ share/man/man3/pthread_testcancel.3
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-.Dd August 16, 2016
+.Dd February 17, 2017
.Dt PTHREAD_TESTCANCEL 3
.Os
.Sh NAME
@@ -120,9 +120,9 @@
The
.Fn kevent
function is a cancellation point if it is potentially blocking,
-i.e. when the
+such as when the
.Fa nevents
-argument is non-zero.
+argument is non-zero.
.It Fn mq_receive
.It Fn mq_send
.It Fn mq_timedreceive
@@ -146,6 +146,7 @@
.It Fn recvmsg
.It Fn select
.It Fn sem_timedwait
+.It Fn sem_timedwait5_np
.It Fn sem_wait
.It Fn send
.It Fn sendmsg
Index: sys/kern/kern_umtx.c
===================================================================
--- sys/kern/kern_umtx.c
+++ sys/kern/kern_umtx.c
@@ -3219,10 +3219,16 @@
error = 0;
else {
umtxq_remove(uq);
- /* A relative timeout cannot be restarted. */
- if (error == ERESTART && timeout != NULL &&
- (timeout->_flags & UMTX_ABSTIME) == 0)
- error = EINTR;
+ if (timeout != NULL && (timeout->_flags & UMTX_ABSTIME) == 0) {
+ /* A relative timeout cannot be restarted. */
+ if (error == ERESTART)
+ error = EINTR;
+ if (error == EINTR) {
+ abs_timeout_update(&timo);
+ timeout->_timeout = timo.end;
+ timespecsub(&timeout->_timeout, &timo.cur);
+ }
+ }
}
umtxq_unlock(&uq->uq_key);
umtx_key_release(&uq->uq_key);
@@ -3585,19 +3591,33 @@
__umtx_op_sem2_wait(struct thread *td, struct _umtx_op_args *uap)
{
struct _umtx_time *tm_p, timeout;
+ size_t uasize;
int error;
/* Allow a null timespec (wait forever). */
- if (uap->uaddr2 == NULL)
+ if (uap->uaddr2 == NULL) {
+ uasize = 0;
tm_p = NULL;
- else {
- error = umtx_copyin_umtx_time(
- uap->uaddr2, (size_t)uap->uaddr1, &timeout);
+ } else {
+ uasize = (size_t)uap->uaddr1;
+ error = umtx_copyin_umtx_time(uap->uaddr2, uasize, &timeout);
if (error != 0)
return (error);
tm_p = &timeout;
}
- return (do_sem2_wait(td, uap->obj, tm_p));
+ error = do_sem2_wait(td, uap->obj, tm_p);
+ if (error == EINTR && uap->uaddr2 != NULL &&
+ (timeout._flags & UMTX_ABSTIME) == 0 &&
+ uasize >= sizeof(struct _umtx_time) + sizeof(struct timespec)) {
+ error = copyout(&timeout._timeout,
+ (struct _umtx_time *)uap->uaddr2 + 1,
+ sizeof(struct timespec));
+ if (error == 0) {
+ error = EINTR;
+ }
+ }
+
+ return (error);
}
static int
@@ -4194,19 +4214,37 @@
__umtx_op_sem2_wait_compat32(struct thread *td, struct _umtx_op_args *uap)
{
struct _umtx_time *tm_p, timeout;
+ size_t uasize;
int error;
/* Allow a null timespec (wait forever). */
- if (uap->uaddr2 == NULL)
+ if (uap->uaddr2 == NULL) {
+ uasize = 0;
tm_p = NULL;
- else {
- error = umtx_copyin_umtx_time32(uap->uaddr2,
- (size_t)uap->uaddr1, &timeout);
+ } else {
+ uasize = (size_t)uap->uaddr1;
+ error = umtx_copyin_umtx_time32(uap->uaddr2, uasize, &timeout);
if (error != 0)
return (error);
tm_p = &timeout;
}
- return (do_sem2_wait(td, uap->obj, tm_p));
+ error = do_sem2_wait(td, uap->obj, tm_p);
+ if (error == EINTR && uap->uaddr2 != NULL &&
+ (timeout._flags & UMTX_ABSTIME) == 0 &&
+ uasize >= sizeof(struct umtx_time32) + sizeof(struct timespec32)) {
+ struct timespec32 remain32 = {
+ .tv_sec = timeout._timeout.tv_sec,
+ .tv_nsec = timeout._timeout.tv_nsec
+ };
+ error = copyout(&remain32,
+ (struct umtx_time32 *)uap->uaddr2 + 1,
+ sizeof(struct timespec32));
+ if (error == 0) {
+ error = EINTR;
+ }
+ }
+
+ return (error);
}
static int
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 15, 5:27 AM (6 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25317019
Default Alt Text
D9656.id25354.diff (10 KB)
Attached To
Mode
D9656: Add sem_clockwait_np()
Attached
Detach File
Event Timeline
Log In to Comment