ARGOBOTS
basic_wait.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 
12 static int sched_init(ABT_sched sched, ABT_sched_config config);
13 static void sched_run(ABT_sched sched);
14 static int sched_free(ABT_sched);
15 static void sched_sort_pools(int num_pools, ABT_pool *pools);
16 
19  .init = sched_init,
20  .run = sched_run,
21  .free = sched_free,
22  .get_migr_pool = NULL,
23 };
24 
25 typedef struct {
26  uint32_t event_freq;
27  int num_pools;
28  ABT_pool *pools;
29 } sched_data;
30 
32  .type =
34 
35 ABT_sched_def *ABTI_sched_get_basic_wait_def(void)
36 {
37  return &sched_basic_wait_def;
38 }
39 
40 static inline sched_data *sched_data_get_ptr(void *data)
41 {
42  return (sched_data *)data;
43 }
44 
45 static int sched_init(ABT_sched sched, ABT_sched_config config)
46 {
47  int abt_errno = ABT_SUCCESS;
48  int num_pools;
49 
50  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
51  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
52 
53  /* Default settings */
54  sched_data *p_data = (sched_data *)ABTU_malloc(sizeof(sched_data));
55  p_data->event_freq = ABTI_global_get_sched_event_freq();
56 
57  /* Set the variables from the config */
58  void *p_event_freq = &p_data->event_freq;
59  ABTI_sched_config_read(config, 1, 1, &p_event_freq);
60 
61  /* Save the list of pools */
62  num_pools = p_sched->num_pools;
63  p_data->num_pools = num_pools;
64  p_data->pools = (ABT_pool *)ABTU_malloc(num_pools * sizeof(ABT_pool));
65  memcpy(p_data->pools, p_sched->pools, sizeof(ABT_pool) * num_pools);
66 
67  /* Sort pools according to their access mode so the scheduler can execute
68  work units from the private pools. */
69  if (num_pools > 1) {
70  sched_sort_pools(num_pools, p_data->pools);
71  }
72 
73  p_sched->data = p_data;
74 
75 fn_exit:
76  return abt_errno;
77 
78 fn_fail:
79  HANDLE_ERROR_WITH_CODE("basic_wait: sched_init", abt_errno);
80  goto fn_exit;
81 }
82 
83 static void sched_run(ABT_sched sched)
84 {
85  ABTI_local *p_local = ABTI_local_get_local();
86  uint32_t work_count = 0;
87  sched_data *p_data;
88  uint32_t event_freq;
89  int num_pools;
90  ABT_pool *pools;
91  int i;
92  int run_cnt_nowait;
93 
94  ABTI_xstream *p_xstream = p_local->p_xstream;
95  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
96  ABTI_ASSERT(p_sched);
97 
98  p_data = sched_data_get_ptr(p_sched->data);
99  event_freq = p_data->event_freq;
100  num_pools = p_data->num_pools;
101  pools = p_data->pools;
102 
103  while (1) {
104  run_cnt_nowait = 0;
105 
106  /* Execute one work unit from the scheduler's pool */
107  for (i = 0; i < num_pools; i++) {
108  ABT_pool pool = pools[i];
109  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
110  /* Pop one work unit */
111  ABT_unit unit = ABTI_pool_pop(p_pool);
112  if (unit != ABT_UNIT_NULL) {
113  ABTI_xstream_run_unit(&p_local, p_xstream, unit, p_pool);
114  run_cnt_nowait++;
115  break;
116  }
117  }
118 
119  /* Block briefly on pop_timedwait() if we didn't find work to do in
120  * main loop above.
121  */
122  if (!run_cnt_nowait) {
123  double abstime = ABTI_get_wtime();
124  abstime += 0.1;
125  ABT_unit unit =
126  ABTI_pool_pop_timedwait(ABTI_pool_get_ptr(pools[0]), abstime);
127  if (unit != ABT_UNIT_NULL) {
128  ABTI_xstream_run_unit(&p_local, p_xstream, unit,
129  ABTI_pool_get_ptr(pools[0]));
130  break;
131  }
132  }
133 
134  /* If run_cnt_nowait is zero, that means that no units were
135  * found in first pass through pools and we must have called
136  * pop_timedwait above. We should check events regardless of
137  * work_count in that case for them to be processed in a timely
138  * manner
139  */
140  if (!run_cnt_nowait || (++work_count >= event_freq)) {
141  ABTI_xstream_check_events(p_xstream, sched);
142  ABT_bool stop =
143  ABTI_sched_has_to_stop(&p_local, p_sched, p_xstream);
144  if (stop == ABT_TRUE)
145  break;
146  work_count = 0;
147  }
148  }
149 }
150 
151 static int sched_free(ABT_sched sched)
152 {
153  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
154  ABTI_ASSERT(p_sched);
155 
156  sched_data *p_data = sched_data_get_ptr(p_sched->data);
157  ABTU_free(p_data->pools);
158  ABTU_free(p_data);
159  return ABT_SUCCESS;
160 }
161 
162 static int pool_get_access_num(ABT_pool *p_pool)
163 {
164  ABT_pool_access access;
165  int num = 0;
166 
167  access = ABTI_pool_get_ptr(*p_pool)->access;
168  switch (access) {
170  num = 0;
171  break;
174  num = 1;
175  break;
178  num = 2;
179  break;
180  default:
181  ABTI_ASSERT(0);
182  break;
183  }
184 
185  return num;
186 }
187 
188 static int sched_cmp_pools(const void *p1, const void *p2)
189 {
190  int p1_access, p2_access;
191 
192  p1_access = pool_get_access_num((ABT_pool *)p1);
193  p2_access = pool_get_access_num((ABT_pool *)p2);
194 
195  if (p1_access > p2_access) {
196  return 1;
197  } else if (p1_access < p2_access) {
198  return -1;
199  } else {
200  return 0;
201  }
202 }
203 
204 static void sched_sort_pools(int num_pools, ABT_pool *pools)
205 {
206  qsort(pools, num_pools, sizeof(ABT_pool), sched_cmp_pools);
207 }
struct ABT_unit_opaque * ABT_unit
Definition: abt.h:275
struct ABT_sched_opaque * ABT_sched
Definition: abt.h:257
static int sched_init(ABT_sched sched, ABT_sched_config config)
Definition: basic_wait.c:45
#define ABT_UNIT_NULL
Definition: abt.h:343
static void * ABTU_malloc(size_t size)
Definition: abtu.h:39
int ABT_bool
Definition: abt.h:309
struct ABT_pool_opaque * ABT_pool
Definition: abt.h:267
ABT_sched_config_var ABT_sched_basic_wait_freq
Definition: basic_wait.c:31
static int sched_free(ABT_sched)
Definition: basic_wait.c:151
#define HANDLE_ERROR_WITH_CODE(msg, n)
Definition: abti_error.h:234
static sched_data * sched_data_get_ptr(void *data)
Definition: basic_wait.c:40
static int sched_cmp_pools(const void *p1, const void *p2)
Definition: basic_wait.c:188
#define ABT_SUCCESS
Definition: abt.h:64
ABT_pool_access
Definition: abt.h:162
#define ABT_TRUE
Definition: abt.h:223
static void sched_run(ABT_sched sched)
Definition: basic_wait.c:83
static ABT_sched_def sched_basic_wait_def
Definition: basic_wait.c:17
ABT_sched_type type
Definition: abt.h:387
static void sched_sort_pools(int num_pools, ABT_pool *pools)
Definition: basic_wait.c:204
struct ABT_sched_config_opaque * ABT_sched_config
Definition: abt.h:259
static void ABTU_free(void *ptr)
Definition: abtu.h:32
static int pool_get_access_num(ABT_pool *p_pool)
Definition: basic_wait.c:162