* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#define _GNU_SOURCE
+#define _LGPL_SOURCE
#include <limits.h>
-#include <sys/syscall.h>
#include <unistd.h>
#include <urcu.h>
#include <urcu/futex.h>
-#include <common/error.h>
+#include <common/common.h>
#include "futex.h"
* futex() call. If active, we set the value and wake everyone else we indicate
* that we are gone (cleanup() case).
*/
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
void futex_wait_update(int32_t *futex, int active)
{
if (active) {
uatomic_set(futex, 1);
- futex_async(futex, FUTEX_WAKE,
- INT_MAX, NULL, NULL, 0);
+ if (futex_async(futex, FUTEX_WAKE,
+ INT_MAX, NULL, NULL, 0) < 0) {
+ PERROR("futex_async");
+ abort();
+ }
} else {
uatomic_set(futex, 0);
}
/*
* Prepare futex.
*/
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
void futex_nto1_prepare(int32_t *futex)
{
uatomic_set(futex, -1);
/*
* Wait futex.
*/
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
void futex_nto1_wait(int32_t *futex)
{
cmm_smp_mb();
- if (uatomic_read(futex) == -1) {
- futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0);
+ if (uatomic_read(futex) != -1)
+ goto end;
+ while (futex_async(futex, FUTEX_WAIT, -1, NULL, NULL, 0)) {
+ switch (errno) {
+ case EWOULDBLOCK:
+ /* Value already changed. */
+ goto end;
+ case EINTR:
+ /* Retry if interrupted by signal. */
+ break; /* Get out of switch. */
+ default:
+ /* Unexpected error. */
+ PERROR("futex_async");
+ abort();
+ }
}
-
+end:
DBG("Futex n to 1 wait done");
}
/*
* Wake 1 futex.
*/
-__attribute__((visibility("hidden")))
+LTTNG_HIDDEN
void futex_nto1_wake(int32_t *futex)
{
- if (caa_unlikely(uatomic_read(futex) == -1)) {
- uatomic_set(futex, 0);
- futex_async(futex, FUTEX_WAKE, 1, NULL, NULL, 0);
+ if (caa_unlikely(uatomic_read(futex) != -1))
+ goto end;
+ uatomic_set(futex, 0);
+ if (futex_async(futex, FUTEX_WAKE, 1, NULL, NULL, 0) < 0) {
+ PERROR("futex_async");
+ abort();
}
-
+end:
DBG("Futex n to 1 wake done");
}