diff --git a/parsec/class/parsec_object.c b/parsec/class/parsec_object.c index 14f3956b5..77c0b6aaa 100644 --- a/parsec/class/parsec_object.c +++ b/parsec/class/parsec_object.c @@ -9,6 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. + * Copyright (c) 2025 Stony Brook University. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -29,6 +30,8 @@ #include "parsec/sys/atomic.h" #include "parsec/class/parsec_object.h" +static void parsec_obj_default_class_release(parsec_object_t* obj); + /* * Instantiation of class descriptor for the base class. This is * special, since be mark it as already initialized, with no parent @@ -39,6 +42,7 @@ parsec_class_t parsec_object_t_class = { NULL, /* parent class */ NULL, /* constructor */ NULL, /* destructor */ + &parsec_obj_default_class_release, /* release */ 1, /* initialized -- this class is preinitialized */ 0, /* class hierarchy depth */ NULL, /* array of constructors */ @@ -144,6 +148,7 @@ void parsec_class_initialize(parsec_class_t *cls) cls_construct_array = cls->cls_construct_array + cls_construct_array_count; cls_destruct_array = cls->cls_destruct_array; + parsec_release_t release = NULL; c = cls; *cls_construct_array = NULL; /* end marker for the constructors */ for (i = 0; i < cls->cls_depth; i++) { @@ -155,10 +160,13 @@ void parsec_class_initialize(parsec_class_t *cls) *cls_destruct_array = c->cls_destruct; cls_destruct_array++; } + if (NULL != c->cls_release && NULL == release) { + release = c->cls_release; + } c = c->cls_parent; } *cls_destruct_array = NULL; /* end marker for the destructors */ - + cls->cls_release = release; cls->cls_initialized = 1; save_class(cls); @@ -188,6 +196,9 @@ void parsec_class_finalize(void) } } +static void parsec_obj_default_class_release(parsec_object_t* obj){ + free(obj); +} static void save_class(parsec_class_t *cls) { diff --git a/parsec/class/parsec_object.h b/parsec/class/parsec_object.h index b94151ab7..ae92768b7 100644 --- a/parsec/class/parsec_object.h +++ b/parsec/class/parsec_object.h @@ -10,6 +10,7 @@ * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2025 Stony Brook University. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -137,6 +138,7 @@ typedef struct parsec_object_t parsec_object_t; typedef struct parsec_class_t parsec_class_t; typedef void (*parsec_construct_t) (parsec_object_t *); typedef void (*parsec_destruct_t) (parsec_object_t *); +typedef void (*parsec_release_t) (parsec_object_t *); /* types **************************************************************/ @@ -152,6 +154,7 @@ struct parsec_class_t { parsec_class_t *cls_parent; /**< parent class descriptor */ parsec_construct_t cls_construct; /**< class constructor */ parsec_destruct_t cls_destruct; /**< class destructor */ + parsec_release_t cls_release; /**< class release */ int cls_initialized; /**< is class initialized */ int cls_depth; /**< depth of class hierarchy tree */ parsec_construct_t *cls_construct_array; @@ -204,25 +207,39 @@ struct parsec_object_t { /** - * Static initializer for a class descriptor + * Extended initializer for a class descriptor * * @param NAME Name of class * @param PARENT Name of parent class * @param CONSTRUCTOR Pointer to constructor * @param DESTRUCTOR Pointer to destructor + * @param RELEASE Pointer to a function to release an object * * Put this in NAME.c */ -#define PARSEC_OBJ_CLASS_INSTANCE(NAME, PARENT, CONSTRUCTOR, DESTRUCTOR) \ +#define PARSEC_OBJ_RELEASE_CLASS_INSTANCE(NAME, PARENT, CONSTRUCTOR, DESTRUCTOR, RELEASE) \ parsec_class_t NAME ## _class = { \ # NAME, \ PARSEC_OBJ_CLASS(PARENT), \ (parsec_construct_t) CONSTRUCTOR, \ (parsec_destruct_t) DESTRUCTOR, \ + (parsec_release_t) RELEASE, \ 0, 0, NULL, NULL, \ sizeof(NAME) \ } +/** + * Static initializer for a class descriptor + * + * @param NAME Name of class + * @param PARENT Name of parent class + * @param CONSTRUCTOR Pointer to constructor + * @param DESTRUCTOR Pointer to destructor + * + * Put this in NAME.c + */ +#define PARSEC_OBJ_CLASS_INSTANCE(NAME, PARENT, CONSTRUCTOR, DESTRUCTOR) \ + PARSEC_OBJ_RELEASE_CLASS_INSTANCE(NAME, PARENT, CONSTRUCTOR, DESTRUCTOR, NULL) /** * Declaration for class descriptor @@ -314,7 +331,7 @@ static inline parsec_object_t *parsec_obj_new_debug(parsec_class_t* type, const parsec_obj_run_destructors((parsec_object_t *) (object)); \ PARSEC_OBJ_SET_MAGIC_ID((object), 0); \ PARSEC_OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \ - free(object); \ + ((parsec_object_t *)(object))->obj_class->cls_release((parsec_object_t *) (object)); \ object = NULL; \ } \ } while (0) @@ -323,7 +340,7 @@ static inline parsec_object_t *parsec_obj_new_debug(parsec_class_t* type, const do { \ if (0 == parsec_obj_update((parsec_object_t *) (object), -1)) { \ parsec_obj_run_destructors((parsec_object_t *) (object)); \ - free(object); \ + ((parsec_object_t *)(object))->obj_class->cls_release((parsec_object_t *) (object)); \ object = NULL; \ } \ } while (0)