Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:47:30

0001 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
0002 /*
0003  * Copyright (c) 2011-2015 Los Alamos National Security, LLC. All rights
0004  *                         reserved.
0005  * Copyright (c) 2017-2019 Intel, Inc.  All rights reserved.
0006  * Copyright (c) 2020      Cisco Systems, Inc.  All rights reserved
0007  * Copyright (c) 2021-2024 Nanook Consulting.  All rights reserved.
0008  * $COPYRIGHT$
0009  *
0010  * Additional copyrights may follow
0011  *
0012  * $HEADER$
0013  */
0014 
0015 /****    PRTE STATE MACHINE    ****/
0016 
0017 /* States are treated as events so that the event
0018  * library can sequence them. Each state consists
0019  * of an event, a job or process state, a pointer
0020  * to the respective object, and a callback function
0021  * to be executed for that state. Events can be defined
0022  * at different priorities - e.g., SYS priority for
0023  * events associated with launching jobs, and ERR priority
0024  * for events associated with abnormal termination of
0025  * a process.
0026  *
0027  * The state machine consists of a list of state objects,
0028  * each defining a state-cbfunc pair. At startup, a default
0029  * list is created by the base functions which is then
0030  * potentially customized by selected components within
0031  * the various PRTE frameworks. For example, a PLM component
0032  * may need to insert states in the launch procedure, or may
0033  * want to redirect a particular state callback to a custom
0034  * function.
0035  *
0036  * For convenience, an ANY state can be defined along with a generic
0037  * callback function, with the corresponding state object
0038  * placed at the end of the state machine. Setting the
0039  * machine to a state that has not been explicitly defined
0040  * will cause this default action to be executed. Thus, you
0041  * don't have to explicitly define a state-cbfunc pair
0042  * for every job or process state.
0043  */
0044 
0045 #ifndef _PRTE_STATE_H_
0046 #define _PRTE_STATE_H_
0047 
0048 #include "prte_config.h"
0049 
0050 #include "src/class/pmix_list.h"
0051 #include "src/event/event-internal.h"
0052 #include "src/pmix/pmix-internal.h"
0053 
0054 #include "src/mca/errmgr/errmgr.h"
0055 #include "src/mca/plm/plm_types.h"
0056 #include "src/mca/state/state_types.h"
0057 #include "src/runtime/prte_globals.h"
0058 #include "src/util/error_strings.h"
0059 
0060 BEGIN_C_DECLS
0061 
0062 /*
0063  * MCA Framework - put here to access the pmix_output channel
0064  * in the macros
0065  */
0066 PRTE_EXPORT extern pmix_mca_base_framework_t prte_state_base_framework;
0067 
0068 #ifdef HAVE_SYS_TIME_H
0069 #    include <sys/time.h>
0070 #endif
0071 
0072 /* For ease in debugging the state machine, it is STRONGLY recommended
0073  * that the functions be accessed using the following macros
0074  */
0075 
0076 /* Timestamp for state printouts */
0077 #define PRTE_STATE_GET_TIMESTAMP(t)           \
0078     do {                                      \
0079         struct timeval tv;                    \
0080         gettimeofday(&tv, NULL);              \
0081         t = tv.tv_sec;                        \
0082         t += (double) tv.tv_usec / 1000000.0; \
0083     } while (0);
0084 
0085 #define PRTE_ACTIVATE_JOB_STATE(j, s)                                                         \
0086     do {                                                                                      \
0087         prte_job_t *shadow = (j);                                                             \
0088         if (prte_state_base_framework.framework_verbose > 0) {                                \
0089             double timestamp = 0.0;                                                           \
0090             PRTE_STATE_GET_TIMESTAMP(timestamp);                                              \
0091             pmix_output_verbose(1, prte_state_base_framework.framework_output,                \
0092                                 "%s [%f] ACTIVATE JOB %s STATE %s AT %s:%d",                  \
0093                                 PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), timestamp,                \
0094                                 (NULL == shadow) ? "NULL" : PRTE_JOBID_PRINT(shadow->nspace), \
0095                                 prte_job_state_to_str((s)), __FILE__, __LINE__);              \
0096         }                                                                                     \
0097         prte_state.activate_job_state(shadow, (s));                                           \
0098     } while (0);
0099 
0100 #define PRTE_ACTIVATE_PROC_STATE(p, s)                                               \
0101     do {                                                                             \
0102         pmix_proc_t *shadow = (p);                                                   \
0103         if (prte_state_base_framework.framework_verbose > 0) {                       \
0104             double timestamp = 0.0;                                                  \
0105             PRTE_STATE_GET_TIMESTAMP(timestamp);                                     \
0106             pmix_output_verbose(1, prte_state_base_framework.framework_output,       \
0107                                 "%s [%f] ACTIVATE PROC %s STATE %s AT %s:%d",        \
0108                                 PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), timestamp,       \
0109                                 (NULL == shadow) ? "NULL" : PRTE_NAME_PRINT(shadow), \
0110                                 prte_proc_state_to_str((s)), __FILE__, __LINE__);    \
0111         }                                                                            \
0112         prte_state.activate_proc_state(shadow, (s));                                 \
0113     } while (0);
0114 
0115 /* Called when actually arriving (reaching) the state with priority k */
0116 #define PRTE_REACHING_JOB_STATE(j, s)                                                         \
0117     do {                                                                                      \
0118         prte_job_t *shadow = (j);                                                             \
0119         if (prte_state_base_framework.framework_verbose > 0) {                                \
0120             double timestamp = 0.0;                                                           \
0121             PRTE_STATE_GET_TIMESTAMP(timestamp);                                              \
0122             pmix_output_verbose(1, prte_state_base_framework.framework_output,                \
0123                                 "%s [%f] ACTIVATING JOB %s STATE %s",                         \
0124                                 PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), timestamp,                \
0125                                 (NULL == shadow) ? "NULL" : PRTE_JOBID_PRINT(shadow->nspace), \
0126                                 prte_job_state_to_str((s)));                                  \
0127         }                                                                                     \
0128     } while (0);
0129 
0130 #define PRTE_REACHING_PROC_STATE(p, s)                                               \
0131     do {                                                                             \
0132         pmix_proc_t *shadow = (p);                                                   \
0133         if (prte_state_base_framework.framework_verbose > 0) {                       \
0134             double timestamp = 0.0;                                                  \
0135             PRTE_STATE_GET_TIMESTAMP(timestamp);                                     \
0136             pmix_output_verbose(1, prte_state_base_framework.framework_output,       \
0137                                 "%s [%f] ACTIVATING PROC %s STATE %s",               \
0138                                 PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), timestamp,       \
0139                                 (NULL == shadow) ? "NULL" : PRTE_NAME_PRINT(shadow), \
0140                                 prte_proc_state_to_str((s)));                        \
0141         }                                                                            \
0142     } while (0);
0143 
0144 /**
0145  * Module initialization function.
0146  *
0147  * @retval PRTE_SUCCESS The operation completed successfully
0148  * @retval PRTE_ERROR   An unspecifed error occurred
0149  */
0150 typedef int (*prte_state_base_module_init_fn_t)(void);
0151 
0152 /**
0153  * Module finalization function.
0154  *
0155  * @retval PRTE_SUCCESS The operation completed successfully
0156  * @retval PRTE_ERROR   An unspecifed error occurred
0157  */
0158 typedef int (*prte_state_base_module_finalize_fn_t)(void);
0159 
0160 /****    JOB STATE APIs    ****/
0161 /* Job states are accessed via prte_job_t objects as they are only
0162  * used in PRTE tools and not application processes. APIs are provided
0163  * for assembling and editing the state machine, as well as activating
0164  * a specific job state
0165  *
0166  * Note the inherent assumption in this design that any customization
0167  * of the state machine will at least start with the base states - i.e.,
0168  * that one would start with the default machine and edit it to add,
0169  * remove, or modify callbacks as required. Alternatively, one could
0170  * just clear the list entirely and assemble a fully custom state
0171  * machine - both models are supported.
0172  */
0173 
0174 /* Activate a state in the job state machine.
0175  *
0176  * Creates and activates an event with the callback corresponding to the
0177  * specified job state. If the specified state is not found:
0178  *
0179  * 1. if a state machine entry for PRTE_JOB_STATE_ERROR was given, and
0180  *    the state is an error state (i.e., PRTE_JOB_STATE_ERROR <= state),
0181  *    then the callback for the ERROR state will be used
0182  *
0183  * 2. if a state machine entry for PRTE_JOB_STATE_ANY was given, and
0184  *    the state is not an error state (i.e., state < PRTE_JOB_STATE_ERROR),
0185  *    then the callback for the ANY state will be used
0186  *
0187  * 3. if neither of the above is true, then the call will be ignored.
0188  */
0189 typedef void (*prte_state_base_module_activate_job_state_fn_t)(prte_job_t *jdata,
0190                                                                prte_job_state_t state);
0191 
0192 /* Add a state to the job state machine.
0193  *
0194  */
0195 typedef int (*prte_state_base_module_add_job_state_fn_t)(prte_job_state_t state,
0196                                                          prte_state_cbfunc_t cbfunc);
0197 
0198 /* Set the callback function for a state in the job state machine.
0199  *
0200  */
0201 typedef int (*prte_state_base_module_set_job_state_callback_fn_t)(prte_job_state_t state,
0202                                                                   prte_state_cbfunc_t cbfunc);
0203 
0204 /* Remove a state from the job state machine.
0205  *
0206  */
0207 typedef int (*prte_state_base_module_remove_job_state_fn_t)(prte_job_state_t state);
0208 
0209 /****    Proc STATE APIs  ****/
0210 /* Proc states are accessed via pmix_proc_t as the state machine
0211  * must be available to both application processes and PRTE tools. APIs are
0212  * providedfor assembling and editing the state machine, as well as activating
0213  * a specific proc state
0214  *
0215  * Note the inherent assumption in this design that any customization
0216  * of the state machine will at least start with the base states - i.e.,
0217  * that one would start with the default machine and edit it to add,
0218  * remove, or modify callbacks as required. Alternatively, one could
0219  * just clear the list entirely and assemble a fully custom state
0220  * machine - both models are supported.
0221  */
0222 
0223 /* Activate a proc state.
0224  *
0225  * Creates and activates an event with the callback corresponding to the
0226  * specified proc state. If the specified state is not found:
0227  *
0228  * 1. if a state machine entry for PRTE_PROC_STATE_ERROR was given, and
0229  *    the state is an error state (i.e., PRTE_PROC_STATE_ERROR <= state),
0230  *    then the callback for the ERROR state will be used
0231  *
0232  * 2. if a state machine entry for PRTE_PROC_STATE_ANY was given, and
0233  *    the state is not an error state (i.e., state < PRTE_PROC_STATE_ERROR),
0234  *    then the callback for the ANY state will be used
0235  *
0236  * 3. if neither of the above is true, then the call will be ignored.
0237  */
0238 typedef void (*prte_state_base_module_activate_proc_state_fn_t)(pmix_proc_t *proc,
0239                                                                 prte_proc_state_t state);
0240 
0241 /* Add a state to the proc state machine.
0242  *
0243  */
0244 typedef int (*prte_state_base_module_add_proc_state_fn_t)(prte_proc_state_t state,
0245                                                           prte_state_cbfunc_t cbfunc);
0246 
0247 /* Set the callback function for a state in the proc state machine.
0248  *
0249  */
0250 typedef int (*prte_state_base_module_set_proc_state_callback_fn_t)(prte_proc_state_t state,
0251                                                                    prte_state_cbfunc_t cbfunc);
0252 
0253 /* Remove a state from the proc state machine.
0254  *
0255  */
0256 typedef int (*prte_state_base_module_remove_proc_state_fn_t)(prte_proc_state_t state);
0257 
0258 /*
0259  * Module Structure
0260  */
0261 struct prte_state_base_module_1_0_0_t {
0262     /** Initialization Function */
0263     prte_state_base_module_init_fn_t init;
0264     /** Finalization Function */
0265     prte_state_base_module_finalize_fn_t finalize;
0266     /* Job state APIs */
0267     prte_state_base_module_activate_job_state_fn_t activate_job_state;
0268     prte_state_base_module_add_job_state_fn_t add_job_state;
0269     prte_state_base_module_set_job_state_callback_fn_t set_job_state_callback;
0270     prte_state_base_module_remove_job_state_fn_t remove_job_state;
0271     /* Proc state APIs */
0272     prte_state_base_module_activate_proc_state_fn_t activate_proc_state;
0273     prte_state_base_module_add_proc_state_fn_t add_proc_state;
0274     prte_state_base_module_set_proc_state_callback_fn_t set_proc_state_callback;
0275     prte_state_base_module_remove_proc_state_fn_t remove_proc_state;
0276 };
0277 typedef struct prte_state_base_module_1_0_0_t prte_state_base_module_1_0_0_t;
0278 typedef prte_state_base_module_1_0_0_t prte_state_base_module_t;
0279 PRTE_EXPORT extern prte_state_base_module_t prte_state;
0280 
0281 /*
0282  * State Component
0283  */
0284 typedef pmix_mca_base_component_t prte_state_base_component_t;
0285 
0286 /*
0287  * Macro for use in components that are of type state
0288  */
0289 #define PRTE_STATE_BASE_VERSION_1_0_0 PRTE_MCA_BASE_VERSION_3_0_0("state", 1, 0, 0)
0290 
0291 END_C_DECLS
0292 #endif