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.
Этот коммит содержится в:
родитель
c9e83658dd
Коммит
d56656580a
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user