ARGOBOTS  dce6e727ffc4ca5b3ffc04cb9517c6689be51ec5
abti_unit.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_UNIT_H_INCLUDED
7 #define ABTI_UNIT_H_INCLUDED
8 
9 /* A hash table is heavy. It should be avoided as much as possible. */
10 #define ABTI_UNIT_BUILTIN_POOL_BIT ((uintptr_t)0x1)
11 
12 static inline ABT_bool ABTI_unit_is_builtin(ABT_unit unit)
13 {
14  if (((uintptr_t)unit) & ABTI_UNIT_BUILTIN_POOL_BIT) {
15  /* This must happen only when unit is associated with a built-in pool.
16  * See ABT_pool_def's u_create_from_thread() for details. */
17  return ABT_TRUE;
18  } else {
19  return ABT_FALSE;
20  }
21 }
22 
23 static inline ABT_unit ABTI_unit_get_builtin_unit(ABTI_thread *p_thread)
24 {
25  ABTI_ASSERT(!(((uintptr_t)p_thread) & ABTI_UNIT_BUILTIN_POOL_BIT));
26  return (ABT_unit)(((uintptr_t)p_thread) | ABTI_UNIT_BUILTIN_POOL_BIT);
27 }
28 
29 static inline void ABTI_unit_init_builtin(ABTI_thread *p_thread)
30 {
31  p_thread->p_prev = NULL;
32  p_thread->p_next = NULL;
33  ABTD_atomic_relaxed_store_int(&p_thread->is_in_pool, 0);
34  p_thread->unit = ABTI_unit_get_builtin_unit(p_thread);
35 }
36 
37 static inline ABTI_thread *ABTI_unit_get_thread_from_builtin_unit(ABT_unit unit)
38 {
39  ABTI_ASSERT(ABTI_unit_is_builtin(unit));
40  return (ABTI_thread *)(((uintptr_t)unit) & (~ABTI_UNIT_BUILTIN_POOL_BIT));
41 }
42 
43 static inline ABTI_thread *ABTI_unit_get_thread(ABTI_global *p_global,
44  ABT_unit unit)
45 {
46  if (ABTU_likely(ABTI_unit_is_builtin(unit))) {
47  /* This unit is associated with a built-in pool. */
48  return ABTI_unit_get_thread_from_builtin_unit(unit);
49  } else {
50  return ABTI_unit_get_thread_from_user_defined_unit(p_global, unit);
51  }
52 }
53 
54 ABTU_ret_err static inline int
55 ABTI_unit_set_associated_pool(ABTI_global *p_global, ABT_unit unit,
56  ABTI_pool *p_pool, ABTI_thread **pp_thread)
57 {
58  if (ABTU_likely(ABTI_unit_is_builtin(unit))) {
59  ABTI_thread *p_thread = ABTI_unit_get_thread_from_builtin_unit(unit);
60  if (ABTU_likely(p_pool->is_builtin)) {
61  /* Do nothing since built-in pools share the implementation of
62  * ABT_unit. */
63  p_thread->p_pool = p_pool;
64  *pp_thread = p_thread;
65  return ABT_SUCCESS;
66  } else {
67  /* The new pool is a user-defined pool. */
68  ABT_pool pool = ABTI_pool_get_handle(p_pool);
69  ABT_unit new_unit =
70  p_pool->required_def.p_create_unit(pool, ABTI_thread_get_handle(
71  p_thread));
72  if (new_unit == ABT_UNIT_NULL)
73  return ABT_ERR_OTHER;
74  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
75  if (ret != ABT_SUCCESS) {
76  p_pool->required_def.p_free_unit(pool, new_unit);
77  return ret;
78  }
79  p_thread->unit = new_unit;
80  p_thread->p_pool = p_pool;
81  *pp_thread = p_thread;
82  return ABT_SUCCESS;
83  }
84  } else {
85  /* Currently, unit is associated with a user-defined pool. */
86  ABTI_thread *p_thread =
87  ABTI_unit_get_thread_from_user_defined_unit(p_global, unit);
88  if (p_pool->is_builtin) {
89  /* The old unit is associated with a custom pool. Remove the
90  * existing mapping. */
91  ABTI_unit_unmap_thread(p_global, unit);
92  ABT_pool old_pool = ABTI_pool_get_handle(p_thread->p_pool);
93  p_thread->p_pool->required_def.p_free_unit(old_pool, unit);
94  ABTI_unit_init_builtin(p_thread);
95  p_thread->p_pool = p_pool;
96  *pp_thread = p_thread;
97  return ABT_SUCCESS;
98  } else if (p_thread->p_pool == p_pool) {
99  /* Both are associated with the same custom pool. */
100  *pp_thread = p_thread;
101  return ABT_SUCCESS;
102  } else {
103  /* Both are associated with different custom pools. */
104  ABT_pool pool = ABTI_pool_get_handle(p_pool);
105  ABT_unit new_unit =
106  p_pool->required_def.p_create_unit(pool, ABTI_thread_get_handle(
107  p_thread));
108  if (new_unit == ABT_UNIT_NULL)
109  return ABT_ERR_OTHER;
110  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
111  if (ret != ABT_SUCCESS) {
112  p_pool->required_def.p_free_unit(pool, new_unit);
113  return ret;
114  }
115  ABTI_unit_unmap_thread(p_global, unit);
116  ABT_pool old_pool = ABTI_pool_get_handle(p_thread->p_pool);
117  p_thread->p_pool->required_def.p_free_unit(old_pool, unit);
118  p_thread->unit = new_unit;
119  p_thread->p_pool = p_pool;
120  *pp_thread = p_thread;
121  return ABT_SUCCESS;
122  }
123  }
124 }
125 
126 /* The following functions have ABTI_thread prefix, but they mainly manage
127  * thread-unit mapping, so they are placed in this header file so far. */
128 ABTU_ret_err static inline int ABTI_thread_init_pool(ABTI_global *p_global,
129  ABTI_thread *p_thread,
130  ABTI_pool *p_pool)
131 {
132  if (ABTU_likely(p_pool->is_builtin)) {
133  ABTI_unit_init_builtin(p_thread);
134  p_thread->p_pool = p_pool;
135  return ABT_SUCCESS;
136  } else {
137  ABT_pool pool = ABTI_pool_get_handle(p_pool);
138  ABT_unit new_unit =
139  p_pool->required_def.p_create_unit(pool, ABTI_thread_get_handle(
140  p_thread));
141  if (new_unit == ABT_UNIT_NULL)
142  return ABT_ERR_OTHER;
143  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
144  if (ret != ABT_SUCCESS) {
145  p_pool->required_def.p_free_unit(pool, new_unit);
146  return ret;
147  }
148  p_thread->unit = new_unit;
149  p_thread->p_pool = p_pool;
150  return ABT_SUCCESS;
151  }
152 }
153 
154 ABTU_ret_err static inline int
155 ABTI_thread_set_associated_pool(ABTI_global *p_global, ABTI_thread *p_thread,
156  ABTI_pool *p_pool)
157 {
158  ABT_unit unit = p_thread->unit;
159  if (ABTU_likely(ABTI_unit_is_builtin(unit) && p_pool->is_builtin)) {
160  /* Do nothing since built-in pools share the implementation of
161  * ABT_unit. */
162  p_thread->p_pool = p_pool;
163  return ABT_SUCCESS;
164  } else if (ABTI_unit_is_builtin(unit)) {
165  /* The new unit is associated with a custom pool. Add a new mapping. */
166  ABT_pool pool = ABTI_pool_get_handle(p_pool);
167  ABT_unit new_unit =
168  p_pool->required_def.p_create_unit(pool, ABTI_thread_get_handle(
169  p_thread));
170  if (new_unit == ABT_UNIT_NULL)
171  return ABT_ERR_OTHER;
172  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
173  if (ret != ABT_SUCCESS) {
174  p_pool->required_def.p_free_unit(pool, new_unit);
175  return ret;
176  }
177  p_thread->unit = new_unit;
178  p_thread->p_pool = p_pool;
179  return ABT_SUCCESS;
180  } else if (p_pool->is_builtin) {
181  /* The old unit is associated with a custom pool. Remove the existing
182  * mapping. */
183  ABTI_unit_unmap_thread(p_global, unit);
184  ABT_pool old_pool = ABTI_pool_get_handle(p_thread->p_pool);
185  p_thread->p_pool->required_def.p_free_unit(old_pool, unit);
186  ABTI_unit_init_builtin(p_thread);
187  p_thread->p_pool = p_pool;
188  return ABT_SUCCESS;
189  } else if (p_thread->p_pool == p_pool) {
190  /* Both are associated with the same custom pool. */
191  return ABT_SUCCESS;
192  } else {
193  /* Both are associated with different custom pools. */
194  ABT_pool pool = ABTI_pool_get_handle(p_pool);
195  ABT_unit new_unit =
196  p_pool->required_def.p_create_unit(pool, ABTI_thread_get_handle(
197  p_thread));
198  if (new_unit == ABT_UNIT_NULL)
199  return ABT_ERR_OTHER;
200  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
201  if (ret != ABT_SUCCESS) {
202  p_pool->required_def.p_free_unit(pool, new_unit);
203  return ret;
204  }
205  ABTI_unit_unmap_thread(p_global, unit);
206  ABT_pool old_pool = ABTI_pool_get_handle(p_thread->p_pool);
207  p_thread->p_pool->required_def.p_free_unit(old_pool, unit);
208  p_thread->unit = new_unit;
209  p_thread->p_pool = p_pool;
210  return ABT_SUCCESS;
211  }
212 }
213 
214 static inline void ABTI_thread_unset_associated_pool(ABTI_global *p_global,
215  ABTI_thread *p_thread)
216 {
217  ABT_unit unit = p_thread->unit;
218  if (ABTU_unlikely(!ABTI_unit_is_builtin(unit))) {
219  ABTI_unit_unmap_thread(p_global, unit);
220  ABT_pool old_pool = ABTI_pool_get_handle(p_thread->p_pool);
221  p_thread->p_pool->required_def.p_free_unit(old_pool, unit);
222  }
223 #if ABTI_IS_ERROR_CHECK_ENABLED
224  p_thread->unit = ABT_UNIT_NULL;
225  p_thread->p_pool = NULL;
226 #endif
227 }
228 
229 #endif /* ABTI_UNIT_H_INCLUDED */
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1043
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:878
ABTU_likely
#define ABTU_likely(cond)
Definition: abtu.h:119
ABT_unit
struct ABT_unit_opaque * ABT_unit
Work unit handle type for scheduling.
Definition: abt.h:911
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:155
ABTU_unlikely
#define ABTU_unlikely(cond)
Definition: abtu.h:120
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:784
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:786
ABT_ERR_OTHER
#define ABT_ERR_OTHER
Error code: other error.
Definition: abt.h:109
ABT_UNIT_NULL
#define ABT_UNIT_NULL
Definition: abt.h:1104