root/oshmem/mca/atomic/base/atomic_base_select.c

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

DEFINITIONS

This source file includes following definitions.
  1. mca_atomic_base_select
  2. avail_com_compare
  3. check_components
  4. check_one_component
  5. query
  6. query_1_0_0

   1 /*
   2  * Copyright (c) 2013      Mellanox Technologies, Inc.
   3  *                         All rights reserved.
   4  * Copyright (c) 2015      Research Organization for Information Science
   5  *                         and Technology (RIST). All rights reserved.
   6  * $COPYRIGHT$
   7  *
   8  * Additional copyrights may follow
   9  *
  10  * $HEADER$
  11  */
  12 
  13 #include "oshmem_config.h"
  14 
  15 #include <stdio.h>
  16 #include <stdlib.h>
  17 #include <string.h>
  18 
  19 #include "oshmem/constants.h"
  20 
  21 #include "opal/class/opal_list.h"
  22 #include "oshmem/util/oshmem_util.h"
  23 #include "oshmem/mca/mca.h"
  24 #include "opal/mca/base/base.h"
  25 #include "opal/mca/base/mca_base_component_repository.h"
  26 
  27 #include "oshmem/mca/atomic/atomic.h"
  28 #include "oshmem/mca/atomic/base/base.h"
  29 
  30 /*
  31  * Global variables; most of which are loaded by back-ends of MCA
  32  * variables
  33  */
  34 mca_atomic_base_module_t mca_atomic = {{0}};
  35 
  36 /*
  37  * Local types
  38  */
  39 struct avail_com_t {
  40     opal_list_item_t super;
  41 
  42     int ac_priority;
  43     mca_atomic_base_module_t *ac_module;
  44 };
  45 typedef struct avail_com_t avail_com_t;
  46 
  47 /*
  48  * Local functions
  49  */
  50 static opal_list_t *check_components(opal_list_t * components);
  51 static int check_one_component(const mca_base_component_t * component,
  52                                mca_atomic_base_module_1_0_0_t ** module);
  53 
  54 static int query(const mca_base_component_t * component,
  55                  int *priority,
  56                  mca_atomic_base_module_1_0_0_t ** module);
  57 
  58 static int query_1_0_0(const mca_atomic_base_component_1_0_0_t * atomic_component,
  59                        int *priority,
  60                        mca_atomic_base_module_1_0_0_t ** module);
  61 
  62 /*
  63  * Stuff for the OBJ interface
  64  */
  65 static OBJ_CLASS_INSTANCE(avail_com_t, opal_list_item_t, NULL, NULL);
  66 
  67 /*
  68  * This function is called at the initialization.
  69  * It is used to select which atomic component will be
  70  * active for a given group.
  71  */
  72 int mca_atomic_base_select(void)
  73 {
  74     opal_list_t *selectable;
  75     opal_list_item_t *item;
  76 
  77     /* Announce */
  78     ATOMIC_VERBOSE(10,
  79                    "atomic:base:atomic_select: Checking all available modules");
  80     selectable = check_components(&oshmem_atomic_base_framework.framework_components);
  81 
  82     /* Upon return from the above, the modules list will contain the
  83      list of modules that returned (priority >= 0).  If we have no
  84      atomic modules available, then print error and return. */
  85     if (NULL == selectable) {
  86         /* There's no modules available */
  87         return OSHMEM_ERROR;
  88     }
  89 
  90     /* do the selection loop */
  91     for (item = opal_list_remove_first(selectable); NULL != item; item =
  92             opal_list_remove_first(selectable)) {
  93         avail_com_t *avail = (avail_com_t *) item;
  94 
  95         /* Set module having the highest priority */
  96         memcpy(&mca_atomic, avail->ac_module, sizeof(mca_atomic));
  97 
  98         OBJ_RELEASE(avail->ac_module);
  99         OBJ_RELEASE(avail);
 100         /* check correctness */
 101         if (!(mca_atomic.atomic_fadd)  || !(mca_atomic.atomic_add) ||
 102             !(mca_atomic.atomic_fand)  || !(mca_atomic.atomic_and) ||
 103             !(mca_atomic.atomic_for)   || !(mca_atomic.atomic_or) ||
 104             !(mca_atomic.atomic_fxor)  || !(mca_atomic.atomic_xor) ||
 105             !(mca_atomic.atomic_cswap) || !(mca_atomic.atomic_swap)) {
 106             return OSHMEM_ERR_NOT_FOUND;
 107         }
 108     }
 109 
 110     /* Done with the list from the check_components() call so release it. */
 111     OBJ_RELEASE(selectable);
 112 
 113     return OSHMEM_SUCCESS;
 114 }
 115 
 116 static int avail_com_compare (opal_list_item_t **a,
 117                                opal_list_item_t **b)
 118 {
 119     avail_com_t *acom = (avail_com_t *) *a;
 120     avail_com_t *bcom = (avail_com_t *) *b;
 121 
 122     if (acom->ac_priority > bcom->ac_priority) {
 123         return 1;
 124     } else if (acom->ac_priority < bcom->ac_priority) {
 125         return -1;
 126     }
 127 
 128     return 0;
 129 }
 130 
 131 /*
 132  * For each module in the list, check and see if it wants to run, and
 133  * do the resulting priority comparison.  Make a list of modules to be
 134  * only those who returned that they want to run, and put them in
 135  * priority order.
 136  */
 137 static opal_list_t *check_components(opal_list_t *components)
 138 {
 139     int priority;
 140     const mca_base_component_t *component;
 141     mca_base_component_list_item_t *cli;
 142     mca_atomic_base_module_1_0_0_t *module;
 143     opal_list_t *selectable;
 144     avail_com_t *avail;
 145 
 146     /* Make a list of the components that query successfully */
 147     selectable = OBJ_NEW(opal_list_t);
 148 
 149     /* Scan through the list of components */
 150     OPAL_LIST_FOREACH(cli, &oshmem_atomic_base_framework.framework_components, mca_base_component_list_item_t) {
 151         component = cli->cli_component;
 152 
 153         priority = check_one_component(component, &module);
 154         if (priority >= 0) {
 155             /* We have a component that indicated that it wants to run
 156                by giving us a module */
 157             avail = OBJ_NEW(avail_com_t);
 158             avail->ac_priority = priority;
 159             avail->ac_module = module;
 160 
 161             opal_list_append(selectable, &avail->super);
 162         }
 163     }
 164 
 165     /* If we didn't find any available components, return an error */
 166     if (0 == opal_list_get_size(selectable)) {
 167         OBJ_RELEASE(selectable);
 168         return NULL;
 169     }
 170 
 171     /* Put this list in priority order */
 172     opal_list_sort(selectable, avail_com_compare);
 173 
 174     /* All done */
 175     return selectable;
 176 }
 177 
 178 /*
 179  * Check a single component
 180  */
 181 static int check_one_component(const mca_base_component_t *component,
 182                                mca_atomic_base_module_1_0_0_t **module)
 183 {
 184     int err;
 185     int priority = -1;
 186 
 187     err = query(component, &priority, module);
 188 
 189     if (OSHMEM_SUCCESS == err) {
 190         priority = (priority < 100) ? priority : 100;
 191         ATOMIC_VERBOSE(10,
 192                        "atomic:base:atomic_select: component available: %s, priority: %d",
 193                        component->mca_component_name, priority);
 194 
 195     } else {
 196         priority = -1;
 197         ATOMIC_VERBOSE(10,
 198                        "atomic:base:atomic_select: component not available: %s",
 199                        component->mca_component_name);
 200     }
 201 
 202     return priority;
 203 }
 204 
 205 /**************************************************************************
 206  * Query functions
 207  **************************************************************************/
 208 
 209 /*
 210  * Take any version of a atomic module, query it, and return the right
 211  * module struct
 212  */
 213 static int query(const mca_base_component_t *component,
 214                  int *priority,
 215                  mca_atomic_base_module_1_0_0_t **module)
 216 {
 217     *module = NULL;
 218     if (1 == component->mca_type_major_version
 219             && 0 == component->mca_type_minor_version
 220             && 0 == component->mca_type_release_version) {
 221         const mca_atomic_base_component_1_0_0_t *atomic100 =
 222                 (mca_atomic_base_component_1_0_0_t *) component;
 223 
 224         return query_1_0_0(atomic100, priority, module);
 225     }
 226 
 227     /* Unknown atomic API version -- return error */
 228 
 229     return OSHMEM_ERROR;
 230 }
 231 
 232 static int query_1_0_0(const mca_atomic_base_component_1_0_0_t *component,
 233                        int *priority,
 234                        mca_atomic_base_module_1_0_0_t **module)
 235 {
 236     mca_atomic_base_module_1_0_0_t *ret;
 237 
 238     /* There's currently no need for conversion */
 239 
 240     ret = component->atomic_query(priority);
 241     if (NULL != ret) {
 242         *module = ret;
 243         return OSHMEM_SUCCESS;
 244     }
 245 
 246     return OSHMEM_ERROR;
 247 }

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