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