ARGOBOTS  66b1c39742507d8df30e8d28c54839b961a14814
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
abtd_env.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 #include <unistd.h>
8 #include <strings.h>
9 
10 #define ABTD_KEY_TABLE_DEFAULT_SIZE 4
11 #define ABTD_THREAD_DEFAULT_STACKSIZE 16384
12 #define ABTD_SCHED_DEFAULT_STACKSIZE (4 * 1024 * 1024)
13 #define ABTD_SCHED_EVENT_FREQ 50
14 #define ABTD_SCHED_SLEEP_NSEC 100
15 
16 #define ABTD_OS_PAGE_SIZE (4 * 1024)
17 #define ABTD_HUGE_PAGE_SIZE (2 * 1024 * 1024)
18 #define ABTD_MEM_PAGE_SIZE (2 * 1024 * 1024)
19 #define ABTD_MEM_STACK_PAGE_SIZE (8 * 1024 * 1024)
20 #define ABTD_MEM_MAX_NUM_STACKS 1024
21 #define ABTD_MEM_MAX_TOTAL_STACK_SIZE (64 * 1024 * 1024)
22 #define ABTD_MEM_MAX_NUM_DESCS 4096
23 
24 void ABTD_env_init(ABTI_global *p_global)
25 {
26  char *env;
27 
28  /* Get the number of available cores in the system */
29  p_global->num_cores = sysconf(_SC_NPROCESSORS_ONLN);
30 
31  /* By default, we use the CPU affinity */
32  p_global->set_affinity = ABT_TRUE;
33  env = getenv("ABT_SET_AFFINITY");
34  if (env == NULL)
35  env = getenv("ABT_ENV_SET_AFFINITY");
36  if (env != NULL) {
37  if (strcasecmp(env, "n") == 0 || strcasecmp(env, "no") == 0) {
38  p_global->set_affinity = ABT_FALSE;
39  }
40  }
41  if (p_global->set_affinity == ABT_TRUE) {
42  ABTD_affinity_init(env);
43  }
44 
45 #ifdef ABT_CONFIG_USE_DEBUG_LOG_PRINT
46  /* If the debug log printing is set in configure, logging is turned on by
47  * default. */
48  p_global->use_logging = ABT_TRUE;
49  p_global->use_debug = ABT_TRUE;
50 #else
51  /* Otherwise, logging is not turned on by default. */
52  p_global->use_logging = ABT_FALSE;
53  p_global->use_debug = ABT_FALSE;
54 #endif
55  env = getenv("ABT_USE_LOG");
56  if (env == NULL)
57  env = getenv("ABT_ENV_USE_LOG");
58  if (env != NULL) {
59  if (strcmp(env, "0") == 0 || strcasecmp(env, "n") == 0 ||
60  strcasecmp(env, "no") == 0) {
61  p_global->use_logging = ABT_FALSE;
62  } else {
63  p_global->use_logging = ABT_TRUE;
64  }
65  }
66  env = getenv("ABT_USE_DEBUG");
67  if (env == NULL)
68  env = getenv("ABT_ENV_USE_DEBUG");
69  if (env != NULL) {
70  if (strcmp(env, "0") == 0 || strcasecmp(env, "n") == 0 ||
71  strcasecmp(env, "no") == 0) {
72  p_global->use_debug = ABT_FALSE;
73  } else {
74  p_global->use_debug = ABT_TRUE;
75  }
76  }
77 
78  /* Maximum size of the internal ES array */
79  env = getenv("ABT_MAX_NUM_XSTREAMS");
80  if (env == NULL)
81  env = getenv("ABT_ENV_MAX_NUM_XSTREAMS");
82  if (env != NULL) {
83  p_global->max_xstreams = atoi(env);
84  } else {
85  p_global->max_xstreams = p_global->num_cores;
86  }
87 
88  /* Default key table size */
89  env = getenv("ABT_KEY_TABLE_SIZE");
90  if (env == NULL)
91  env = getenv("ABT_ENV_KEY_TABLE_SIZE");
92  if (env != NULL) {
93  p_global->key_table_size = (int)atoi(env);
94  } else {
95  p_global->key_table_size = ABTD_KEY_TABLE_DEFAULT_SIZE;
96  }
97  /* key_table_size must be a power of 2. */
98  {
99  int i;
100  for (i = 0; i < sizeof(int) * 8; i++) {
101  if ((p_global->key_table_size - 1) >> i == 0)
102  break;
103  }
104  p_global->key_table_size = 1 << i;
105  }
106 
107  /* Default stack size for ULT */
108  env = getenv("ABT_THREAD_STACKSIZE");
109  if (env == NULL)
110  env = getenv("ABT_ENV_THREAD_STACKSIZE");
111  if (env != NULL) {
112  p_global->thread_stacksize = (size_t)atol(env);
113  ABTI_ASSERT(p_global->thread_stacksize >= 512);
114  } else {
115  p_global->thread_stacksize = ABTD_THREAD_DEFAULT_STACKSIZE;
116  }
117  /* Stack size must be a multiple of cacheline size. */
118  p_global->thread_stacksize =
119  (p_global->thread_stacksize + ABT_CONFIG_STATIC_CACHELINE_SIZE - 1) &
121 
122  /* Default stack size for scheduler */
123  env = getenv("ABT_SCHED_STACKSIZE");
124  if (env == NULL)
125  env = getenv("ABT_ENV_SCHED_STACKSIZE");
126  if (env != NULL) {
127  p_global->sched_stacksize = (size_t)atol(env);
128  ABTI_ASSERT(p_global->sched_stacksize >= 512);
129  } else {
130  p_global->sched_stacksize = ABTD_SCHED_DEFAULT_STACKSIZE;
131  }
132 
133  /* Default frequency for event checking by the scheduler */
134  env = getenv("ABT_SCHED_EVENT_FREQ");
135  if (env == NULL)
136  env = getenv("ABT_ENV_SCHED_EVENT_FREQ");
137  if (env != NULL) {
138  p_global->sched_event_freq = (uint32_t)atol(env);
139  ABTI_ASSERT(p_global->sched_event_freq >= 1);
140  } else {
141  p_global->sched_event_freq = ABTD_SCHED_EVENT_FREQ;
142  }
143 
144  /* Default nanoseconds for scheduler sleep */
145  env = getenv("ABT_SCHED_SLEEP_NSEC");
146  if (env == NULL)
147  env = getenv("ABT_ENV_SCHED_SLEEP_NSEC");
148  if (env != NULL) {
149  p_global->sched_sleep_nsec = atol(env);
150  ABTI_ASSERT(p_global->sched_sleep_nsec >= 0);
151  } else {
152  p_global->sched_sleep_nsec = ABTD_SCHED_SLEEP_NSEC;
153  }
154 
155  /* Mutex attributes */
156  env = getenv("ABT_MUTEX_MAX_HANDOVERS");
157  if (env == NULL)
158  env = getenv("ABT_ENV_MUTEX_MAX_HANDOVERS");
159  if (env != NULL) {
160  p_global->mutex_max_handovers = (uint32_t)atoi(env);
161  ABTI_ASSERT(p_global->mutex_max_handovers >= 1);
162  } else {
163  p_global->mutex_max_handovers = 64;
164  }
165 
166  env = getenv("ABT_MUTEX_MAX_WAKEUPS");
167  if (env == NULL)
168  env = getenv("ABT_ENV_MUTEX_MAX_WAKEUPS");
169  if (env != NULL) {
170  p_global->mutex_max_wakeups = (uint32_t)atoi(env);
171  ABTI_ASSERT(p_global->mutex_max_wakeups >= 1);
172  } else {
173  p_global->mutex_max_wakeups = 1;
174  }
175 
176  /* OS page size */
177  env = getenv("ABT_OS_PAGE_SIZE");
178  if (env == NULL)
179  env = getenv("ABT_ENV_OS_PAGE_SIZE");
180  if (env != NULL) {
181  p_global->os_page_size = (uint32_t)atol(env);
182  } else {
183  p_global->os_page_size = ABTD_OS_PAGE_SIZE;
184  }
185 
186  /* Huge page size */
187  env = getenv("ABT_HUGE_PAGE_SIZE");
188  if (env == NULL)
189  env = getenv("ABT_ENV_HUGE_PAGE_SIZE");
190  if (env != NULL) {
191  p_global->huge_page_size = (uint32_t)atol(env);
192  } else {
193  p_global->huge_page_size = ABTD_HUGE_PAGE_SIZE;
194  }
195 
196 #ifdef ABT_CONFIG_USE_MEM_POOL
197  /* Page size for memory allocation */
198  env = getenv("ABT_MEM_PAGE_SIZE");
199  if (env == NULL)
200  env = getenv("ABT_ENV_MEM_PAGE_SIZE");
201  if (env != NULL) {
202  p_global->mem_page_size = (uint32_t)atol(env);
203  } else {
204  p_global->mem_page_size = ABTD_MEM_PAGE_SIZE;
205  }
206 
207  /* Stack page size for memory allocation */
208  env = getenv("ABT_MEM_STACK_PAGE_SIZE");
209  if (env == NULL)
210  env = getenv("ABT_ENV_MEM_STACK_PAGE_SIZE");
211  if (env != NULL) {
212  p_global->mem_sp_size = (size_t)atol(env);
213  } else {
214  p_global->mem_sp_size = ABTD_MEM_STACK_PAGE_SIZE;
215  }
216 
217  /* Maximum number of stacks that each ES can keep during execution */
218  env = getenv("ABT_MEM_MAX_NUM_STACKS");
219  if (env == NULL)
220  env = getenv("ABT_ENV_MEM_MAX_NUM_STACKS");
221  if (env != NULL) {
222  p_global->mem_max_stacks = (uint32_t)atol(env);
223  } else {
224  if (p_global->thread_stacksize * ABTD_MEM_MAX_NUM_STACKS >
225  ABTD_MEM_MAX_TOTAL_STACK_SIZE) {
226  /* Each execution stream caches too many stacks in total. Let's
227  * reduce the max # of stacks. */
228  p_global->mem_max_stacks =
229  ABTD_MEM_MAX_TOTAL_STACK_SIZE / p_global->thread_stacksize;
230  } else {
231  p_global->mem_max_stacks = ABTD_MEM_MAX_NUM_STACKS;
232  }
233  }
234  /* The value must be a multiple of ABT_MEM_POOL_MAX_LOCAL_BUCKETS. */
235  p_global->mem_max_stacks =
236  ((p_global->mem_max_stacks + ABT_MEM_POOL_MAX_LOCAL_BUCKETS - 1) /
239 
240  /* Maximum number of descriptors that each ES can keep during execution */
241  env = getenv("ABT_MEM_MAX_NUM_DESCS");
242  if (env == NULL)
243  env = getenv("ABT_ENV_MEM_MAX_NUM_DESCS");
244  if (env != NULL) {
245  p_global->mem_max_descs = (uint32_t)atol(env);
246  } else {
247  p_global->mem_max_descs = ABTD_MEM_MAX_NUM_DESCS;
248  }
249  /* The value must be a multiple of ABT_MEM_POOL_MAX_LOCAL_BUCKETS. */
250  p_global->mem_max_descs =
251  ((p_global->mem_max_descs + ABT_MEM_POOL_MAX_LOCAL_BUCKETS - 1) /
254 
255  /* How to allocate large pages. The default is to use mmap() for huge
256  * pages and then to fall back to allocate regular pages using mmap() when
257  * huge pages are run out of. */
258  env = getenv("ABT_MEM_LP_ALLOC");
259  if (env == NULL)
260  env = getenv("ABT_ENV_MEM_LP_ALLOC");
261 #if defined(HAVE_MAP_ANONYMOUS) || defined(HAVE_MAP_ANON)
262 #if defined(__x86_64__)
263  int lp_alloc = ABTI_MEM_LP_MMAP_HP_RP;
264 #else
265  /*
266  * If hugepage is used, mmap() needs a correct size of hugepage; otherwise,
267  * error happens on munmap(). However, the default size is for typical
268  * x86/64 machines, not for other architectures, so the error happens when
269  * the hugepage size is different. To run Argobots with default settings
270  * on these architectures, we disable hugepage allocation by default on
271  * non-x86/64 architectures; on such a machine, hugepage settings should
272  * be explicitly enabled via an environmental variable.
273  *
274  * TODO: fix this issue by detecting and setting a correct hugepage size.
275  */
276  int lp_alloc = ABTI_MEM_LP_MALLOC;
277 #endif
278 #else
279  int lp_alloc = ABTI_MEM_LP_MALLOC;
280 #endif
281  if (env != NULL) {
282  if (strcasecmp(env, "malloc") == 0) {
283  lp_alloc = ABTI_MEM_LP_MALLOC;
284 #if defined(HAVE_MAP_ANONYMOUS) || defined(HAVE_MAP_ANON)
285  } else if (strcasecmp(env, "mmap_rp") == 0) {
286  lp_alloc = ABTI_MEM_LP_MMAP_RP;
287  } else if (strcasecmp(env, "mmap_hp_rp") == 0) {
288  lp_alloc = ABTI_MEM_LP_MMAP_HP_RP;
289  } else if (strcasecmp(env, "mmap_hp_thp") == 0) {
290  lp_alloc = ABTI_MEM_LP_MMAP_HP_THP;
291 #endif
292  } else if (strcasecmp(env, "thp") == 0) {
293  lp_alloc = ABTI_MEM_LP_THP;
294  }
295  }
296 
297  /* Check if the requested allocation method is really possible. */
298  if (lp_alloc != ABTI_MEM_LP_MALLOC) {
299  p_global->mem_lp_alloc = ABTI_mem_check_lp_alloc(lp_alloc);
300  } else {
301  p_global->mem_lp_alloc = lp_alloc;
302  }
303 #endif
304 
305  /* Whether to print the configuration on ABT_init() */
306  env = getenv("ABT_PRINT_CONFIG");
307  if (env == NULL)
308  env = getenv("ABT_ENV_PRINT_CONFIG");
309  if (env != NULL) {
310  if (strcmp(env, "1") == 0 || strcasecmp(env, "yes") == 0 ||
311  strcasecmp(env, "y") == 0) {
312  p_global->print_config = ABT_TRUE;
313  } else {
314  p_global->print_config = ABT_FALSE;
315  }
316  } else {
317  p_global->print_config = ABT_FALSE;
318  }
319 
320  /* Init timer */
321  ABTD_time_init();
322 }
#define ABT_MEM_POOL_MAX_LOCAL_BUCKETS
Definition: abti_mem_pool.h:9
#define ABT_CONFIG_STATIC_CACHELINE_SIZE
Definition: abt_config.h:57
#define ABT_FALSE
Definition: abt.h:285
#define ABT_TRUE
Definition: abt.h:284