Deleted Added
full compact
29c29
< __FBSDID("$FreeBSD: head/sys/kern/kern_umtx.c 216463 2010-12-15 19:30:44Z mdf $");
---
> __FBSDID("$FreeBSD: head/sys/kern/kern_umtx.c 216641 2010-12-22 05:01:52Z davidxu $");
45a46
> #include <sys/syscallsubr.h>
2353a2355
> uint32_t clockid;
2360a2363,2374
>
> if ((wflags & CVWAIT_CLOCKID) != 0) {
> clockid = fuword32(&cv->c_clockid);
> if (clockid < CLOCK_REALTIME ||
> clockid >= CLOCK_THREAD_CPUTIME_ID) {
> /* hmm, only HW clock id will work. */
> return (EINVAL);
> }
> } else {
> clockid = CLOCK_REALTIME;
> }
>
2367,2368c2381,2382
< * The magic thing is we should set c_has_waiters to 1 before
< * releasing user mutex.
---
> * Set c_has_waiters to 1 before releasing user mutex, also
> * don't modify cache line when unnecessary.
2370c2384,2385
< suword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), 1);
---
> if (fuword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters)) == 0)
> suword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), 1);
2380,2384c2395
< if ((wflags & UMTX_CHECK_UNPARKING) &&
< (td->td_pflags & TDP_WAKEUP)) {
< td->td_pflags &= ~TDP_WAKEUP;
< error = EINTR;
< } else if (timeout == NULL) {
---
> if (timeout == NULL) {
2387,2389c2398,2408
< getnanouptime(&ets);
< timespecadd(&ets, timeout);
< TIMESPEC_TO_TIMEVAL(&tv, timeout);
---
> if ((wflags & CVWAIT_ABSTIME) == 0) {
> kern_clock_gettime(td, clockid, &ets);
> timespecadd(&ets, timeout);
> tts = *timeout;
> } else { /* absolute time */
> ets = *timeout;
> tts = *timeout;
> kern_clock_gettime(td, clockid, &cts);
> timespecsub(&tts, &cts);
> }
> TIMESPEC_TO_TIMEVAL(&tv, &tts);
2394c2413
< getnanouptime(&cts);
---
> kern_clock_gettime(td, clockid, &cts);
2409c2428,2445
< umtxq_remove(uq);
---
> /*
> * This must be timeout,interrupted by signal or
> * surprious wakeup, clear c_has_waiter flag when
> * necessary.
> */
> umtxq_busy(&uq->uq_key);
> if ((uq->uq_flags & UQF_UMTXQ) != 0) {
> int oldlen = uq->uq_cur_queue->length;
> umtxq_remove(uq);
> if (oldlen == 1) {
> umtxq_unlock(&uq->uq_key);
> suword32(
> __DEVOLATILE(uint32_t *,
> &cv->c_has_waiters), 0);
> umtxq_lock(&uq->uq_key);
> }
> }
> umtxq_unbusy(&uq->uq_key);
3031a3068
> #define BATCH_SIZE 128
3032a3070,3094
> __umtx_op_nwake_private(struct thread *td, struct _umtx_op_args *uap)
> {
> int count = uap->val;
> void *uaddrs[BATCH_SIZE];
> char **upp = (char **)uap->obj;
> int tocopy;
> int error = 0;
> int i, pos = 0;
>
> while (count > 0) {
> tocopy = count;
> if (tocopy > BATCH_SIZE)
> tocopy = BATCH_SIZE;
> error = copyin(upp+pos, uaddrs, tocopy * sizeof(char *));
> if (error != 0)
> break;
> for (i = 0; i < tocopy; ++i)
> kern_umtx_wake(td, uaddrs[i], INT_MAX, 1);
> count -= tocopy;
> pos += tocopy;
> }
> return (error);
> }
>
> static int
3248c3310,3311
< __umtx_op_sem_wake /* UMTX_OP_SEM_WAKE */
---
> __umtx_op_sem_wake, /* UMTX_OP_SEM_WAKE */
> __umtx_op_nwake_private /* UMTX_OP_NWAKE_PRIVATE */
3489a3553,3578
> static int
> __umtx_op_nwake_private32(struct thread *td, struct _umtx_op_args *uap)
> {
> int count = uap->val;
> uint32_t uaddrs[BATCH_SIZE];
> uint32_t **upp = (uint32_t **)uap->obj;
> int tocopy;
> int error = 0;
> int i, pos = 0;
>
> while (count > 0) {
> tocopy = count;
> if (tocopy > BATCH_SIZE)
> tocopy = BATCH_SIZE;
> error = copyin(upp+pos, uaddrs, tocopy * sizeof(uint32_t));
> if (error != 0)
> break;
> for (i = 0; i < tocopy; ++i)
> kern_umtx_wake(td, (void *)(intptr_t)uaddrs[i],
> INT_MAX, 1);
> count -= tocopy;
> pos += tocopy;
> }
> return (error);
> }
>
3511c3600,3601
< __umtx_op_sem_wake /* UMTX_OP_SEM_WAKE */
---
> __umtx_op_sem_wake, /* UMTX_OP_SEM_WAKE */
> __umtx_op_nwake_private32 /* UMTX_OP_NWAKE_PRIVATE */