From d56656580a01599b81cc11bfd8152341fd6de9fb Mon Sep 17 00:00:00 2001 From: George Bosilca Date: Fri, 10 Feb 2006 21:04:26 +0000 Subject: [PATCH] Profiling shows that we spend way to much time (it's relative of course but it's still more than I want to) on the constructor and destructor loops. Compress the constructors and destructors array to remove all the useless tests against NULL. Now we use the cache a little bit more efficient. Correct a threading problem in the obj_update function. In the threaded case we have to return the value returned by the ompi_atomic_add function otherwise there are ways leading to the release of an object twice. This commit was SVN r8966. --- opal/class/opal_object.c | 30 +++++++++++++++--- opal/class/opal_object.h | 66 ++++++++++++++++------------------------ 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/opal/class/opal_object.c b/opal/class/opal_object.c index e77af4c3e9..1e1e3f156b 100644 --- a/opal/class/opal_object.c +++ b/opal/class/opal_object.c @@ -69,6 +69,8 @@ static void expand_array(void); void opal_class_initialize(opal_class_t *cls) { opal_class_t *c; + opal_construct_t* cls_construct_array; + opal_destruct_t* cls_destruct_array; int i; assert(cls); @@ -98,26 +100,44 @@ void opal_class_initialize(opal_class_t *cls) for (c = cls; c; c = c->cls_parent) { cls->cls_depth += 1; } - + /* * Allocate arrays for hierarchy of constructors and destructors */ cls->cls_construct_array = - (void (**)(opal_object_t*))malloc(cls->cls_depth * - sizeof(opal_construct_t) * 2); + (void (**)(opal_object_t*))malloc((cls->cls_depth + 1)* + sizeof(opal_construct_t) * 2 ); if (NULL == cls->cls_construct_array) { perror("Out of memory"); exit(-1); } cls->cls_destruct_array = cls->cls_construct_array + cls->cls_depth; + cls_construct_array = cls->cls_construct_array; + cls_destruct_array = cls->cls_destruct_array; c = cls; for (i = 0; i < cls->cls_depth; i++) { - cls->cls_construct_array[i] = c->cls_construct; - cls->cls_destruct_array[i] = c->cls_destruct; + if( NULL != c->cls_construct ) { + *cls_construct_array = c->cls_construct; + cls_construct_array++; + } + if( NULL != c->cls_destruct ) { + *cls_destruct_array = c->cls_destruct; + cls_destruct_array++; + } c = c->cls_parent; } + *cls_construct_array = NULL; /* end marker for the constructors */ + *cls_destruct_array = NULL; /* end marker for the destructors */ + /* Now we have to invert the constructors */ + for( i = 0, --cls_construct_array; + cls_construct_array > (cls->cls_construct_array + i); + i++, cls_construct_array-- ) { + opal_construct_t temp_construct = *cls_construct_array; + *cls_construct_array = cls->cls_construct_array[i]; + cls->cls_construct_array[i] = temp_construct; + } cls->cls_initialized = 1; save_class(cls); diff --git a/opal/class/opal_object.h b/opal/class/opal_object.h index 766bec3ae4..9b713b8369 100644 --- a/opal/class/opal_object.h +++ b/opal/class/opal_object.h @@ -254,9 +254,7 @@ static inline opal_object_t *opal_obj_new_debug(size_t obj_size, opal_class_t* t do { \ assert(NULL != object); \ assert(NULL != ((opal_object_t *) (object))->obj_class); \ - if (NULL != object) { \ - opal_obj_update((opal_object_t *) (object), 1); \ - } \ + opal_obj_update((opal_object_t *) (object), 1); \ assert(((opal_object_t *) (object))->obj_reference_count >= 0); \ } while (0) @@ -310,17 +308,15 @@ do { \ OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \ } while (0) -#define OBJ_CONSTRUCT_INTERNAL(object, type) \ - do { \ - if (0 == (type)->cls_initialized) { \ - opal_class_initialize((type)); \ - } \ - if (NULL != object) { \ - ((opal_object_t *) (object))->obj_class = (type); \ - ((opal_object_t *) (object))->obj_reference_count = 1; \ - opal_obj_run_constructors((opal_object_t *) (object)); \ - } \ - } while (0) +#define OBJ_CONSTRUCT_INTERNAL(object, type) \ +do { \ + if (0 == (type)->cls_initialized) { \ + opal_class_initialize((type)); \ + } \ + ((opal_object_t *) (object))->obj_class = (type); \ + ((opal_object_t *) (object))->obj_reference_count = 1; \ + opal_obj_run_constructors((opal_object_t *) (object)); \ +} while (0) /** @@ -328,13 +324,11 @@ do { \ * * @param object Pointer to the object */ -#define OBJ_DESTRUCT(object) \ - do { \ - if (NULL != object) { \ - opal_obj_run_destructors((opal_object_t *) (object)); \ - OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \ - } \ - } while (0) +#define OBJ_DESTRUCT(object) \ +do { \ + opal_obj_run_destructors((opal_object_t *) (object)); \ + OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \ +} while (0) BEGIN_C_DECLS OMPI_DECLSPEC OBJ_CLASS_DECLARATION(opal_object_t); @@ -378,17 +372,14 @@ END_C_DECLS */ static inline void opal_obj_run_constructors(opal_object_t * object) { - opal_class_t *cls; - int i; + opal_construct_t* cls_construct; - assert(NULL != object); assert(NULL != object->obj_class); - cls = object->obj_class; - for (i = cls->cls_depth - 1; i >= 0; i--) { - if (cls->cls_construct_array[i]) { - (cls->cls_construct_array[i]) (object); - } + cls_construct = object->obj_class->cls_construct_array; + while( NULL != *cls_construct ) { + (*cls_construct)(object); + cls_construct++; } } @@ -403,17 +394,14 @@ static inline void opal_obj_run_constructors(opal_object_t * object) */ static inline void opal_obj_run_destructors(opal_object_t * object) { - opal_class_t *cls; - int i; + opal_destruct_t* cls_destruct; - assert(NULL != object); assert(NULL != object->obj_class); - cls = object->obj_class; - for (i = 0; i < cls->cls_depth; i++) { - if (cls->cls_destruct_array[i]) { - (cls->cls_destruct_array[i]) (object); - } + cls_destruct = object->obj_class->cls_destruct_array; + while( NULL != *cls_destruct ) { + (*cls_destruct)(object); + cls_destruct++; } } @@ -460,11 +448,11 @@ static inline opal_object_t *opal_obj_new(size_t size, opal_class_t * cls) static inline int opal_obj_update(opal_object_t *object, int inc) { #if OMPI_HAVE_THREAD_SUPPORT - opal_atomic_add(&(object->obj_reference_count), inc ); + return opal_atomic_add(&(object->obj_reference_count), inc ); #else object->obj_reference_count += inc; -#endif return object->obj_reference_count; +#endif }