root/ompi/mca/hook/base/hook_base.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ompi_hook_base_register
  2. ompi_hook_base_open
  3. ompi_hook_base_close
  4. ompi_hook_base_register_callbacks
  5. ompi_hook_base_deregister_callbacks
  6. ompi_hook_base_mpi_initialized_top
  7. ompi_hook_base_mpi_initialized_bottom
  8. ompi_hook_base_mpi_init_thread_top
  9. ompi_hook_base_mpi_init_thread_bottom
  10. ompi_hook_base_mpi_finalized_top
  11. ompi_hook_base_mpi_finalized_bottom
  12. ompi_hook_base_mpi_init_top
  13. ompi_hook_base_mpi_init_top_post_opal
  14. ompi_hook_base_mpi_init_bottom
  15. ompi_hook_base_mpi_init_error
  16. ompi_hook_base_mpi_finalize_top
  17. ompi_hook_base_mpi_finalize_bottom

   1 /*
   2  * Copyright (c) 2017      IBM Corporation.  All rights reserved.
   3  * Copyright (c) 2018      Research Organization for Information Science
   4  *                         and Technology (RIST).  All rights reserved.
   5  * $COPYRIGHT$
   6  *
   7  * Additional copyrights may follow
   8  *
   9  * $HEADER$
  10  */
  11 
  12 #include "ompi_config.h"
  13 
  14 #include <sys/types.h>
  15 #include <unistd.h>
  16 
  17 #include "ompi/mca/mca.h"
  18 #include "opal/mca/base/base.h"
  19 
  20 #include "opal/runtime/opal.h"
  21 #include "opal/util/output.h"
  22 #include "opal/util/show_help.h"
  23 #include "opal/class/opal_list.h"
  24 #include "opal/include/opal/prefetch.h"
  25 
  26 #include "ompi/constants.h"
  27 #include "ompi/mca/hook/hook.h"
  28 #include "ompi/mca/hook/base/base.h"
  29 
  30 /*
  31  * The following file was created by configure.  It contains extern
  32  * statements and the definition of an array of pointers to each
  33  * component's public mca_base_component_t struct.
  34  */
  35 #include "ompi/mca/hook/base/static-components.h"
  36 
  37 
  38 // Is the framework open - or has it been closed and we need to reopen it.
  39 static bool ompi_hook_is_framework_open = false;
  40 
  41 static opal_list_t *additional_callback_components = NULL;
  42 
  43 
  44 static int ompi_hook_base_register( mca_base_register_flag_t flags )
  45 {
  46     return OMPI_SUCCESS;
  47 }
  48 
  49 static int ompi_hook_base_open( mca_base_open_flag_t flags )
  50 {
  51     int ret;
  52     const mca_base_component_t **static_components = ompi_hook_base_framework.framework_static_components;
  53     mca_base_component_list_item_t *cli = NULL;
  54     mca_base_component_t *component = NULL;
  55     bool found = false;
  56 
  57     additional_callback_components = OBJ_NEW(opal_list_t);
  58 
  59     /* Open up all available components */
  60     ret = mca_base_framework_components_open( &ompi_hook_base_framework, flags );
  61     if (ret != OMPI_SUCCESS) {
  62         return ret;
  63     }
  64 
  65     /*
  66      * Make sure that the `MCA_BASE_COMPONENT_FLAG_REQUIRED` components defined
  67      * as static are loaded. If we find one that was avoided then error out.
  68      */
  69     if( NULL != static_components ) {
  70         for (int i = 0 ; NULL != static_components[i]; ++i) {
  71             if( static_components[i]->mca_component_flags & MCA_BASE_COMPONENT_FLAG_REQUIRED ) {
  72                 // Make sure that this component is in the list of components that
  73                 // were included in the earlier framework_components_open() call.
  74                 found = false;
  75                 OPAL_LIST_FOREACH(cli, &ompi_hook_base_framework.framework_components, mca_base_component_list_item_t) {
  76                     component = (mca_base_component_t*)cli->cli_component;
  77                     if( component == static_components[i] ) {
  78                         found = true;
  79                         break;
  80                     }
  81                 }
  82                 if( !found ) {
  83                     opal_show_help("help-mca-hook-base.txt", "hook:missing-required-component", true,
  84                                    ompi_hook_base_framework.framework_name,
  85                                    static_components[i]->mca_component_name);
  86                     return OPAL_ERR_NOT_SUPPORTED;
  87                 }
  88             }
  89         }
  90     }
  91 
  92     /* Assume that if the component is present then it wants to be used.
  93      * It has the option to have NULL as the function pointer for any
  94      * functions call hook locations they do not want to hear about
  95      */
  96 
  97     /*
  98      * There are three classes of components - we want them processed in this order
  99      * 1) static components
 100      * 2) dynamic components
 101      * 3) internal 'component' hooks (from other places in the code)
 102      *
 103      * The ordering of (1) and (2) is managed by mca_base_component_find().
 104      * We keep a separate list for the 'internal' hooks.
 105      */
 106 
 107     ompi_hook_is_framework_open = true;
 108 
 109     /* All done */
 110     return OMPI_SUCCESS;
 111 }
 112 
 113 static int ompi_hook_base_close( void )
 114 {
 115     int ret;
 116 
 117     /*
 118      * Close our components
 119      */
 120     ret = mca_base_framework_components_close( &ompi_hook_base_framework, NULL );
 121     if( OMPI_SUCCESS != ret ) {
 122         return ret;
 123     }
 124     OBJ_RELEASE(additional_callback_components);
 125     ompi_hook_is_framework_open = false;
 126 
 127     return OMPI_SUCCESS;
 128 }
 129 
 130 
 131 int ompi_hook_base_register_callbacks(ompi_hook_base_component_t *comp)
 132 {
 133     mca_base_component_list_item_t *cli;
 134 
 135     // Check if it is already there
 136     OPAL_LIST_FOREACH(cli, additional_callback_components, mca_base_component_list_item_t) {
 137         if( cli->cli_component == (mca_base_component_t*)comp ) {
 138             return OMPI_SUCCESS;
 139         }
 140     }
 141 
 142     // Not found, so add it to the list
 143     cli = OBJ_NEW(mca_base_component_list_item_t);
 144     cli->cli_component = (mca_base_component_t*)comp;
 145     opal_list_append(additional_callback_components, (opal_list_item_t*) cli);
 146 
 147     return OMPI_SUCCESS;
 148 }
 149 
 150 int ompi_hook_base_deregister_callbacks(ompi_hook_base_component_t *comp)
 151 {
 152     mca_base_component_list_item_t *cli;
 153 
 154     // Check if it is already there
 155     OPAL_LIST_FOREACH(cli, additional_callback_components, mca_base_component_list_item_t) {
 156         if( cli->cli_component == (mca_base_component_t*)comp ) {
 157             opal_list_remove_item(additional_callback_components, (opal_list_item_t*) cli);
 158             OBJ_RELEASE(cli);
 159             return OMPI_SUCCESS;
 160         }
 161     }
 162 
 163     return OMPI_ERR_NOT_FOUND;
 164 }
 165 
 166 MCA_BASE_FRAMEWORK_DECLARE(ompi, hook, "hook hooks",
 167                            ompi_hook_base_register,
 168                            ompi_hook_base_open,
 169                            ompi_hook_base_close,
 170                            mca_hook_base_static_components, 0);
 171 
 172 
 173 /* ***********************************************************************
 174  * ***********************************************************************
 175  * *********************************************************************** */
 176 
 177 /*
 178  * If the framework has not been opened, then we can only use the static components.
 179  *
 180  * Otherwise we would need to initialize opal outside of ompi_mpi_init and possibly
 181  * after ompi_mpi_finalize which gets messy (especially when trying to cleanup).
 182  */
 183 #define HOOK_CALL_COMMON_HOOK_NOT_INITIALIZED(fn_name, ...)             \
 184     do {                                                                \
 185         ompi_hook_base_component_t *component;                          \
 186         int idx;                                                        \
 187                                                                         \
 188         for(idx = 0; NULL != mca_hook_base_static_components[idx]; ++idx ) { \
 189             component = (ompi_hook_base_component_t*)mca_hook_base_static_components[idx]; \
 190             if( NULL != component->hookm_ ## fn_name &&                 \
 191                 ompi_hook_base_ ## fn_name != component->hookm_ ## fn_name ) { \
 192                 component->hookm_ ## fn_name ( __VA_ARGS__ );           \
 193             }                                                           \
 194         }                                                               \
 195     } while(0)
 196 
 197 /*
 198  * Once the framework is open then call all available components with
 199  * the approprate function pointer. Call order:
 200  * 1) static components
 201  * 2) dynamic components
 202  * 3) 'registered' components (those registered by ompi_hook_base_register_callbacks)
 203  */
 204 #define HOOK_CALL_COMMON_HOOK_INITIALIZED(fn_name, ...)                 \
 205     do {                                                                \
 206         mca_base_component_list_item_t *cli;                            \
 207         ompi_hook_base_component_t *component;                          \
 208                                                                         \
 209         OPAL_LIST_FOREACH(cli, &ompi_hook_base_framework.framework_components, mca_base_component_list_item_t) { \
 210             component = (ompi_hook_base_component_t*)cli->cli_component; \
 211             if( NULL != component->hookm_ ## fn_name &&                 \
 212                 ompi_hook_base_ ## fn_name != component->hookm_ ## fn_name ) { \
 213                 component->hookm_ ## fn_name ( __VA_ARGS__ );           \
 214             }                                                           \
 215         }                                                               \
 216                                                                         \
 217         OPAL_LIST_FOREACH(cli, additional_callback_components, mca_base_component_list_item_t) { \
 218             component = (ompi_hook_base_component_t*)cli->cli_component; \
 219             if( NULL != component->hookm_ ## fn_name &&                 \
 220                 ompi_hook_base_ ## fn_name != component->hookm_ ## fn_name ) { \
 221                 component->hookm_ ## fn_name ( __VA_ARGS__ );           \
 222             }                                                           \
 223         }                                                               \
 224     } while(0)
 225 
 226 #define HOOK_CALL_COMMON(fn_name, ...)                                  \
 227     do {                                                                \
 228         if( OPAL_LIKELY(ompi_hook_is_framework_open) ) {                \
 229             HOOK_CALL_COMMON_HOOK_INITIALIZED(fn_name, __VA_ARGS__);    \
 230         }                                                               \
 231         else {                                                          \
 232             HOOK_CALL_COMMON_HOOK_NOT_INITIALIZED(fn_name, __VA_ARGS__); \
 233         }                                                               \
 234     } while(0)
 235 
 236 
 237 
 238 void ompi_hook_base_mpi_initialized_top(int *flag)
 239 {
 240     HOOK_CALL_COMMON( mpi_initialized_top, flag );
 241 }
 242 
 243 void ompi_hook_base_mpi_initialized_bottom(int *flag)
 244 {
 245     HOOK_CALL_COMMON( mpi_initialized_bottom, flag );
 246 }
 247 
 248 
 249 void ompi_hook_base_mpi_init_thread_top(int *argc, char ***argv, int required, int *provided)
 250 {
 251     HOOK_CALL_COMMON( mpi_init_thread_top, argc, argv, required, provided );
 252 }
 253 
 254 void ompi_hook_base_mpi_init_thread_bottom(int *argc, char ***argv, int required, int *provided)
 255 {
 256     HOOK_CALL_COMMON( mpi_init_thread_bottom, argc, argv, required, provided );
 257 }
 258 
 259 
 260 void ompi_hook_base_mpi_finalized_top(int *flag)
 261 {
 262     HOOK_CALL_COMMON( mpi_finalized_top, flag );
 263 }
 264 
 265 void ompi_hook_base_mpi_finalized_bottom(int *flag)
 266 {
 267     HOOK_CALL_COMMON( mpi_finalized_bottom, flag );
 268 }
 269 
 270 
 271 void ompi_hook_base_mpi_init_top(int argc, char **argv, int requested, int *provided)
 272 {
 273     HOOK_CALL_COMMON( mpi_init_top, argc, argv, requested, provided);
 274 }
 275 
 276 void ompi_hook_base_mpi_init_top_post_opal(int argc, char **argv, int requested, int *provided)
 277 {
 278     HOOK_CALL_COMMON( mpi_init_top_post_opal, argc, argv, requested, provided);
 279 }
 280 
 281 void ompi_hook_base_mpi_init_bottom(int argc, char **argv, int requested, int *provided)
 282 {
 283     HOOK_CALL_COMMON( mpi_init_bottom, argc, argv, requested, provided);
 284 }
 285 
 286 void ompi_hook_base_mpi_init_error(int argc, char **argv, int requested, int *provided)
 287 {
 288     HOOK_CALL_COMMON( mpi_init_error, argc, argv, requested, provided);
 289 }
 290 
 291 
 292 void ompi_hook_base_mpi_finalize_top(void)
 293 {
 294     HOOK_CALL_COMMON( mpi_finalize_top, );
 295 }
 296 
 297 void ompi_hook_base_mpi_finalize_bottom(void)
 298 {
 299     HOOK_CALL_COMMON( mpi_finalize_bottom, );
 300 }

/* [<][>][^][v][top][bottom][index][help] */