root/opal/class/opal_object.c

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

DEFINITIONS

This source file includes following definitions.
  1. opal_class_initialize
  2. opal_class_finalize
  3. save_class
  4. expand_array

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2015      Los Alamos National Security, LLC. All rights
  14  *                         reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 /**
  23  * @file
  24  *
  25  * Implementation of opal_object_t, the base opal foundation class
  26  */
  27 
  28 #include "opal_config.h"
  29 
  30 #include <stdio.h>
  31 
  32 #include "opal/sys/atomic.h"
  33 #include "opal/class/opal_object.h"
  34 #include "opal/constants.h"
  35 
  36 /*
  37  * Instantiation of class descriptor for the base class.  This is
  38  * special, since be mark it as already initialized, with no parent
  39  * and no constructor or destructor.
  40  */
  41 opal_class_t opal_object_t_class = {
  42     "opal_object_t",      /* name */
  43     NULL,                 /* parent class */
  44     NULL,                 /* constructor */
  45     NULL,                 /* destructor */
  46     1,                    /* initialized  -- this class is preinitialized */
  47     0,                    /* class hierarchy depth */
  48     NULL,                 /* array of constructors */
  49     NULL,                 /* array of destructors */
  50     sizeof(opal_object_t) /* size of the opal object */
  51 };
  52 
  53 int opal_class_init_epoch = 1;
  54 
  55 /*
  56  * Local variables
  57  */
  58 static opal_atomic_lock_t class_lock = OPAL_ATOMIC_LOCK_INIT;
  59 static void** classes = NULL;
  60 static int num_classes = 0;
  61 static int max_classes = 0;
  62 static const int increment = 10;
  63 
  64 
  65 /*
  66  * Local functions
  67  */
  68 static void save_class(opal_class_t *cls);
  69 static void expand_array(void);
  70 
  71 
  72 /*
  73  * Lazy initialization of class descriptor.
  74  */
  75 void opal_class_initialize(opal_class_t *cls)
  76 {
  77     opal_class_t *c;
  78     opal_construct_t* cls_construct_array;
  79     opal_destruct_t* cls_destruct_array;
  80     int cls_construct_array_count;
  81     int cls_destruct_array_count;
  82     int i;
  83 
  84     assert(cls);
  85 
  86     /* Check to see if any other thread got in here and initialized
  87        this class before we got a chance to */
  88 
  89     if (opal_class_init_epoch == cls->cls_initialized) {
  90         return;
  91     }
  92     opal_atomic_lock(&class_lock);
  93 
  94     /* If another thread initializing this same class came in at
  95        roughly the same time, it may have gotten the lock and
  96        initialized.  So check again. */
  97 
  98     if (opal_class_init_epoch == cls->cls_initialized) {
  99         opal_atomic_unlock(&class_lock);
 100         return;
 101     }
 102 
 103     /*
 104      * First calculate depth of class hierarchy
 105      * And the number of constructors and destructors
 106      */
 107 
 108     cls->cls_depth = 0;
 109     cls_construct_array_count = 0;
 110     cls_destruct_array_count  = 0;
 111     for (c = cls; c; c = c->cls_parent) {
 112         if( NULL != c->cls_construct ) {
 113             cls_construct_array_count++;
 114         }
 115         if( NULL != c->cls_destruct ) {
 116             cls_destruct_array_count++;
 117         }
 118         cls->cls_depth++;
 119     }
 120 
 121     /*
 122      * Allocate arrays for hierarchy of constructors and destructors
 123      * plus for each a NULL-sentinel
 124      */
 125 
 126     cls->cls_construct_array =
 127         (void (**)(opal_object_t*))malloc((cls_construct_array_count +
 128                                            cls_destruct_array_count + 2) *
 129                                           sizeof(opal_construct_t) );
 130     if (NULL == cls->cls_construct_array) {
 131         perror("Out of memory");
 132         exit(-1);
 133     }
 134     cls->cls_destruct_array =
 135         cls->cls_construct_array + cls_construct_array_count + 1;
 136 
 137     /*
 138      * The constructor array is reversed, so start at the end
 139      */
 140 
 141     cls_construct_array = cls->cls_construct_array + cls_construct_array_count;
 142     cls_destruct_array  = cls->cls_destruct_array;
 143 
 144     c = cls;
 145     *cls_construct_array = NULL;  /* end marker for the constructors */
 146     for (i = 0; i < cls->cls_depth; i++) {
 147         if( NULL != c->cls_construct ) {
 148             --cls_construct_array;
 149             *cls_construct_array = c->cls_construct;
 150         }
 151         if( NULL != c->cls_destruct ) {
 152             *cls_destruct_array = c->cls_destruct;
 153             cls_destruct_array++;
 154         }
 155         c = c->cls_parent;
 156     }
 157     *cls_destruct_array = NULL;  /* end marker for the destructors */
 158 
 159     cls->cls_initialized = opal_class_init_epoch;
 160     save_class(cls);
 161 
 162     /* All done */
 163 
 164     opal_atomic_unlock(&class_lock);
 165 }
 166 
 167 
 168 /*
 169  * Note that this is finalize for *all* classes.
 170  */
 171 int opal_class_finalize(void)
 172 {
 173     int i;
 174 
 175     if (INT_MAX == opal_class_init_epoch) {
 176         opal_class_init_epoch = 1;
 177     } else {
 178         opal_class_init_epoch++;
 179     }
 180 
 181     if (NULL != classes) {
 182         for (i = 0; i < num_classes; ++i) {
 183             if (NULL != classes[i]) {
 184                 free(classes[i]);
 185             }
 186         }
 187         free(classes);
 188         classes = NULL;
 189         num_classes = 0;
 190         max_classes = 0;
 191     }
 192 
 193     return OPAL_SUCCESS;
 194 }
 195 
 196 
 197 static void save_class(opal_class_t *cls)
 198 {
 199     if (num_classes >= max_classes) {
 200         expand_array();
 201     }
 202 
 203     classes[num_classes] = cls->cls_construct_array;
 204     ++num_classes;
 205 }
 206 
 207 
 208 static void expand_array(void)
 209 {
 210     int i;
 211 
 212     max_classes += increment;
 213     classes = (void**)realloc(classes, sizeof(opal_class_t*) * max_classes);
 214     if (NULL == classes) {
 215         perror("class malloc failed");
 216         exit(-1);
 217     }
 218     for (i = num_classes; i < max_classes; ++i) {
 219         classes[i] = NULL;
 220     }
 221 }
 222 

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