ARGOBOTS  36a41b57298ad4e16b5ada8c95c81f00dfed4d3c
global.c
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 #include "abti.h"
7 
8 /* Must be in a critical section. */
9 ABTU_ret_err static int init_library(void);
10 ABTU_ret_err static int finailze_library(void);
11 static inline ABT_bool is_initialized_library(void);
12 
18 /* Global Data */
19 ABTI_global *gp_ABTI_global = NULL;
20 
21 /* To indicate how many times ABT_init is called. */
22 static uint32_t g_ABTI_num_inits = 0;
23 /* A global lock protecting the initialization/finalization process */
24 static ABTD_spinlock g_ABTI_init_lock = ABTD_SPINLOCK_STATIC_INITIALIZER();
25 /* A flag whether Argobots has been initialized or not */
26 static ABTD_atomic_uint32 g_ABTI_initialized =
27  ABTD_ATOMIC_UINT32_STATIC_INITIALIZER(0);
28 
75 int ABT_init(int argc, char **argv)
76 {
77  ABTI_UNUSED(argc);
78  ABTI_UNUSED(argv);
79 
80  int abt_errno;
81  /* Take a global lock protecting the initialization/finalization process. */
82  ABTD_spinlock_acquire(&g_ABTI_init_lock);
83  /* If Argobots has already been initialized, just return */
84  if (g_ABTI_num_inits > 0) {
86  abt_errno = ABT_SUCCESS;
87  } else {
88  abt_errno = init_library();
89  if (abt_errno == ABT_SUCCESS)
91  }
92  /* Unlock a global lock */
93  ABTD_spinlock_release(&g_ABTI_init_lock);
94  ABTI_CHECK_ERROR(abt_errno);
95  return ABT_SUCCESS;
96 }
97 
141 int ABT_finalize(void)
142 {
143  ABTI_UB_ASSERT(ABTI_initialized());
144 
145  /* Take a global lock protecting the initialization/finalization process. */
146  ABTD_spinlock_acquire(&g_ABTI_init_lock);
147  int abt_errno = finailze_library();
148  /* Unlock a global lock */
149  ABTD_spinlock_release(&g_ABTI_init_lock);
150  ABTI_CHECK_ERROR(abt_errno);
151  return ABT_SUCCESS;
152 }
153 
174 {
175  if (is_initialized_library()) {
176  return ABT_SUCCESS;
177  } else {
178  return ABT_ERR_UNINITIALIZED;
179  }
180 }
181 
182 /*****************************************************************************/
183 /* Private APIs */
184 /*****************************************************************************/
185 
186 /* This function must be async-signal-safe. */
187 ABT_bool ABTI_initialized(void)
188 {
189  return is_initialized_library();
190 }
191 
192 /*****************************************************************************/
193 /* Internal static functions */
194 /*****************************************************************************/
195 
196 ABTU_ret_err static int init_library(void)
197 {
198  int abt_errno, init_stage = 0;
199 
200  ABTI_global *p_global;
201  ABTI_xstream *p_local_xstream;
202 
203  abt_errno = ABTU_malloc(sizeof(ABTI_global), (void **)&p_global);
204  ABTI_CHECK_ERROR(abt_errno);
205  ABTI_global_set_global(p_global);
206 
207  /* Initialize the system environment */
208  ABTD_env_init(p_global);
209 
210  /* Initialize memory pool */
211  abt_errno = ABTI_mem_init(p_global);
212  if (abt_errno != ABT_SUCCESS)
213  goto FAILED;
214  init_stage = 1;
215 
216  /* Initialize IDs */
217  ABTI_thread_reset_id();
218  ABTI_sched_reset_id();
219  ABTI_pool_reset_id();
220 
221 #ifndef ABT_CONFIG_DISABLE_TOOL_INTERFACE
222  /* Initialize the tool interface */
223  ABTD_spinlock_clear(&p_global->tool_writer_lock);
224  p_global->tool_thread_cb_f = NULL;
225  p_global->tool_thread_user_arg = NULL;
226  ABTD_atomic_relaxed_store_uint64(&p_global->tool_thread_event_mask_tagged,
227  0);
228 #endif
229  /* Initialize a unit-to-thread hash table. */
230  ABTI_unit_init_hash_table(p_global);
231 
232  /* Initialize the ES list */
233  p_global->p_xstream_head = NULL;
234  p_global->num_xstreams = 0;
235 
236  /* Initialize a spinlock */
237  ABTD_spinlock_clear(&p_global->xstream_list_lock);
238 
239  /* Create the primary ES */
240  abt_errno = ABTI_xstream_create_primary(p_global, &p_local_xstream);
241  if (abt_errno != ABT_SUCCESS)
242  goto FAILED;
243  init_stage = 2;
244 
245  /* Init the ES local data */
246  ABTI_local_set_xstream(p_local_xstream);
247 
248  /* Create the primary ULT */
249  ABTI_ythread *p_primary_ythread;
250  abt_errno =
251  ABTI_ythread_create_primary(p_global,
252  ABTI_xstream_get_local(p_local_xstream),
253  p_local_xstream, &p_primary_ythread);
254  if (abt_errno != ABT_SUCCESS)
255  goto FAILED;
256  init_stage = 3;
257 
258  /* Set as if p_local_xstream is currently running the primary ULT. */
259  ABTD_atomic_relaxed_store_int(&p_primary_ythread->thread.state,
261  p_primary_ythread->thread.p_last_xstream = p_local_xstream;
262  p_global->p_primary_ythread = p_primary_ythread;
263  p_local_xstream->p_thread = &p_primary_ythread->thread;
264 
265  /* Start the primary ES */
266  ABTI_xstream_start_primary(p_global, &p_local_xstream, p_local_xstream,
267  p_primary_ythread);
268 
269  if (p_global->print_config == ABT_TRUE) {
270  ABTI_info_print_config(p_global, stdout);
271  }
272  ABTD_atomic_release_store_uint32(&g_ABTI_initialized, 1);
273  return ABT_SUCCESS;
274 FAILED:
275  if (init_stage >= 2) {
276  ABTI_xstream_free(p_global, ABTI_xstream_get_local(p_local_xstream),
277  p_local_xstream, ABT_TRUE);
278  ABTI_local_set_xstream(NULL);
279  }
280  if (init_stage >= 1) {
281  ABTI_mem_finalize(p_global);
282  }
283  ABTD_affinity_finalize(p_global);
284  ABTU_free(p_global);
285  ABTI_global_set_global(NULL);
286  ABTI_HANDLE_ERROR(abt_errno);
287 }
288 
290 {
291  ABTI_local *p_local = ABTI_local_get_local();
292 
293  /* If Argobots is not initialized, just return */
294  ABTI_CHECK_TRUE(g_ABTI_num_inits > 0, ABT_ERR_UNINITIALIZED);
295  /* If Argobots is still referenced by others, just return */
296  if (--g_ABTI_num_inits != 0) {
297  return ABT_SUCCESS;
298  }
299 
300  ABTI_global *p_global = ABTI_global_get_global();
301  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(p_local);
302  /* If called by an external thread, return an error. */
303  ABTI_CHECK_TRUE(!ABTI_IS_EXT_THREAD_ENABLED || p_local_xstream,
305 
306  ABTI_CHECK_TRUE_MSG(p_local_xstream->type == ABTI_XSTREAM_TYPE_PRIMARY,
308  "ABT_finalize must be called by the primary ES.");
309 
310  ABTI_thread *p_self = p_local_xstream->p_thread;
311  ABTI_CHECK_TRUE_MSG(p_self->type & ABTI_THREAD_TYPE_PRIMARY,
313  "ABT_finalize must be called by the primary ULT.");
314  ABTI_ythread *p_ythread;
315  ABTI_CHECK_YIELDABLE(p_self, &p_ythread, ABT_ERR_INV_THREAD);
316 
317 #ifndef ABT_CONFIG_DISABLE_TOOL_INTERFACE
318  /* Turns off the tool interface */
319  ABTI_tool_event_thread_update_callback(p_global, NULL,
321 #endif
322 
323  /* Finish the main scheduler of this local xstream. */
324  ABTI_sched_finish(p_local_xstream->p_main_sched);
325  /* p_self cannot join the main scheduler since p_self needs to be orphaned.
326  * Let's wait till the main scheduler finishes. This thread will be
327  * scheduled when the main root thread finishes. */
328  ABTI_ythread_yield_orphan(&p_local_xstream, p_ythread,
330  ABTI_ASSERT(p_local_xstream == ABTI_local_get_xstream(p_local));
331  ABTI_ASSERT(p_local_xstream->p_thread == p_self);
332 
333  /* Remove the primary ULT */
334  p_local_xstream->p_thread = NULL;
335  ABTI_ythread_free_primary(p_global, ABTI_xstream_get_local(p_local_xstream),
336  p_ythread);
337 
338  /* Free the primary ES */
339  ABTI_xstream_free(p_global, ABTI_xstream_get_local(p_local_xstream),
340  p_local_xstream, ABT_TRUE);
341 
342  /* Finalize the ES local data */
343  ABTI_local_set_xstream(NULL);
344 
345  /* Free the ES array */
346  ABTI_ASSERT(p_global->p_xstream_head == NULL);
347 
348  /* Finalize the memory pool */
349  ABTI_mem_finalize(p_global);
350 
351  /* Restore the affinity */
352  ABTD_affinity_finalize(p_global);
353 
354  /* Free a unit-to-thread hash table. */
355  ABTI_unit_finalize_hash_table(p_global);
356 
357  /* Free the ABTI_global structure */
358  ABTU_free(p_global);
359  ABTI_global_set_global(NULL);
360  ABTD_atomic_release_store_uint32(&g_ABTI_initialized, 0);
361  return ABT_SUCCESS;
362 }
363 
364 /* This function must be async-signal-safe. */
365 static inline ABT_bool is_initialized_library(void)
366 {
367  return (ABTD_atomic_acquire_load_uint32(&g_ABTI_initialized) != 0)
368  ? ABT_TRUE
369  : ABT_FALSE;
370 }
ABT_ERR_INV_THREAD
#define ABT_ERR_INV_THREAD
Error code: invalid work unit.
Definition: abt.h:186
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1043
ABT_ERR_UNINITIALIZED
#define ABT_ERR_UNINITIALIZED
Error code: Argobots it not initialized.
Definition: abt.h:97
ABT_ERR_INV_XSTREAM
#define ABT_ERR_INV_XSTREAM
Error code: invalid execution stream.
Definition: abt.h:114
init_library
static ABTU_ret_err int init_library(void)
Definition: global.c:196
gp_ABTI_global
ABTI_global * gp_ABTI_global
Definition: global.c:19
ABT_finalize
int ABT_finalize(void)
Finalize the Argobots execution environment.
Definition: global.c:141
ABT_init
int ABT_init(int argc, char **argv)
Initialize the Argobots execution environment.
Definition: global.c:75
abti.h
ABT_SYNC_EVENT_TYPE_OTHER
@ ABT_SYNC_EVENT_TYPE_OTHER
Definition: abt.h:702
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:235
is_initialized_library
static ABT_bool is_initialized_library(void)
Definition: global.c:365
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
g_ABTI_num_inits
static uint32_t g_ABTI_num_inits
Definition: global.c:22
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_initialized
int ABT_initialized(void)
Check if the Argobots execution environment has been initialized.
Definition: global.c:173
ABT_TOOL_EVENT_THREAD_NONE
#define ABT_TOOL_EVENT_THREAD_NONE
Work-unit-event mask: none.
Definition: abt.h:725
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
finailze_library
static ABTU_ret_err int finailze_library(void)
Definition: global.c:289
g_ABTI_initialized
static ABTD_atomic_uint32 g_ABTI_initialized
Definition: global.c:26
ABT_THREAD_STATE_RUNNING
@ ABT_THREAD_STATE_RUNNING
Definition: abt.h:429
g_ABTI_init_lock
static ABTD_spinlock g_ABTI_init_lock
Definition: global.c:24