4
* Copyright Ericsson AB 2009-2011. All Rights Reserved.
6
* The contents of this file are subject to the Erlang Public License,
7
* Version 1.1, (the "License"); you may not use this file except in
8
* compliance with the License. You should have received a copy of the
9
* Erlang Public License along with this software. If not, it can be
10
* retrieved online at http://www.erlang.org/.
12
* Software distributed under the License is distributed on an "AS IS"
13
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
* the License for the specific language governing rights and limitations
21
* Author: Rickard Green
24
#if defined(ETHR_HAVE_LINUX_FUTEX) && defined(ETHR_HAVE_NATIVE_ATOMICS)
25
/* --- Linux futex implementation of ethread events ------------------------- */
26
#define ETHR_LINUX_FUTEX_IMPL__
28
#include <sys/syscall.h>
30
#include <linux/futex.h>
33
#define ETHR_EVENT_OFF_WAITER__ ((ethr_sint32_t) -1)
34
#define ETHR_EVENT_OFF__ ((ethr_sint32_t) 1)
35
#define ETHR_EVENT_ON__ ((ethr_sint32_t) 0)
37
#if defined(FUTEX_WAIT_PRIVATE) && defined(FUTEX_WAKE_PRIVATE)
38
# define ETHR_FUTEX_WAIT__ FUTEX_WAIT_PRIVATE
39
# define ETHR_FUTEX_WAKE__ FUTEX_WAKE_PRIVATE
41
# define ETHR_FUTEX_WAIT__ FUTEX_WAIT
42
# define ETHR_FUTEX_WAKE__ FUTEX_WAKE
46
ethr_atomic32_t futex;
49
#define ETHR_FUTEX__(FTX, OP, VAL) \
50
(-1 == syscall(__NR_futex, \
51
(void *) ethr_atomic32_addr((FTX)), \
59
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__)
61
static void ETHR_INLINE
62
ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
66
val = ethr_atomic32_xchg(&e->futex, ETHR_EVENT_ON__);
67
if (val == ETHR_EVENT_OFF_WAITER__) {
68
int res = ETHR_FUTEX__(&e->futex, ETHR_FUTEX_WAKE__, 1);
70
ETHR_FATAL_ERROR__(res);
74
static void ETHR_INLINE
75
ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
77
ethr_atomic32_set(&e->futex, ETHR_EVENT_OFF__);
83
#elif defined(ETHR_PTHREADS)
84
/* --- Posix mutex/cond implementation of events ---------------------------- */
87
ethr_atomic32_t state;
92
#define ETHR_EVENT_OFF_WAITER__ -1L
93
#define ETHR_EVENT_OFF__ 1L
94
#define ETHR_EVENT_ON__ 0L
96
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__)
98
static void ETHR_INLINE
99
ETHR_INLINE_FUNC_NAME_(ethr_event_set)(ethr_event *e)
103
val = ethr_atomic32_xchg(&e->state, ETHR_EVENT_ON__);
104
if (val == ETHR_EVENT_OFF_WAITER__) {
105
int res = pthread_mutex_lock(&e->mtx);
107
ETHR_FATAL_ERROR__(res);
108
res = pthread_cond_signal(&e->cnd);
110
ETHR_FATAL_ERROR__(res);
111
res = pthread_mutex_unlock(&e->mtx);
113
ETHR_FATAL_ERROR__(res);
117
static void ETHR_INLINE
118
ETHR_INLINE_FUNC_NAME_(ethr_event_reset)(ethr_event *e)
120
ethr_atomic32_set(&e->state, ETHR_EVENT_OFF__);
128
int ethr_event_init(ethr_event *e);
129
int ethr_event_destroy(ethr_event *e);
130
int ethr_event_wait(ethr_event *e);
131
int ethr_event_swait(ethr_event *e, int spincount);
132
#if !defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_EVENT_IMPL__)
133
void ethr_event_set(ethr_event *e);
134
void ethr_event_reset(ethr_event *e);