/*
- * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
- * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 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).
*/
+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.
*/
+LTTNG_HIDDEN
void futex_nto1_prepare(int32_t *futex)
{
uatomic_set(futex, -1);
/*
* Wait futex.
*/
+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.
*/
+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");
}