2003-12-22 19:29:21 +03:00
|
|
|
/*
|
2005-11-05 22:57:48 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
|
|
|
* University Research and Technology
|
|
|
|
* Corporation. All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2007-01-21 17:24:29 +03:00
|
|
|
* Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
|
2004-11-28 23:09:25 +03:00
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
2004-01-07 10:57:00 +03:00
|
|
|
* $HEADER$
|
2003-12-22 19:29:21 +03:00
|
|
|
*/
|
2004-01-07 10:57:00 +03:00
|
|
|
|
2004-02-10 17:04:27 +03:00
|
|
|
/**
|
2004-02-13 00:30:06 +03:00
|
|
|
* @file
|
|
|
|
*
|
2005-07-04 04:16:24 +04:00
|
|
|
* Implementation of opal_object_t, the base opal foundation class
|
2004-02-10 17:04:27 +03:00
|
|
|
*/
|
2003-12-22 19:29:21 +03:00
|
|
|
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "opal_config.h"
|
2004-08-19 03:24:27 +04:00
|
|
|
|
2004-02-13 00:30:06 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "opal/sys/atomic.h"
|
2005-07-03 20:06:07 +04:00
|
|
|
#include "opal/class/opal_object.h"
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "opal/constants.h"
|
2003-12-22 19:29:21 +03:00
|
|
|
|
2004-02-13 00:30:06 +03:00
|
|
|
/*
|
|
|
|
* Instantiation of class descriptor for the base class. This is
|
|
|
|
* special, since be mark it as already initialized, with no parent
|
2006-08-26 03:22:35 +04:00
|
|
|
* and no constructor or destructor.
|
2004-02-13 00:30:06 +03:00
|
|
|
*/
|
2005-07-03 20:06:07 +04:00
|
|
|
opal_class_t opal_object_t_class = {
|
2007-01-21 17:24:29 +03:00
|
|
|
"opal_object_t", /* name */
|
|
|
|
NULL, /* parent class */
|
|
|
|
NULL, /* constructor */
|
|
|
|
NULL, /* destructor */
|
|
|
|
1, /* initialized -- this class is preinitialized */
|
|
|
|
0, /* class hierarchy depth */
|
|
|
|
NULL, /* array of constructors */
|
|
|
|
NULL, /* array of destructors */
|
|
|
|
sizeof(opal_object_t) /* size of the opal object */
|
2004-02-13 00:30:06 +03:00
|
|
|
};
|
2003-12-22 19:29:21 +03:00
|
|
|
|
2005-03-25 01:13:05 +03:00
|
|
|
/*
|
|
|
|
* Local variables
|
|
|
|
*/
|
2005-07-04 01:38:51 +04:00
|
|
|
static opal_atomic_lock_t class_lock = { { OPAL_ATOMIC_UNLOCKED } };
|
2005-03-25 01:13:05 +03:00
|
|
|
static void** classes = NULL;
|
|
|
|
static int num_classes = 0;
|
|
|
|
static int max_classes = 0;
|
|
|
|
static const int increment = 10;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local functions
|
|
|
|
*/
|
2005-07-03 20:06:07 +04:00
|
|
|
static void save_class(opal_class_t *cls);
|
2005-03-25 01:13:05 +03:00
|
|
|
static void expand_array(void);
|
|
|
|
|
2004-02-10 17:04:27 +03:00
|
|
|
|
2004-02-13 00:30:06 +03:00
|
|
|
/*
|
|
|
|
* Lazy initialization of class descriptor.
|
|
|
|
*/
|
2005-07-03 20:06:07 +04:00
|
|
|
void opal_class_initialize(opal_class_t *cls)
|
2003-12-22 19:29:21 +03:00
|
|
|
{
|
2005-07-03 20:06:07 +04:00
|
|
|
opal_class_t *c;
|
2006-02-11 00:04:26 +03:00
|
|
|
opal_construct_t* cls_construct_array;
|
2007-03-06 19:38:06 +03:00
|
|
|
opal_destruct_t* cls_destruct_array;
|
|
|
|
int cls_construct_array_count;
|
|
|
|
int cls_destruct_array_count;
|
2004-02-13 00:30:06 +03:00
|
|
|
int i;
|
2003-12-22 19:29:21 +03:00
|
|
|
|
2004-10-18 20:55:20 +04:00
|
|
|
assert(cls);
|
2005-03-25 01:13:05 +03:00
|
|
|
|
|
|
|
/* Check to see if any other thread got in here and initialized
|
|
|
|
this class before we got a chance to */
|
|
|
|
|
|
|
|
if (1 == cls->cls_initialized) {
|
|
|
|
return;
|
|
|
|
}
|
2005-07-04 01:38:51 +04:00
|
|
|
opal_atomic_lock(&class_lock);
|
2005-03-25 01:13:05 +03:00
|
|
|
|
|
|
|
/* If another thread initializing this same class came in at
|
|
|
|
roughly the same time, it may have gotten the lock and
|
|
|
|
initialized. So check again. */
|
|
|
|
|
|
|
|
if (1 == cls->cls_initialized) {
|
2005-07-04 01:38:51 +04:00
|
|
|
opal_atomic_unlock(&class_lock);
|
2005-03-25 01:13:05 +03:00
|
|
|
return;
|
|
|
|
}
|
2004-02-10 17:04:27 +03:00
|
|
|
|
2004-02-13 00:30:06 +03:00
|
|
|
/*
|
|
|
|
* First calculate depth of class hierarchy
|
2007-03-06 19:38:06 +03:00
|
|
|
* And the number of constructors and destructors
|
2004-02-13 00:30:06 +03:00
|
|
|
*/
|
|
|
|
|
2004-10-18 20:55:20 +04:00
|
|
|
cls->cls_depth = 0;
|
2007-03-06 19:38:06 +03:00
|
|
|
cls_construct_array_count = 0;
|
|
|
|
cls_destruct_array_count = 0;
|
2004-10-18 20:55:20 +04:00
|
|
|
for (c = cls; c; c = c->cls_parent) {
|
2007-03-06 19:38:06 +03:00
|
|
|
if( NULL != c->cls_construct ) {
|
|
|
|
cls_construct_array_count++;
|
|
|
|
}
|
|
|
|
if( NULL != c->cls_destruct ) {
|
|
|
|
cls_destruct_array_count++;
|
|
|
|
}
|
|
|
|
cls->cls_depth++;
|
2004-02-13 00:30:06 +03:00
|
|
|
}
|
2006-02-11 00:04:26 +03:00
|
|
|
|
2004-02-13 00:30:06 +03:00
|
|
|
/*
|
|
|
|
* Allocate arrays for hierarchy of constructors and destructors
|
2007-03-06 19:38:06 +03:00
|
|
|
* plus for each a NULL-sentinel
|
2004-02-13 00:30:06 +03:00
|
|
|
*/
|
2004-02-10 17:04:27 +03:00
|
|
|
|
2005-03-25 01:13:05 +03:00
|
|
|
cls->cls_construct_array =
|
2007-03-06 19:38:06 +03:00
|
|
|
(void (**)(opal_object_t*))malloc((cls_construct_array_count +
|
|
|
|
cls_destruct_array_count + 2) *
|
|
|
|
sizeof(opal_construct_t) );
|
2004-10-18 20:55:20 +04:00
|
|
|
if (NULL == cls->cls_construct_array) {
|
2004-02-13 00:30:06 +03:00
|
|
|
perror("Out of memory");
|
2005-03-25 01:13:05 +03:00
|
|
|
exit(-1);
|
2004-02-13 00:30:06 +03:00
|
|
|
}
|
2007-03-06 19:38:06 +03:00
|
|
|
cls->cls_destruct_array =
|
|
|
|
cls->cls_construct_array + cls_construct_array_count + 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The constructor array is reversed, so start at the end
|
|
|
|
*/
|
|
|
|
|
|
|
|
cls_construct_array = cls->cls_construct_array + cls_construct_array_count;
|
|
|
|
cls_destruct_array = cls->cls_destruct_array;
|
|
|
|
|
2004-10-18 20:55:20 +04:00
|
|
|
c = cls;
|
2007-03-06 19:38:06 +03:00
|
|
|
*cls_construct_array = NULL; /* end marker for the constructors */
|
2004-10-18 20:55:20 +04:00
|
|
|
for (i = 0; i < cls->cls_depth; i++) {
|
2006-02-11 00:04:26 +03:00
|
|
|
if( NULL != c->cls_construct ) {
|
2007-03-06 19:38:06 +03:00
|
|
|
--cls_construct_array;
|
2006-02-11 00:04:26 +03:00
|
|
|
*cls_construct_array = c->cls_construct;
|
|
|
|
}
|
|
|
|
if( NULL != c->cls_destruct ) {
|
|
|
|
*cls_destruct_array = c->cls_destruct;
|
|
|
|
cls_destruct_array++;
|
|
|
|
}
|
2004-02-13 00:30:06 +03:00
|
|
|
c = c->cls_parent;
|
2006-02-11 00:04:26 +03:00
|
|
|
}
|
|
|
|
*cls_destruct_array = NULL; /* end marker for the destructors */
|
2004-02-10 17:04:27 +03:00
|
|
|
|
2004-10-18 20:55:20 +04:00
|
|
|
cls->cls_initialized = 1;
|
2005-03-25 01:13:05 +03:00
|
|
|
save_class(cls);
|
|
|
|
|
|
|
|
/* All done */
|
|
|
|
|
2005-07-04 01:38:51 +04:00
|
|
|
opal_atomic_unlock(&class_lock);
|
2004-02-13 00:30:06 +03:00
|
|
|
}
|
2005-03-25 01:13:05 +03:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note that this is finalize for *all* classes.
|
|
|
|
*/
|
2005-07-03 20:06:07 +04:00
|
|
|
int opal_class_finalize(void)
|
2005-03-25 01:13:05 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (NULL != classes) {
|
|
|
|
for (i = 0; i < num_classes; ++i) {
|
|
|
|
if (NULL != classes[i]) {
|
|
|
|
free(classes[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(classes);
|
|
|
|
classes = NULL;
|
|
|
|
num_classes = 0;
|
|
|
|
max_classes = 0;
|
|
|
|
}
|
|
|
|
|
2006-02-12 04:33:29 +03:00
|
|
|
return OPAL_SUCCESS;
|
2005-03-25 01:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-03 20:06:07 +04:00
|
|
|
static void save_class(opal_class_t *cls)
|
2005-03-25 01:13:05 +03:00
|
|
|
{
|
|
|
|
if (num_classes >= max_classes) {
|
|
|
|
expand_array();
|
|
|
|
}
|
|
|
|
|
|
|
|
classes[num_classes] = cls->cls_construct_array;
|
|
|
|
++num_classes;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void expand_array(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
max_classes += increment;
|
2006-08-23 00:07:42 +04:00
|
|
|
classes = (void**)realloc(classes, sizeof(void *) * max_classes);
|
2005-03-25 01:13:05 +03:00
|
|
|
if (NULL == classes) {
|
|
|
|
perror("class malloc failed");
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
for (i = num_classes; i < max_classes; ++i) {
|
|
|
|
classes[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|