ARGOBOTS  29b0d4cc91ca184a8278ddf690fd0bcb2119000e
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
abti_mutex.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #ifndef ABTI_MUTEX_H_INCLUDED
7 #define ABTI_MUTEX_H_INCLUDED
8 
9 static inline ABTI_mutex *ABTI_mutex_get_ptr(ABT_mutex mutex)
10 {
11 #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK
12  ABTI_mutex *p_mutex;
13  if (mutex == ABT_MUTEX_NULL) {
14  p_mutex = NULL;
15  } else {
16  p_mutex = (ABTI_mutex *)mutex;
17  }
18  return p_mutex;
19 #else
20  return (ABTI_mutex *)mutex;
21 #endif
22 }
23 
25 {
26 #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK
27  ABT_mutex h_mutex;
28  if (p_mutex == NULL) {
29  h_mutex = ABT_MUTEX_NULL;
30  } else {
31  h_mutex = (ABT_mutex)p_mutex;
32  }
33  return h_mutex;
34 #else
35  return (ABT_mutex)p_mutex;
36 #endif
37 }
38 
39 ABTU_ret_err static inline int ABTI_mutex_init(ABTI_mutex *p_mutex)
40 {
42  p_mutex->attr.attrs = ABTI_MUTEX_ATTR_NONE;
45 #ifndef ABT_CONFIG_USE_SIMPLE_MUTEX
47  &p_mutex->p_htable);
48  ABTI_CHECK_ERROR(abt_errno);
49  p_mutex->p_handover = NULL;
50  p_mutex->p_giver = NULL;
51 #endif
52  return ABT_SUCCESS;
53 }
54 
55 #ifdef ABT_CONFIG_USE_SIMPLE_MUTEX
56 #define ABTI_mutex_fini(p_mutex)
57 #else
58 static inline void ABTI_mutex_fini(ABTI_mutex *p_mutex)
59 {
61 }
62 #endif
63 
64 static inline void ABTI_mutex_spinlock(ABTI_mutex *p_mutex)
65 {
66  /* ABTI_spinlock_ functions cannot be used since p_mutex->val can take
67  * other values (i.e., not UNLOCKED nor LOCKED.) */
68  while (!ABTD_atomic_bool_cas_weak_uint32(&p_mutex->val, 0, 1)) {
69  while (ABTD_atomic_acquire_load_uint32(&p_mutex->val) != 0)
70  ;
71  }
72  LOG_DEBUG("%p: spinlock\n", p_mutex);
73 }
74 
75 static inline void ABTI_mutex_lock(ABTI_local **pp_local, ABTI_mutex *p_mutex)
76 {
77  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(*pp_local);
78  if (ABTI_IS_EXT_THREAD_ENABLED && !p_local_xstream) {
79  ABTI_mutex_spinlock(p_mutex);
80  return;
81  }
82  ABTI_ythread *p_ythread =
83  ABTI_thread_get_ythread_or_null(p_local_xstream->p_thread);
84  if (!p_ythread) {
85  ABTI_mutex_spinlock(p_mutex);
86  return;
87  }
88 #ifdef ABT_CONFIG_USE_SIMPLE_MUTEX
89  LOG_DEBUG("%p: lock - try\n", p_mutex);
90  while (!ABTD_atomic_bool_cas_strong_uint32(&p_mutex->val, 0, 1)) {
91  ABTI_ythread_yield(&p_local_xstream, p_ythread,
92  ABT_SYNC_EVENT_TYPE_MUTEX, (void *)p_mutex);
93  *pp_local = ABTI_xstream_get_local(p_local_xstream);
94  }
95  LOG_DEBUG("%p: lock - acquired\n", p_mutex);
96 #else
97  /* Only ULTs can yield when the mutex has been locked. For others,
98  * just call mutex_spinlock. */
99  LOG_DEBUG("%p: lock - try\n", p_mutex);
100  int c;
101  if ((c = ABTD_atomic_val_cas_strong_uint32(&p_mutex->val, 0, 1)) != 0) {
102  if (c != 2) {
103  c = ABTD_atomic_exchange_uint32(&p_mutex->val, 2);
104  }
105  while (c != 0) {
106  ABTI_mutex_wait(&p_local_xstream, p_mutex, 2);
107  *pp_local = ABTI_xstream_get_local(p_local_xstream);
108 
109  /* If the mutex has been handed over to the current ULT from
110  * other ULT on the same ES, we don't need to change the mutex
111  * state. */
112  if (p_mutex->p_handover) {
113  if (p_ythread == p_mutex->p_handover) {
114  p_mutex->p_handover = NULL;
116 
117  /* Push the previous ULT to its pool */
118  ABTI_ythread *p_giver = p_mutex->p_giver;
121  ABTI_pool_push(p_giver->thread.p_pool,
122  p_giver->thread.unit);
123  break;
124  }
125  }
126 
127  c = ABTD_atomic_exchange_uint32(&p_mutex->val, 2);
128  }
129  }
130  LOG_DEBUG("%p: lock - acquired\n", p_mutex);
131  return;
132 #endif
133 }
134 
135 static inline int ABTI_mutex_trylock(ABTI_mutex *p_mutex)
136 {
137  if (!ABTD_atomic_bool_cas_strong_uint32(&p_mutex->val, 0, 1)) {
138  return ABT_ERR_MUTEX_LOCKED;
139  }
140  return ABT_SUCCESS;
141 }
142 
143 static inline void ABTI_mutex_unlock(ABTI_local *p_local, ABTI_mutex *p_mutex)
144 {
145 #ifdef ABT_CONFIG_USE_SIMPLE_MUTEX
148  LOG_DEBUG("%p: unlock w/o wake\n", p_mutex);
149 #else
150  if (ABTD_atomic_fetch_sub_uint32(&p_mutex->val, 1) != 1) {
152  LOG_DEBUG("%p: unlock with wake\n", p_mutex);
153  ABTI_mutex_wake_de(p_local, p_mutex);
154  } else {
155  LOG_DEBUG("%p: unlock w/o wake\n", p_mutex);
156  }
157 #endif
158 }
159 
160 #endif /* ABTI_MUTEX_H_INCLUDED */
uint32_t max_handovers
Definition: abti.h:157
ABTI_pool * p_pool
Definition: abti.h:324
static ABTI_ythread * ABTI_thread_get_ythread_or_null(ABTI_thread *p_thread)
Definition: abti_thread.h:59
#define ABT_ERR_MUTEX_LOCKED
Definition: abt.h:105
ABTU_ret_err int ABTI_ythread_htable_create(uint32_t num_rows, ABTI_ythread_htable **pp_htable)
Definition: ythread_htable.c:9
static ABT_mutex ABTI_mutex_get_handle(ABTI_mutex *p_mutex)
Definition: abti_mutex.h:24
void ABTI_mutex_wake_de(ABTI_local *p_local, ABTI_mutex *p_mutex)
Definition: mutex.c:502
struct ABTI_local ABTI_local
Definition: abti.h:101
uint32_t max_wakeups
Definition: abti.h:158
int max_xstreams
Definition: abti.h:170
static void ABTD_atomic_release_store_int(ABTD_atomic_int *ptr, int val)
Definition: abtd_atomic.h:924
uint32_t attrs
Definition: abti.h:154
ABTI_thread * p_thread
Definition: abti.h:251
static uint32_t ABTD_atomic_val_cas_strong_uint32(ABTD_atomic_uint32 *ptr, uint32_t oldv, uint32_t newv)
Definition: abtd_atomic.h:272
ABTD_atomic_uint32 val
Definition: abti.h:162
static void ABTD_atomic_release_store_uint32(ABTD_atomic_uint32 *ptr, uint32_t val)
Definition: abtd_atomic.h:947
static void ABTI_mutex_lock(ABTI_local **pp_local, ABTI_mutex *p_mutex)
Definition: abti_mutex.h:75
static void ABTI_mutex_unlock(ABTI_local *p_local, ABTI_mutex *p_mutex)
Definition: abti_mutex.h:143
static void ABTI_mutex_fini(ABTI_mutex *p_mutex)
Definition: abti_mutex.h:58
ABTI_ythread_htable * p_htable
Definition: abti.h:164
static uint32_t ABTD_atomic_exchange_uint32(ABTD_atomic_uint32 *ptr, uint32_t v)
Definition: abtd_atomic.h:1022
ABTI_ythread * p_handover
Definition: abti.h:165
struct ABT_mutex_opaque * ABT_mutex
Definition: abt.h:357
uint32_t mutex_max_handovers
Definition: abti.h:188
uint32_t mutex_max_wakeups
Definition: abti.h:189
static uint32_t ABTD_atomic_acquire_load_uint32(const ABTD_atomic_uint32 *ptr)
Definition: abtd_atomic.h:797
ABTD_atomic_int state
Definition: abti.h:322
#define ABTI_IS_EXT_THREAD_ENABLED
Definition: abti.h:28
static int ABTD_atomic_bool_cas_weak_uint32(ABTD_atomic_uint32 *ptr, uint32_t oldv, uint32_t newv)
Definition: abtd_atomic.h:310
void ABTI_mutex_wait(ABTI_xstream **pp_local_xstream, ABTI_mutex *p_mutex, int val)
Definition: mutex.c:430
ABTI_global * gp_ABTI_global
Definition: global.c:18
ABTI_thread thread
Definition: abti.h:348
#define ABT_SUCCESS
Definition: abt.h:64
static void ABTD_atomic_mem_barrier(void)
Definition: abtd_atomic.h:1077
static ABTU_ret_err int ABTI_mutex_init(ABTI_mutex *p_mutex)
Definition: abti_mutex.h:39
static void ABTD_atomic_relaxed_store_uint32(ABTD_atomic_uint32 *ptr, uint32_t val)
Definition: abtd_atomic.h:884
ABTI_ythread * p_giver
Definition: abti.h:166
#define ABT_MUTEX_NULL
Definition: abt.h:419
static void ABTI_pool_push(ABTI_pool *p_pool, ABT_unit unit)
Definition: abti_pool.h:65
static void ABTI_mutex_spinlock(ABTI_mutex *p_mutex)
Definition: abti_mutex.h:64
ABTI_mutex_attr attr
Definition: abti.h:163
static uint32_t ABTD_atomic_fetch_sub_uint32(ABTD_atomic_uint32 *ptr, uint32_t v)
Definition: abtd_atomic.h:440
static int ABTD_atomic_bool_cas_strong_uint32(ABTD_atomic_uint32 *ptr, uint32_t oldv, uint32_t newv)
Definition: abtd_atomic.h:346
#define LOG_DEBUG(fmt,...)
Definition: abti_log.h:26
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:127
void ABTI_ythread_htable_free(ABTI_ythread_htable *p_htable)
static int ABTI_mutex_trylock(ABTI_mutex *p_mutex)
Definition: abti_mutex.h:135
static ABTI_mutex * ABTI_mutex_get_ptr(ABT_mutex mutex)
Definition: abti_mutex.h:9
ABT_unit unit
Definition: abti.h:317
static void ABTI_ythread_yield(ABTI_xstream **pp_local_xstream, ABTI_ythread *p_ythread, ABT_sync_event_type sync_event_type, void *p_sync)
Definition: abti_ythread.h:350
static ABTI_local * ABTI_xstream_get_local(ABTI_xstream *p_xstream)
Definition: abti_stream.h:67
#define ABTU_ret_err
Definition: abtu.h:49
static ABTI_xstream * ABTI_local_get_xstream_or_null(ABTI_local *p_local)
Definition: abti_local.h:77