ARGOBOTS  4dc37e16e1b227a480715ab67dae1dcfb4d2d4e0
prio.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 /* Priority Scheduler Implementation */
9 
10 static int sched_init(ABT_sched sched, ABT_sched_config config);
11 static void sched_run(ABT_sched sched);
12 static int sched_free(ABT_sched);
13 
15  .init = sched_init,
16  .run = sched_run,
17  .free = sched_free,
18  .get_migr_pool = NULL };
19 
20 typedef struct {
21  uint32_t event_freq;
22  int num_pools;
23  ABT_pool *pools;
24 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
25  struct timespec sleep_time;
26 #endif
27 } sched_data;
28 
29 ABT_sched_def *ABTI_sched_get_prio_def(void)
30 {
31  return &sched_prio_def;
32 }
33 
34 static inline sched_data *sched_data_get_ptr(void *data)
35 {
36  return (sched_data *)data;
37 }
38 
39 static int sched_init(ABT_sched sched, ABT_sched_config config)
40 {
41  int abt_errno;
42  int num_pools;
43  ABTI_global *p_global = ABTI_global_get_global();
44 
45  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
46  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
47  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
48 
49  /* Default settings */
50  sched_data *p_data;
51  abt_errno = ABTU_malloc(sizeof(sched_data), (void **)&p_data);
52  ABTI_CHECK_ERROR(abt_errno);
53 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
54  p_data->sleep_time.tv_sec = 0;
55  p_data->sleep_time.tv_nsec = p_global->sched_sleep_nsec;
56 #endif
57 
58  /* Set the default value by default. */
59  p_data->event_freq = p_global->sched_event_freq;
60  if (p_config) {
61  int event_freq;
62  /* Set the variables from config */
63  abt_errno = ABTI_sched_config_read(p_config, ABT_sched_basic_freq.idx,
64  &event_freq);
65  if (abt_errno == ABT_SUCCESS) {
66  p_data->event_freq = event_freq;
67  }
68  }
69 
70  /* Save the list of pools */
71  num_pools = p_sched->num_pools;
72  p_data->num_pools = num_pools;
73  abt_errno =
74  ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&p_data->pools);
75  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
76  ABTU_free(p_data);
77  ABTI_CHECK_ERROR(abt_errno);
78  }
79  memcpy(p_data->pools, p_sched->pools, sizeof(ABT_pool) * num_pools);
80 
81  p_sched->data = p_data;
82  return ABT_SUCCESS;
83 }
84 
85 static void sched_run(ABT_sched sched)
86 {
87  ABTI_global *p_global = ABTI_global_get_global();
88  ABTI_xstream *p_local_xstream =
89  ABTI_local_get_xstream(ABTI_local_get_local());
90  uint32_t work_count = 0;
91  sched_data *p_data;
92  uint32_t event_freq;
93  int num_pools;
94  ABT_pool *pools;
95  int i;
96  CNT_DECL(run_cnt);
97 
98  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
99  ABTI_ASSERT(p_sched);
100 
101  p_data = sched_data_get_ptr(p_sched->data);
102  event_freq = p_data->event_freq;
103  num_pools = p_sched->num_pools;
104  pools = p_data->pools;
105 
106  while (1) {
107  CNT_INIT(run_cnt, 0);
108 
109  /* Execute one work unit from the scheduler's pool */
110  /* The pool with lower index has higher priority. */
111  for (i = 0; i < num_pools; i++) {
112  ABT_pool pool = pools[i];
113  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
114  ABT_thread thread =
115  ABTI_pool_pop(p_pool, ABT_POOL_CONTEXT_OP_POOL_OTHER);
116  if (thread != ABT_THREAD_NULL) {
117  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
118  ABTI_ythread_schedule(p_global, &p_local_xstream, p_thread);
119  CNT_INC(run_cnt);
120  break;
121  }
122  }
123 
124  if (++work_count >= event_freq) {
125  ABTI_xstream_check_events(p_local_xstream, p_sched);
126  if (ABTI_sched_has_to_stop(p_sched) == ABT_TRUE)
127  break;
128  work_count = 0;
129  SCHED_SLEEP(run_cnt, p_data->sleep_time);
130  }
131  }
132 }
133 
134 static int sched_free(ABT_sched sched)
135 {
136  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
137  ABTI_ASSERT(p_sched);
138 
139  sched_data *p_data = sched_data_get_ptr(p_sched->data);
140  ABTU_free(p_data->pools);
141  ABTU_free(p_data);
142  return ABT_SUCCESS;
143 }
sched_run
static void sched_run(ABT_sched sched)
Definition: prio.c:85
ABT_sched_def::type
ABT_sched_type type
Unused value.
Definition: abt.h:1418
ABT_thread
struct ABT_thread_opaque * ABT_thread
Work unit handle type.
Definition: abt.h:932
ABT_POOL_CONTEXT_OP_POOL_OTHER
#define ABT_POOL_CONTEXT_OP_POOL_OTHER
A flag that hints an unspecified pool operation.
Definition: abt.h:1660
ABT_sched_config
struct ABT_sched_config_opaque * ABT_sched_config
Scheduler configuration handle type.
Definition: abt.h:852
sched_init
static int sched_init(ABT_sched sched, ABT_sched_config config)
Definition: prio.c:39
ABT_THREAD_NULL
#define ABT_THREAD_NULL
Definition: abt.h:1105
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:878
ABT_sched
struct ABT_sched_opaque * ABT_sched
Scheduler handle type.
Definition: abt.h:845
ABT_SCHED_TYPE_ULT
@ ABT_SCHED_TYPE_ULT
Definition: abt.h:502
abti.h
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
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:784
sched_data_get_ptr
static sched_data * sched_data_get_ptr(void *data)
Definition: prio.c:34
CNT_INIT
#define CNT_INIT(c, v)
Definition: abti_sched.h:79
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:228
ABT_sched_def
A struct that defines a scheduler.
Definition: abt.h:1411
CNT_DECL
#define CNT_DECL(c)
Definition: abti_sched.h:78
SCHED_SLEEP
#define SCHED_SLEEP(c, t)
Definition: abti_sched.h:81
sched_prio_def
static ABT_sched_def sched_prio_def
Definition: prio.c:14
ABT_sched_basic_freq
ABT_sched_config_var ABT_sched_basic_freq
Predefined ABT_sched_config_var to configure the frequency for checking events of the basic scheduler...
Definition: sched_config.c:51
sched_free
static int sched_free(ABT_sched)
Definition: prio.c:134
CNT_INC
#define CNT_INC(c)
Definition: abti_sched.h:80
ABT_sched_config_var::idx
int idx
Definition: abt.h:1351