< prev index next >
src/hotspot/os/linux/waitBarrier_linux.cpp
Print this page
rev 53038 : 8214271: Fast primitive to wake many threads
Reviewed-by:
rev 53039 : [mq]: 8214271-3
*** 36,49 ****
os::errno_name(err)); \
} while (false)
#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
! static int futex(volatile int *uaddr, int futex_op, int val,
! const struct timespec *timeout, int *uaddr2, int val3)
{
! return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
}
void LinuxWaitBarrier::arm(int barrier_tag) {
assert(_futex_barrier == 0, "Already armed");
_futex_barrier = barrier_tag;
--- 36,48 ----
os::errno_name(err)); \
} while (false)
#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
! static int futex(volatile int *addr, int futex_op, int op_arg)
{
! return syscall(SYS_futex, addr, futex_op, op_arg, NULL, NULL, 0);
}
void LinuxWaitBarrier::arm(int barrier_tag) {
assert(_futex_barrier == 0, "Already armed");
_futex_barrier = barrier_tag;
*** 57,71 ****
}
void LinuxWaitBarrier::wake() {
assert(_futex_barrier == 0, "Not disarmed");
int s = futex(&_futex_barrier,
! FUTEX_WAKE,
! INT_MAX, /* wake a max of this many threads */
! NULL /* ignored */,
! NULL /* ignored */,
! 0 /* ignored */);
guarantee_with_errno(s > -1, "futex FUTEX_WAKE");
}
void LinuxWaitBarrier::wait(int barrier_tag) {
assert(barrier_tag != 0, "Trying to wait on disarmed value");
--- 56,67 ----
}
void LinuxWaitBarrier::wake() {
assert(_futex_barrier == 0, "Not disarmed");
int s = futex(&_futex_barrier,
! FUTEX_WAKE_PRIVATE,
! INT_MAX /* wake a max of this many threads */);
guarantee_with_errno(s > -1, "futex FUTEX_WAKE");
}
void LinuxWaitBarrier::wait(int barrier_tag) {
assert(barrier_tag != 0, "Trying to wait on disarmed value");
*** 74,93 ****
OrderAccess::fence();
return;
}
do {
int s = futex(&_futex_barrier,
! FUTEX_WAIT,
! barrier_tag, /* should be this tag */
! NULL, /* no timeout */
! NULL, /* ignored */
! 0 /* ignored */);
guarantee_with_errno((s == 0) ||
(s == -1 && errno == EAGAIN) ||
(s == -1 && errno == EINTR),
"futex FUTEX_WAIT");
! // Return value 0, re-check in case of spurious wake-up.
! // EINTR and re-check and go back to waiting.
! // EAGAIN we already are disarmed, we should pass the check,
! // if not re-armed with same tag.
} while (barrier_tag == _futex_barrier);
}
--- 70,85 ----
OrderAccess::fence();
return;
}
do {
int s = futex(&_futex_barrier,
! FUTEX_WAIT_PRIVATE,
! barrier_tag /* should be this tag */);
guarantee_with_errno((s == 0) ||
(s == -1 && errno == EAGAIN) ||
(s == -1 && errno == EINTR),
"futex FUTEX_WAIT");
! // Return value 0: woken up, but re-check in case of spurious wakeup
! // Error EINTR: woken by signal, so re-check and re-wait if necessary.
! // Error EAGAIN: we are already disarmed and so will pass the check
} while (barrier_tag == _futex_barrier);
}
< prev index next >