1
1

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.
Этот коммит содержится в:
George Bosilca 2006-02-10 21:04:26 +00:00
родитель c9e83658dd
Коммит d56656580a
2 изменённых файлов: 52 добавлений и 44 удалений

Просмотреть файл

@ -69,6 +69,8 @@ static void expand_array(void);
void opal_class_initialize(opal_class_t *cls) void opal_class_initialize(opal_class_t *cls)
{ {
opal_class_t *c; opal_class_t *c;
opal_construct_t* cls_construct_array;
opal_destruct_t* cls_destruct_array;
int i; int i;
assert(cls); assert(cls);
@ -104,20 +106,38 @@ void opal_class_initialize(opal_class_t *cls)
*/ */
cls->cls_construct_array = cls->cls_construct_array =
(void (**)(opal_object_t*))malloc(cls->cls_depth * (void (**)(opal_object_t*))malloc((cls->cls_depth + 1)*
sizeof(opal_construct_t) * 2); sizeof(opal_construct_t) * 2 );
if (NULL == cls->cls_construct_array) { if (NULL == cls->cls_construct_array) {
perror("Out of memory"); perror("Out of memory");
exit(-1); exit(-1);
} }
cls->cls_destruct_array = cls->cls_construct_array + cls->cls_depth; 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; c = cls;
for (i = 0; i < cls->cls_depth; i++) { for (i = 0; i < cls->cls_depth; i++) {
cls->cls_construct_array[i] = c->cls_construct; if( NULL != c->cls_construct ) {
cls->cls_destruct_array[i] = c->cls_destruct; *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; 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; cls->cls_initialized = 1;
save_class(cls); save_class(cls);

Просмотреть файл

@ -254,9 +254,7 @@ static inline opal_object_t *opal_obj_new_debug(size_t obj_size, opal_class_t* t
do { \ do { \
assert(NULL != object); \ assert(NULL != object); \
assert(NULL != ((opal_object_t *) (object))->obj_class); \ 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); \ assert(((opal_object_t *) (object))->obj_reference_count >= 0); \
} while (0) } while (0)
@ -310,17 +308,15 @@ do { \
OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \ OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
} while (0) } while (0)
#define OBJ_CONSTRUCT_INTERNAL(object, type) \ #define OBJ_CONSTRUCT_INTERNAL(object, type) \
do { \ do { \
if (0 == (type)->cls_initialized) { \ if (0 == (type)->cls_initialized) { \
opal_class_initialize((type)); \ opal_class_initialize((type)); \
} \ } \
if (NULL != object) { \ ((opal_object_t *) (object))->obj_class = (type); \
((opal_object_t *) (object))->obj_class = (type); \ ((opal_object_t *) (object))->obj_reference_count = 1; \
((opal_object_t *) (object))->obj_reference_count = 1; \ opal_obj_run_constructors((opal_object_t *) (object)); \
opal_obj_run_constructors((opal_object_t *) (object)); \ } while (0)
} \
} while (0)
/** /**
@ -328,13 +324,11 @@ do { \
* *
* @param object Pointer to the object * @param object Pointer to the object
*/ */
#define OBJ_DESTRUCT(object) \ #define OBJ_DESTRUCT(object) \
do { \ do { \
if (NULL != object) { \ opal_obj_run_destructors((opal_object_t *) (object)); \
opal_obj_run_destructors((opal_object_t *) (object)); \ OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \ } while (0)
} \
} while (0)
BEGIN_C_DECLS BEGIN_C_DECLS
OMPI_DECLSPEC OBJ_CLASS_DECLARATION(opal_object_t); 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) static inline void opal_obj_run_constructors(opal_object_t * object)
{ {
opal_class_t *cls; opal_construct_t* cls_construct;
int i;
assert(NULL != object);
assert(NULL != object->obj_class); assert(NULL != object->obj_class);
cls = object->obj_class; cls_construct = object->obj_class->cls_construct_array;
for (i = cls->cls_depth - 1; i >= 0; i--) { while( NULL != *cls_construct ) {
if (cls->cls_construct_array[i]) { (*cls_construct)(object);
(cls->cls_construct_array[i]) (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) static inline void opal_obj_run_destructors(opal_object_t * object)
{ {
opal_class_t *cls; opal_destruct_t* cls_destruct;
int i;
assert(NULL != object);
assert(NULL != object->obj_class); assert(NULL != object->obj_class);
cls = object->obj_class; cls_destruct = object->obj_class->cls_destruct_array;
for (i = 0; i < cls->cls_depth; i++) { while( NULL != *cls_destruct ) {
if (cls->cls_destruct_array[i]) { (*cls_destruct)(object);
(cls->cls_destruct_array[i]) (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) static inline int opal_obj_update(opal_object_t *object, int inc)
{ {
#if OMPI_HAVE_THREAD_SUPPORT #if OMPI_HAVE_THREAD_SUPPORT
opal_atomic_add(&(object->obj_reference_count), inc ); return opal_atomic_add(&(object->obj_reference_count), inc );
#else #else
object->obj_reference_count += inc; object->obj_reference_count += inc;
#endif
return object->obj_reference_count; return object->obj_reference_count;
#endif
} }