1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2011-2015 Los Alamos National Security, LLC. All rights
4 * reserved.
5 * Copyright (c) 2017 Intel, Inc. All rights reserved.
6 * $COPYRIGHT$
7 *
8 * Additional copyrights may follow
9 *
10 * $HEADER$
11 */
12
13 /**** ORTE STATE MACHINE ****/
14
15 /* States are treated as events so that the event
16 * library can sequence them. Each state consists
17 * of an event, a job or process state, a pointer
18 * to the respective object, and a callback function
19 * to be executed for that state. Events can be defined
20 * at different priorities - e.g., SYS priority for
21 * events associated with launching jobs, and ERR priority
22 * for events associated with abnormal termination of
23 * a process.
24 *
25 * The state machine consists of a list of state objects,
26 * each defining a state-cbfunc pair. At startup, a default
27 * list is created by the base functions which is then
28 * potentially customized by selected components within
29 * the various ORTE frameworks. For example, a PLM component
30 * may need to insert states in the launch procedure, or may
31 * want to redirect a particular state callback to a custom
32 * function.
33 *
34 * For convenience, an ANY state can be defined along with a generic
35 * callback function, with the corresponding state object
36 * placed at the end of the state machine. Setting the
37 * machine to a state that has not been explicitly defined
38 * will cause this default action to be executed. Thus, you
39 * don't have to explicitly define a state-cbfunc pair
40 * for every job or process state.
41 */
42
43 #ifndef _ORTE_STATE_H_
44 #define _ORTE_STATE_H_
45
46 #include "orte_config.h"
47
48 #include "opal/class/opal_list.h"
49 #include "opal/mca/event/event.h"
50
51 #include "orte/mca/errmgr/errmgr.h"
52 #include "orte/mca/plm/plm_types.h"
53 #include "orte/runtime/orte_globals.h"
54
55 #include "orte/mca/state/state_types.h"
56
57 BEGIN_C_DECLS
58
59 /*
60 * MCA Framework - put here to access the opal_output channel
61 * in the macros
62 */
63 ORTE_DECLSPEC extern mca_base_framework_t orte_state_base_framework;
64
65 /* For ease in debugging the state machine, it is STRONGLY recommended
66 * that the functions be accessed using the following macros
67 */
68 #define ORTE_FORCED_TERMINATE(x) \
69 do { \
70 if (!orte_abnormal_term_ordered) { \
71 orte_errmgr.abort((x), "%s FORCE-TERMINATE AT %s:%d - error %s(%d)", \
72 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), \
73 ORTE_ERROR_NAME((x)), (x), \
74 __FILE__, __LINE__); \
75 } \
76 } while(0);
77
78 #define ORTE_ACTIVATE_JOB_STATE(j, s) \
79 do { \
80 orte_job_t *shadow=(j); \
81 opal_output_verbose(1, orte_state_base_framework.framework_output, \
82 "%s ACTIVATE JOB %s STATE %s AT %s:%d", \
83 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), \
84 (NULL == shadow) ? "NULL" : \
85 ORTE_JOBID_PRINT(shadow->jobid), \
86 orte_job_state_to_str((s)), \
87 __FILE__, __LINE__); \
88 orte_state.activate_job_state(shadow, (s)); \
89 } while(0);
90
91 #define ORTE_ACTIVATE_PROC_STATE(p, s) \
92 do { \
93 orte_process_name_t *shadow=(p); \
94 opal_output_verbose(1, orte_state_base_framework.framework_output, \
95 "%s ACTIVATE PROC %s STATE %s AT %s:%d", \
96 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), \
97 (NULL == shadow) ? "NULL" : \
98 ORTE_NAME_PRINT(shadow), \
99 orte_proc_state_to_str((s)), \
100 __FILE__, __LINE__); \
101 orte_state.activate_proc_state(shadow, (s)); \
102 } while(0);
103
104 /**
105 * Module initialization function.
106 *
107 * @retval ORTE_SUCCESS The operation completed successfully
108 * @retval ORTE_ERROR An unspecifed error occurred
109 */
110 typedef int (*orte_state_base_module_init_fn_t)(void);
111
112 /**
113 * Module finalization function.
114 *
115 * @retval ORTE_SUCCESS The operation completed successfully
116 * @retval ORTE_ERROR An unspecifed error occurred
117 */
118 typedef int (*orte_state_base_module_finalize_fn_t)(void);
119
120 /**** JOB STATE APIs ****/
121 /* Job states are accessed via orte_job_t objects as they are only
122 * used in ORTE tools and not application processes. APIs are provided
123 * for assembling and editing the state machine, as well as activating
124 * a specific job state
125 *
126 * Note the inherent assumption in this design that any customization
127 * of the state machine will at least start with the base states - i.e.,
128 * that one would start with the default machine and edit it to add,
129 * remove, or modify callbacks as required. Alternatively, one could
130 * just clear the list entirely and assemble a fully custom state
131 * machine - both models are supported.
132 */
133
134 /* Activate a state in the job state machine.
135 *
136 * Creates and activates an event with the callback corresponding to the
137 * specified job state. If the specified state is not found:
138 *
139 * 1. if a state machine entry for ORTE_JOB_STATE_ERROR was given, and
140 * the state is an error state (i.e., ORTE_JOB_STATE_ERROR <= state),
141 * then the callback for the ERROR state will be used
142 *
143 * 2. if a state machine entry for ORTE_JOB_STATE_ANY was given, and
144 * the state is not an error state (i.e., state < ORTE_JOB_STATE_ERROR),
145 * then the callback for the ANY state will be used
146 *
147 * 3. if neither of the above is true, then the call will be ignored.
148 */
149 typedef void (*orte_state_base_module_activate_job_state_fn_t)(orte_job_t *jdata,
150 orte_job_state_t state);
151
152 /* Add a state to the job state machine.
153 *
154 */
155 typedef int (*orte_state_base_module_add_job_state_fn_t)(orte_job_state_t state,
156 orte_state_cbfunc_t cbfunc,
157 int priority);
158
159 /* Set the callback function for a state in the job state machine.
160 *
161 */
162 typedef int (*orte_state_base_module_set_job_state_callback_fn_t)(orte_job_state_t state,
163 orte_state_cbfunc_t cbfunc);
164
165 /* Set the event priority for a state in the job state machine.
166 *
167 */
168 typedef int (*orte_state_base_module_set_job_state_priority_fn_t)(orte_job_state_t state,
169 int priority);
170
171 /* Remove a state from the job state machine.
172 *
173 */
174 typedef int (*orte_state_base_module_remove_job_state_fn_t)(orte_job_state_t state);
175
176
177 /**** Proc STATE APIs ****/
178 /* Proc states are accessed via orte_process_name_t as the state machine
179 * must be available to both application processes and ORTE tools. APIs are
180 * providedfor assembling and editing the state machine, as well as activating
181 * a specific proc state
182 *
183 * Note the inherent assumption in this design that any customization
184 * of the state machine will at least start with the base states - i.e.,
185 * that one would start with the default machine and edit it to add,
186 * remove, or modify callbacks as required. Alternatively, one could
187 * just clear the list entirely and assemble a fully custom state
188 * machine - both models are supported.
189 */
190
191 /* Activate a proc state.
192 *
193 * Creates and activates an event with the callback corresponding to the
194 * specified proc state. If the specified state is not found:
195 *
196 * 1. if a state machine entry for ORTE_PROC_STATE_ERROR was given, and
197 * the state is an error state (i.e., ORTE_PROC_STATE_ERROR <= state),
198 * then the callback for the ERROR state will be used
199 *
200 * 2. if a state machine entry for ORTE_PROC_STATE_ANY was given, and
201 * the state is not an error state (i.e., state < ORTE_PROC_STATE_ERROR),
202 * then the callback for the ANY state will be used
203 *
204 * 3. if neither of the above is true, then the call will be ignored.
205 */
206 typedef void (*orte_state_base_module_activate_proc_state_fn_t)(orte_process_name_t *proc,
207 orte_proc_state_t state);
208
209 /* Add a state to the proc state machine.
210 *
211 */
212 typedef int (*orte_state_base_module_add_proc_state_fn_t)(orte_proc_state_t state,
213 orte_state_cbfunc_t cbfunc,
214 int priority);
215
216 /* Set the callback function for a state in the proc state machine.
217 *
218 */
219 typedef int (*orte_state_base_module_set_proc_state_callback_fn_t)(orte_proc_state_t state,
220 orte_state_cbfunc_t cbfunc);
221
222 /* Set the event priority for a state in the proc state machine.
223 *
224 */
225 typedef int (*orte_state_base_module_set_proc_state_priority_fn_t)(orte_proc_state_t state,
226 int priority);
227
228 /* Remove a state from the proc state machine.
229 *
230 */
231 typedef int (*orte_state_base_module_remove_proc_state_fn_t)(orte_proc_state_t state);
232
233
234 /*
235 * Module Structure
236 */
237 struct orte_state_base_module_1_0_0_t {
238 /** Initialization Function */
239 orte_state_base_module_init_fn_t init;
240 /** Finalization Function */
241 orte_state_base_module_finalize_fn_t finalize;
242 /* Job state APIs */
243 orte_state_base_module_activate_job_state_fn_t activate_job_state;
244 orte_state_base_module_add_job_state_fn_t add_job_state;
245 orte_state_base_module_set_job_state_callback_fn_t set_job_state_callback;
246 orte_state_base_module_set_job_state_priority_fn_t set_job_state_priority;
247 orte_state_base_module_remove_job_state_fn_t remove_job_state;
248 /* Proc state APIs */
249 orte_state_base_module_activate_proc_state_fn_t activate_proc_state;
250 orte_state_base_module_add_proc_state_fn_t add_proc_state;
251 orte_state_base_module_set_proc_state_callback_fn_t set_proc_state_callback;
252 orte_state_base_module_set_proc_state_priority_fn_t set_proc_state_priority;
253 orte_state_base_module_remove_proc_state_fn_t remove_proc_state;
254 };
255 typedef struct orte_state_base_module_1_0_0_t orte_state_base_module_1_0_0_t;
256 typedef orte_state_base_module_1_0_0_t orte_state_base_module_t;
257 ORTE_DECLSPEC extern orte_state_base_module_t orte_state;
258
259 /*
260 * State Component
261 */
262 struct orte_state_base_component_1_0_0_t {
263 /** MCA base component */
264 mca_base_component_t base_version;
265 /** MCA base data */
266 mca_base_component_data_t base_data;
267 };
268 typedef struct orte_state_base_component_1_0_0_t orte_state_base_component_1_0_0_t;
269 typedef orte_state_base_component_1_0_0_t orte_state_base_component_t;
270
271 /*
272 * Macro for use in components that are of type state
273 */
274 #define ORTE_STATE_BASE_VERSION_1_0_0 \
275 ORTE_MCA_BASE_VERSION_2_1_0("state", 1, 0, 0)
276
277 END_C_DECLS
278 #endif