#include "src/include/pmix_config.h"
#include <pthread.h>
#include <stdio.h>
#include "src/class/pmix_object.h"
PMIX_EXPORT pmix_class_t pmix_object_t_class = {
"pmix_object_t",
NULL,
NULL,
NULL,
1,
0,
NULL,
NULL,
sizeof(pmix_object_t)
};
int pmix_class_init_epoch = 1;
static pthread_mutex_t class_mutex = PTHREAD_MUTEX_INITIALIZER;
static void **classes = NULL;
static int num_classes = 0;
static int max_classes = 0;
static const int increment = 10;
static void save_class(pmix_class_t *cls);
static void expand_array(void);
void pmix_class_initialize(pmix_class_t *cls)
{
pmix_class_t *c;
pmix_construct_t *cls_construct_array;
pmix_destruct_t *cls_destruct_array;
int cls_construct_array_count;
int cls_destruct_array_count;
int i;
assert(cls);
if (pmix_class_init_epoch == cls->cls_initialized) {
return;
}
pthread_mutex_lock(&class_mutex);
if (pmix_class_init_epoch == cls->cls_initialized) {
pthread_mutex_unlock(&class_mutex);
return;
}
cls->cls_depth = 0;
cls_construct_array_count = 0;
cls_destruct_array_count = 0;
for (c = cls; c; c = c->cls_parent) {
if (NULL != c->cls_construct) {
cls_construct_array_count++;
}
if (NULL != c->cls_destruct) {
cls_destruct_array_count++;
}
cls->cls_depth++;
}
cls->cls_construct_array = (void (**)(pmix_object_t *)) malloc(
(cls_construct_array_count + cls_destruct_array_count + 2) * sizeof(pmix_construct_t));
if (NULL == cls->cls_construct_array) {
perror("Out of memory");
exit(-1);
}
cls->cls_destruct_array = cls->cls_construct_array + cls_construct_array_count + 1;
cls_construct_array = cls->cls_construct_array + cls_construct_array_count;
cls_destruct_array = cls->cls_destruct_array;
c = cls;
*cls_construct_array = NULL;
for (i = 0; i < cls->cls_depth; i++) {
if (NULL != c->cls_construct) {
--cls_construct_array;
*cls_construct_array = c->cls_construct;
}
if (NULL != c->cls_destruct) {
*cls_destruct_array = c->cls_destruct;
cls_destruct_array++;
}
c = c->cls_parent;
}
*cls_destruct_array = NULL;
cls->cls_initialized = pmix_class_init_epoch;
save_class(cls);
pthread_mutex_unlock(&class_mutex);
}
int pmix_class_finalize(void)
{
int i;
if (INT_MAX == pmix_class_init_epoch) {
pmix_class_init_epoch = 1;
} else {
pmix_class_init_epoch++;
}
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;
}
return 0;
}
static void save_class(pmix_class_t *cls)
{
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;
if (NULL == classes) {
classes = (void **) calloc(max_classes, sizeof(void *));
} else {
classes = (void **) realloc(classes, sizeof(void *) * max_classes);
}
if (NULL == classes) {
perror("class malloc failed");
exit(-1);
}
for (i = num_classes; i < max_classes; ++i) {
classes[i] = NULL;
}
}