ARGOBOTS
basic.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 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
30  struct timespec sleep_time;
31 #endif
32 } sched_data;
33 
35  .type = ABT_SCHED_CONFIG_INT };
36 
37 ABT_sched_def *ABTI_sched_get_basic_def(void)
38 {
39  return &sched_basic_def;
40 }
41 
42 static inline sched_data *sched_data_get_ptr(void *data)
43 {
44  return (sched_data *)data;
45 }
46 
47 static int sched_init(ABT_sched sched, ABT_sched_config config)
48 {
49  int abt_errno = ABT_SUCCESS;
50  int num_pools;
51 
52  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
53  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
54 
55  /* Default settings */
56  sched_data *p_data = (sched_data *)ABTU_malloc(sizeof(sched_data));
57  p_data->event_freq = ABTI_global_get_sched_event_freq();
58 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
59  p_data->sleep_time.tv_sec = 0;
60  p_data->sleep_time.tv_nsec = ABTI_global_get_sched_sleep_nsec();
61 #endif
62 
63  /* Set the variables from the config */
64  void *p_event_freq = &p_data->event_freq;
65  ABTI_sched_config_read(config, 1, 1, &p_event_freq);
66 
67  /* Save the list of pools */
68  num_pools = p_sched->num_pools;
69  p_data->num_pools = num_pools;
70  p_data->pools = (ABT_pool *)ABTU_malloc(num_pools * sizeof(ABT_pool));
71  memcpy(p_data->pools, p_sched->pools, sizeof(ABT_pool) * num_pools);
72 
73  /* Sort pools according to their access mode so the scheduler can execute
74  work units from the private pools. */
75  if (num_pools > 1) {
76  sched_sort_pools(num_pools, p_data->pools);
77  }
78 
79  p_sched->data = p_data;
80 
81 fn_exit:
82  return abt_errno;
83 
84 fn_fail:
85  HANDLE_ERROR_WITH_CODE("basic: sched_init", abt_errno);
86  goto fn_exit;
87 }
88 
89 static void sched_run(ABT_sched sched)
90 {
91  ABTI_local *p_local = ABTI_local_get_local();
92  ABT_unit unit = ABT_UNIT_NULL;
93  uint32_t pop_count = 0;
94  sched_data *p_data;
95  uint32_t event_freq;
96  int num_pools;
97  ABT_pool *pools;
98  int i;
99 
100  ABTI_xstream *p_xstream = p_local->p_xstream;
101  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
102  ABTI_ASSERT(p_sched);
103 
104  p_data = sched_data_get_ptr(p_sched->data);
105  event_freq = p_data->event_freq;
106  num_pools = p_data->num_pools;
107  pools = p_data->pools;
108 
109  while (1) {
110  for (i = 0; i < num_pools; i++) {
111  ABTI_pool *p_pool = ABTI_pool_get_ptr(pools[i]);
112  ++pop_count;
113  if ((unit = ABTI_pool_pop(p_pool)) != ABT_UNIT_NULL) {
114  ABTI_xstream_run_unit(&p_local, p_xstream, unit, p_pool);
115  break;
116  }
117  }
118  /* if we attempted event_freq pops, check for events */
119  if (pop_count >= event_freq) {
120  ABTI_xstream_check_events(p_xstream, sched);
121  if (ABTI_sched_has_to_stop(&p_local, p_sched, p_xstream) ==
122  ABT_TRUE)
123  break;
124  SCHED_SLEEP(unit != ABT_UNIT_NULL, p_data->sleep_time);
125  pop_count = 0;
126  }
127  }
128 }
129 
130 static int sched_free(ABT_sched sched)
131 {
132  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
133  ABTI_ASSERT(p_sched);
134 
135  sched_data *p_data = sched_data_get_ptr(p_sched->data);
136  ABTU_free(p_data->pools);
137  ABTU_free(p_data);
138  return ABT_SUCCESS;
139 }
140 
141 static int pool_get_access_num(ABT_pool *p_pool)
142 {
143  ABT_pool_access access;
144  int num = 0;
145 
146  access = ABTI_pool_get_ptr(*p_pool)->access;
147  switch (access) {
149  num = 0;
150  break;
153  num = 1;
154  break;
157  num = 2;
158  break;
159  default:
160  ABTI_ASSERT(0);
161  break;
162  }
163 
164  return num;
165 }
166 
167 static int sched_cmp_pools(const void *p1, const void *p2)
168 {
169  int p1_access, p2_access;
170 
171  p1_access = pool_get_access_num((ABT_pool *)p1);
172  p2_access = pool_get_access_num((ABT_pool *)p2);
173 
174  if (p1_access > p2_access) {
175  return 1;
176  } else if (p1_access < p2_access) {
177  return -1;
178  } else {
179  return 0;
180  }
181 }
182 
183 static void sched_sort_pools(int num_pools, ABT_pool *pools)
184 {
185  qsort(pools, num_pools, sizeof(ABT_pool), sched_cmp_pools);
186 }
struct ABT_unit_opaque * ABT_unit
Definition: abt.h:275
static int pool_get_access_num(ABT_pool *p_pool)
Definition: basic.c:141
struct ABT_sched_opaque * ABT_sched
Definition: abt.h:257
#define ABT_UNIT_NULL
Definition: abt.h:343
static void * ABTU_malloc(size_t size)
Definition: abtu.h:39
static int sched_free(ABT_sched)
Definition: basic.c:130
struct ABT_pool_opaque * ABT_pool
Definition: abt.h:267
#define HANDLE_ERROR_WITH_CODE(msg, n)
Definition: abti_error.h:234
static int sched_cmp_pools(const void *p1, const void *p2)
Definition: basic.c:167
static int sched_init(ABT_sched sched, ABT_sched_config config)
Definition: basic.c:47
#define ABT_SUCCESS
Definition: abt.h:64
ABT_pool_access
Definition: abt.h:162
static void sched_run(ABT_sched sched)
Definition: basic.c:89
#define ABT_TRUE
Definition: abt.h:223
static sched_data * sched_data_get_ptr(void *data)
Definition: basic.c:42
ABT_sched_type type
Definition: abt.h:387
static ABT_sched_def sched_basic_def
Definition: basic.c:17
ABT_sched_config_var ABT_sched_basic_freq
Definition: basic.c:34
#define SCHED_SLEEP(c, t)
Definition: abti_sched.h:91
struct ABT_sched_config_opaque * ABT_sched_config
Definition: abt.h:259
static void sched_sort_pools(int num_pools, ABT_pool *pools)
Definition: basic.c:183
static void ABTU_free(void *ptr)
Definition: abtu.h:32