ARGOBOTS  be805649b56a69fc4df1b6bc4efbc8911b854459
randws.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 /* Random Work-stealing 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 
16  .init = sched_init,
17  .run = sched_run,
18  .free = sched_free,
19  .get_migr_pool = NULL,
20 };
21 
22 typedef struct {
23  uint32_t event_freq;
24  int num_pools;
25  ABT_pool *pools;
26 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
27  struct timespec sleep_time;
28 #endif
29 } sched_data;
30 
31 ABT_sched_def *ABTI_sched_get_randws_def(void)
32 {
33  return &sched_randws_def;
34 }
35 
36 static int sched_init(ABT_sched sched, ABT_sched_config config)
37 {
38  int abt_errno;
39  int num_pools;
40  ABTI_global *p_global = ABTI_global_get_global();
41 
42  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
43  ABTI_CHECK_NULL_SCHED_PTR(p_sched);
44  ABTI_sched_config *p_config = ABTI_sched_config_get_ptr(config);
45 
46  /* Default settings */
47  sched_data *p_data;
48  abt_errno = ABTU_malloc(sizeof(sched_data), (void **)&p_data);
49  ABTI_CHECK_ERROR(abt_errno);
50 #ifdef ABT_CONFIG_USE_SCHED_SLEEP
51  p_data->sleep_time.tv_sec = 0;
52  p_data->sleep_time.tv_nsec = p_global->sched_sleep_nsec;
53 #endif
54 
55  /* Set the default value by default. */
56  p_data->event_freq = p_global->sched_event_freq;
57  if (p_config) {
58  int event_freq;
59  /* Set the variables from config */
60  abt_errno = ABTI_sched_config_read(p_config, ABT_sched_basic_freq.idx,
61  &event_freq);
62  if (abt_errno == ABT_SUCCESS) {
63  p_data->event_freq = event_freq;
64  }
65  }
66 
67  /* Save the list of pools */
68  num_pools = p_sched->num_pools;
69  p_data->num_pools = num_pools;
70  abt_errno =
71  ABTU_malloc(num_pools * sizeof(ABT_pool), (void **)&p_data->pools);
72  if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno != ABT_SUCCESS) {
73  ABTU_free(p_data);
74  ABTI_HANDLE_ERROR(abt_errno);
75  }
76  memcpy(p_data->pools, p_sched->pools, sizeof(ABT_pool) * num_pools);
77 
78  p_sched->data = p_data;
79  return ABT_SUCCESS;
80 }
81 
82 static void sched_run(ABT_sched sched)
83 {
84  ABTI_global *p_global = ABTI_global_get_global();
85  ABTI_xstream *p_local_xstream =
86  ABTI_local_get_xstream(ABTI_local_get_local());
87  uint32_t work_count = 0;
88  sched_data *p_data;
89  int num_pools;
90  ABT_pool *pools;
91  int target;
92  unsigned seed = time(NULL);
93  CNT_DECL(run_cnt);
94 
95  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
96  ABTI_ASSERT(p_sched);
97 
98  p_data = (sched_data *)p_sched->data;
99  num_pools = p_sched->num_pools;
100  pools = p_data->pools;
101 
102  while (1) {
103  CNT_INIT(run_cnt, 0);
104 
105  /* Execute one work unit from the scheduler's pool */
106  ABT_pool pool = pools[0];
107  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
108  ABT_thread thread =
109  ABTI_pool_pop(p_pool, ABT_POOL_CONTEXT_OWNER_PRIMARY);
110  if (thread != ABT_THREAD_NULL) {
111  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
112  ABTI_ythread_schedule(p_global, &p_local_xstream, p_thread);
113  CNT_INC(run_cnt);
114  } else if (num_pools > 1) {
115  /* Steal a work unit from other pools */
116  target =
117  (num_pools == 2) ? 1 : (rand_r(&seed) % (num_pools - 1) + 1);
118  pool = pools[target];
119  p_pool = ABTI_pool_get_ptr(pool);
120  thread = ABTI_pool_pop(p_pool, ABT_POOL_CONTEXT_OWNER_SECONDARY);
121  if (thread != ABT_THREAD_NULL) {
122  ABTI_thread *p_thread = ABTI_thread_get_ptr(thread);
123  ABTI_ythread_schedule(p_global, &p_local_xstream, p_thread);
124  CNT_INC(run_cnt);
125  }
126  }
127 
128  if (++work_count >= p_data->event_freq) {
129  ABTI_xstream_check_events(p_local_xstream, p_sched);
130  if (ABTI_sched_has_to_stop(p_sched) == ABT_TRUE)
131  break;
132  work_count = 0;
133  SCHED_SLEEP(run_cnt, p_data->sleep_time);
134  }
135  }
136 }
137 
138 static int sched_free(ABT_sched sched)
139 {
140  ABTI_sched *p_sched = ABTI_sched_get_ptr(sched);
141  ABTI_ASSERT(p_sched);
142 
143  sched_data *p_data = (sched_data *)p_sched->data;
144  ABTU_free(p_data->pools);
145  ABTU_free(p_data);
146  return ABT_SUCCESS;
147 }
ABT_sched_def::type
ABT_sched_type type
Unused value.
Definition: abt.h:1329
ABT_thread
struct ABT_thread_opaque * ABT_thread
Work unit handle type.
Definition: abt.h:908
sched_init
static int sched_init(ABT_sched sched, ABT_sched_config config)
Definition: randws.c:36
ABT_POOL_CONTEXT_OWNER_SECONDARY
#define ABT_POOL_CONTEXT_OWNER_SECONDARY
A flag that hints a secondary ownership of a pool.
Definition: abt.h:1560
ABT_sched_config
struct ABT_sched_config_opaque * ABT_sched_config
Scheduler configuration handle type.
Definition: abt.h:828
ABT_THREAD_NULL
#define ABT_THREAD_NULL
Definition: abt.h:1081
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:854
ABT_sched
struct ABT_sched_opaque * ABT_sched
Scheduler handle type.
Definition: abt.h:821
ABT_SCHED_TYPE_ULT
@ ABT_SCHED_TYPE_ULT
Definition: abt.h:502
abti.h
sched_randws_def
static ABT_sched_def sched_randws_def
Definition: randws.c:14
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:760
sched_run
static void sched_run(ABT_sched sched)
Definition: randws.c:82
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:1322
CNT_DECL
#define CNT_DECL(c)
Definition: abti_sched.h:78
ABT_POOL_CONTEXT_OWNER_PRIMARY
#define ABT_POOL_CONTEXT_OWNER_PRIMARY
A flag that hints a primary ownership of a pool.
Definition: abt.h:1543
SCHED_SLEEP
#define SCHED_SLEEP(c, t)
Definition: abti_sched.h:81
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
CNT_INC
#define CNT_INC(c)
Definition: abti_sched.h:80
sched_free
static int sched_free(ABT_sched)
Definition: randws.c:138
ABT_sched_config_var::idx
int idx
Definition: abt.h:1262