ARGOBOTS  1059a7c2eb7e3f99f736a9c3a4f6ea476ac1b804
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
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 ABTI_spinlock g_ABTI_init_lock = ABTI_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 
44 int ABT_init(int argc, char **argv)
45 {
46  ABTI_UNUSED(argc);
47  ABTI_UNUSED(argv);
48  /* Take a global lock protecting the initialization/finalization process. */
49  ABTI_spinlock_acquire(&g_ABTI_init_lock);
50  int abt_errno = init_library();
51  /* Unlock a global lock */
52  ABTI_spinlock_release(&g_ABTI_init_lock);
53  ABTI_CHECK_ERROR(abt_errno);
54  return ABT_SUCCESS;
55 }
56 
73 int ABT_finalize(void)
74 {
75  /* Take a global lock protecting the initialization/finalization process. */
76  ABTI_spinlock_acquire(&g_ABTI_init_lock);
77  int abt_errno = finailze_library();
78  /* Unlock a global lock */
79  ABTI_spinlock_release(&g_ABTI_init_lock);
80  ABTI_CHECK_ERROR(abt_errno);
81  return ABT_SUCCESS;
82 }
83 
96 int ABT_initialized(void)
97 {
98  if (ABTD_atomic_acquire_load_uint32(&g_ABTI_initialized) == 0) {
99  return ABT_ERR_UNINITIALIZED;
100  } else {
101  return ABT_SUCCESS;
102  }
103 }
104 
105 /*****************************************************************************/
106 /* Internal static functions */
107 /*****************************************************************************/
108 
109 ABTU_ret_err static int init_library(void)
110 {
111  int abt_errno;
112  /* If Argobots has already been initialized, just return */
113  if (g_ABTI_num_inits++ > 0) {
114  return ABT_SUCCESS;
115  }
116 
117  abt_errno = ABTU_malloc(sizeof(ABTI_global), (void **)&gp_ABTI_global);
118  ABTI_CHECK_ERROR(abt_errno);
119 
120  /* Initialize the system environment */
121  ABTD_env_init(gp_ABTI_global);
122 
123  /* Initialize memory pool */
124  ABTI_mem_init(gp_ABTI_global);
125 
126  /* Initialize IDs */
127  ABTI_thread_reset_id();
128  ABTI_sched_reset_id();
129  ABTI_pool_reset_id();
130 
131 #ifndef ABT_CONFIG_DISABLE_TOOL_INTERFACE
132  /* Initialize the tool interface */
133  ABTI_spinlock_clear(&gp_ABTI_global->tool_writer_lock);
134  gp_ABTI_global->tool_thread_cb_f = NULL;
135  gp_ABTI_global->tool_thread_user_arg = NULL;
136  gp_ABTI_global->tool_task_cb_f = NULL;
137  gp_ABTI_global->tool_task_user_arg = NULL;
138  ABTD_atomic_relaxed_store_uint64(&gp_ABTI_global
139  ->tool_thread_event_mask_tagged,
140  0);
141 #endif
142 
143  /* Initialize the ES list */
144  gp_ABTI_global->p_xstream_head = NULL;
145  gp_ABTI_global->num_xstreams = 0;
146 
147  /* Initialize a spinlock */
148  ABTI_spinlock_clear(&gp_ABTI_global->xstream_list_lock);
149 
150  /* Create the primary ES */
151  ABTI_xstream *p_local_xstream;
152  abt_errno = ABTI_xstream_create_primary(&p_local_xstream);
153  ABTI_CHECK_ERROR(abt_errno);
154 
155  /* Init the ES local data */
156  ABTI_local_set_xstream(p_local_xstream);
157 
158  /* Create the primary ULT, i.e., the main thread */
159  ABTI_ythread *p_main_ythread;
160  abt_errno =
161  ABTI_ythread_create_main(ABTI_xstream_get_local(p_local_xstream),
162  p_local_xstream, &p_main_ythread);
163  /* Set as if p_local_xstream is currently running the main thread. */
164  ABTD_atomic_relaxed_store_int(&p_main_ythread->thread.state,
166  p_main_ythread->thread.p_last_xstream = p_local_xstream;
167  ABTI_CHECK_ERROR(abt_errno);
168  gp_ABTI_global->p_main_ythread = p_main_ythread;
169  p_local_xstream->p_thread = &p_main_ythread->thread;
170 
171  /* Start the primary ES */
172  ABTI_xstream_start_primary(&p_local_xstream, p_local_xstream,
173  p_main_ythread);
174 
175  if (gp_ABTI_global->print_config == ABT_TRUE) {
176  ABTI_info_print_config(stdout);
177  }
178  ABTD_atomic_release_store_uint32(&g_ABTI_initialized, 1);
179  return ABT_SUCCESS;
180 }
181 
183 {
184  ABTI_local *p_local = ABTI_local_get_local();
185 
186  /* If Argobots is not initialized, just return */
187  ABTI_CHECK_TRUE(g_ABTI_num_inits > 0, ABT_ERR_UNINITIALIZED);
188  /* If Argobots is still referenced by others, just return */
189  if (--g_ABTI_num_inits != 0) {
190  return ABT_SUCCESS;
191  }
192 
193  ABTI_xstream *p_local_xstream = ABTI_local_get_xstream_or_null(p_local);
194  /* If called by an external thread, return an error. */
195  ABTI_CHECK_TRUE(!ABTI_IS_EXT_THREAD_ENABLED || p_local_xstream,
197 
198  ABTI_CHECK_TRUE_MSG(p_local_xstream->type == ABTI_XSTREAM_TYPE_PRIMARY,
200  "ABT_finalize must be called by the primary ES.");
201 
202  ABTI_thread *p_self = p_local_xstream->p_thread;
203  ABTI_CHECK_TRUE_MSG(p_self->type & ABTI_THREAD_TYPE_MAIN,
205  "ABT_finalize must be called by the primary ULT.");
206  ABTI_ythread *p_ythread;
207  ABTI_CHECK_YIELDABLE(p_self, &p_ythread, ABT_ERR_INV_THREAD);
208 
209 #ifndef ABT_CONFIG_DISABLE_TOOL_INTERFACE
210  /* Turns off the tool interface */
211  ABTI_tool_event_thread_update_callback(NULL, ABT_TOOL_EVENT_THREAD_NONE,
212  NULL);
213  ABTI_tool_event_task_update_callback(NULL, ABT_TOOL_EVENT_TASK_NONE, NULL);
214 #endif
215 
216  /* Set the orphan request for the primary ULT */
217  ABTI_thread_set_request(p_self, ABTI_THREAD_REQ_ORPHAN);
218  /* Finish the main scheduler of this local xstream. */
219  ABTI_sched_finish(p_local_xstream->p_main_sched);
220  /* p_self cannot join the main scheduler since p_self needs to be orphaned.
221  * Let's wait till the main scheduler finishes. This thread will be
222  * scheduled when the main root thread finishes. */
223  ABTI_ythread_yield(&p_local_xstream, p_ythread, ABT_SYNC_EVENT_TYPE_OTHER,
224  NULL);
225  ABTI_ASSERT(p_local_xstream == ABTI_local_get_xstream(p_local));
226  ABTI_ASSERT(p_local_xstream->p_thread == p_self);
227 
228  /* Remove the primary ULT */
229  p_local_xstream->p_thread = NULL;
230  ABTI_ythread_free_main(ABTI_xstream_get_local(p_local_xstream), p_ythread);
231 
232  /* Free the primary ES */
233  ABTI_xstream_free(ABTI_xstream_get_local(p_local_xstream), p_local_xstream,
234  ABT_TRUE);
235 
236  /* Finalize the ES local data */
237  ABTI_local_set_xstream(NULL);
238 
239  /* Free the ES array */
240  ABTI_ASSERT(gp_ABTI_global->p_xstream_head == NULL);
241 
242  /* Finalize the memory pool */
243  ABTI_mem_finalize(gp_ABTI_global);
244 
245  /* Restore the affinity */
246  if (gp_ABTI_global->set_affinity == ABT_TRUE) {
247  ABTD_affinity_finalize();
248  }
249 
250  /* Free the ABTI_global structure */
252  gp_ABTI_global = NULL;
253  ABTD_atomic_release_store_uint32(&g_ABTI_initialized, 0);
254  return ABT_SUCCESS;
255 }
int ABT_init(int argc, char **argv) ABT_API_PUBLIC
Initialize the Argobots execution environment.
Definition: global.c:44
static ABTU_ret_err int init_library(void)
Definition: global.c:109
static ABTD_atomic_uint32 g_ABTI_initialized
Definition: global.c:25
static ABTI_spinlock g_ABTI_init_lock
Definition: global.c:23
#define ABT_ERR_INV_THREAD
Definition: abt.h:80
#define ABT_TOOL_EVENT_THREAD_NONE
Definition: abt.h:260
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:129
static uint32_t g_ABTI_num_inits
Definition: global.c:21
int ABT_finalize(void) ABT_API_PUBLIC
Terminate the Argobots execution environment.
Definition: global.c:73
ABTI_global * gp_ABTI_global
Definition: global.c:18
#define ABT_SUCCESS
Definition: abt.h:64
#define ABT_TRUE
Definition: abt.h:284
static ABTU_ret_err int finailze_library(void)
Definition: global.c:182
#define ABT_ERR_UNINITIALIZED
Definition: abt.h:65
#define ABT_TOOL_EVENT_TASK_NONE
Definition: abt.h:273
#define ABT_ERR_INV_XSTREAM
Definition: abt.h:68
static void ABTU_free(void *ptr)
Definition: abtu.h:122
#define ABTU_ret_err
Definition: abtu.h:49
int ABT_initialized(void) ABT_API_PUBLIC
Check whether ABT_init() has been called.
Definition: global.c:96