ARGOBOTS  8bef54a19d7b3e50f977f85716578b627bf37d9c
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_unit new_unit =
69  p_pool->u_create_from_thread(ABTI_thread_get_handle(p_thread));
70  if (new_unit == ABT_UNIT_NULL)
71  return ABT_ERR_OTHER;
72  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
73  if (ret != ABT_SUCCESS) {
74  p_pool->u_free(&new_unit);
75  return ret;
76  }
77  p_thread->unit = new_unit;
78  p_thread->p_pool = p_pool;
79  *pp_thread = p_thread;
80  return ABT_SUCCESS;
81  }
82  } else {
83  /* Currently, unit is associated with a user-defined pool. */
84  ABTI_thread *p_thread =
85  ABTI_unit_get_thread_from_user_defined_unit(p_global, unit);
86  if (p_pool->is_builtin) {
87  /* The old unit is associated with a custom pool. Remove the
88  * existing mapping. */
89  ABTI_unit_unmap_thread(p_global, unit);
90  p_thread->p_pool->u_free(&unit);
91  ABTI_unit_init_builtin(p_thread);
92  p_thread->p_pool = p_pool;
93  *pp_thread = p_thread;
94  return ABT_SUCCESS;
95  } else if (p_thread->p_pool == p_pool) {
96  /* Both are associated with the same custom pool. */
97  *pp_thread = p_thread;
98  return ABT_SUCCESS;
99  } else {
100  /* Both are associated with different custom pools. */
101  ABT_unit new_unit =
102  p_pool->u_create_from_thread(ABTI_thread_get_handle(p_thread));
103  if (new_unit == ABT_UNIT_NULL)
104  return ABT_ERR_OTHER;
105  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
106  if (ret != ABT_SUCCESS) {
107  p_pool->u_free(&new_unit);
108  return ret;
109  }
110  ABTI_unit_unmap_thread(p_global, unit);
111  p_thread->p_pool->u_free(&unit);
112  p_thread->unit = new_unit;
113  p_thread->p_pool = p_pool;
114  *pp_thread = p_thread;
115  return ABT_SUCCESS;
116  }
117  }
118 }
119 
120 /* The following functions have ABTI_thread prefix, but they mainly manage
121  * thread-unit mapping, so they are placed in this header file so far. */
122 ABTU_ret_err static inline int ABTI_thread_init_pool(ABTI_global *p_global,
123  ABTI_thread *p_thread,
124  ABTI_pool *p_pool)
125 {
126  if (ABTU_likely(p_pool->is_builtin)) {
127  ABTI_unit_init_builtin(p_thread);
128  p_thread->p_pool = p_pool;
129  return ABT_SUCCESS;
130  } else {
131  ABT_unit new_unit =
132  p_pool->u_create_from_thread(ABTI_thread_get_handle(p_thread));
133  if (new_unit == ABT_UNIT_NULL)
134  return ABT_ERR_OTHER;
135  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
136  if (ret != ABT_SUCCESS) {
137  p_pool->u_free(&new_unit);
138  return ret;
139  }
140  p_thread->unit = new_unit;
141  p_thread->p_pool = p_pool;
142  return ABT_SUCCESS;
143  }
144 }
145 
146 ABTU_ret_err static inline int
147 ABTI_thread_set_associated_pool(ABTI_global *p_global, ABTI_thread *p_thread,
148  ABTI_pool *p_pool)
149 {
150  ABT_unit unit = p_thread->unit;
151  if (ABTU_likely(ABTI_unit_is_builtin(unit) && p_pool->is_builtin)) {
152  /* Do nothing since built-in pools share the implementation of
153  * ABT_unit. */
154  p_thread->p_pool = p_pool;
155  return ABT_SUCCESS;
156  } else if (ABTI_unit_is_builtin(unit)) {
157  /* The new unit is associated with a custom pool. Add a new mapping. */
158  ABT_unit new_unit =
159  p_pool->u_create_from_thread(ABTI_thread_get_handle(p_thread));
160  if (new_unit == ABT_UNIT_NULL)
161  return ABT_ERR_OTHER;
162  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
163  if (ret != ABT_SUCCESS) {
164  p_pool->u_free(&new_unit);
165  return ret;
166  }
167  p_thread->unit = new_unit;
168  p_thread->p_pool = p_pool;
169  return ABT_SUCCESS;
170  } else if (p_pool->is_builtin) {
171  /* The old unit is associated with a custom pool. Remove the existing
172  * mapping. */
173  ABTI_unit_unmap_thread(p_global, unit);
174  p_thread->p_pool->u_free(&unit);
175  ABTI_unit_init_builtin(p_thread);
176  p_thread->p_pool = p_pool;
177  return ABT_SUCCESS;
178  } else if (p_thread->p_pool == p_pool) {
179  /* Both are associated with the same custom pool. */
180  return ABT_SUCCESS;
181  } else {
182  /* Both are associated with different custom pools. */
183  ABT_unit new_unit =
184  p_pool->u_create_from_thread(ABTI_thread_get_handle(p_thread));
185  if (new_unit == ABT_UNIT_NULL)
186  return ABT_ERR_OTHER;
187  int ret = ABTI_unit_map_thread(p_global, new_unit, p_thread);
188  if (ret != ABT_SUCCESS) {
189  p_pool->u_free(&new_unit);
190  return ret;
191  }
192  ABTI_unit_unmap_thread(p_global, unit);
193  p_thread->p_pool->u_free(&unit);
194  p_thread->unit = new_unit;
195  p_thread->p_pool = p_pool;
196  return ABT_SUCCESS;
197  }
198 }
199 
200 static inline void ABTI_thread_unset_associated_pool(ABTI_global *p_global,
201  ABTI_thread *p_thread)
202 {
203  ABT_unit unit = p_thread->unit;
204  if (ABTU_unlikely(!ABTI_unit_is_builtin(unit))) {
205  ABTI_unit_unmap_thread(p_global, unit);
206  p_thread->p_pool->u_free(&unit);
207  }
208 #if ABTI_IS_ERROR_CHECK_ENABLED
209  p_thread->unit = ABT_UNIT_NULL;
210  p_thread->p_pool = NULL;
211 #endif
212 }
213 
214 #endif /* ABTI_UNIT_H_INCLUDED */
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1001
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:869
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:748
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:750
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:1061