OpenMPI  0.1.1
opal_object.h File Reference

A simple C-language object-oriented system with single inheritance and ownership-based memory management using a retain/release model. More...

#include "opal_config.h"
#include <assert.h>

Go to the source code of this file.

Data Structures

struct  opal_class_t
 Class descriptor. More...
 
struct  opal_object_t
 Base object. More...
 

Macros

#define OPAL_OBJ_STATIC_INIT(BASE_CLASS)   { OBJ_CLASS(BASE_CLASS), 1 }
 For static initializations of OBJects. More...
 
#define OBJ_CLASS(NAME)   (&(NAME ## _class))
 Return a pointer to the class descriptor associated with a class type. More...
 
#define OBJ_CLASS_INSTANCE(NAME, PARENT, CONSTRUCTOR, DESTRUCTOR)
 Static initializer for a class descriptor. More...
 
#define OBJ_CLASS_DECLARATION(NAME)   extern opal_class_t NAME ## _class
 Declaration for class descriptor. More...
 
#define OBJ_NEW(type)   ((type *) opal_obj_new(OBJ_CLASS(type)))
 
#define OBJ_RETAIN(object)   opal_obj_update((opal_object_t *) (object), 1);
 Retain an object (by incrementing its reference count) More...
 
#define OBJ_REMEMBER_FILE_AND_LINENO(OBJECT, FILE, LINENO)
 Helper macro for the debug mode to store the locations where the status of an object change.
 
#define OBJ_SET_MAGIC_ID(OBJECT, VALUE)
 
#define OBJ_RELEASE(object)
 Release an object (by decrementing its reference count). More...
 
#define OBJ_CONSTRUCT(object, type)
 Construct (initialize) objects that are not dynamically allocated. More...
 
#define OBJ_CONSTRUCT_INTERNAL(object, type)
 
#define OBJ_DESTRUCT(object)
 Destruct (finalize) an object that is not dynamically allocated. More...
 

Typedefs

typedef typedefBEGIN_C_DECLS
struct opal_object_t 
opal_object_t
 
typedef struct opal_class_t opal_class_t
 
typedef void(* opal_construct_t )(opal_object_t *)
 
typedef void(* opal_destruct_t )(opal_object_t *)
 

Functions

static opal_object_topal_obj_new (opal_class_t *cls)
 Create an object: dynamically allocate storage and run the class constructor. More...
 
OPAL_DECLSPEC OBJ_CLASS_DECLARATION (opal_object_t)
 
OPAL_DECLSPEC void opal_class_initialize (opal_class_t *)
 Lazy initialization of class descriptor. More...
 
OPAL_DECLSPEC int opal_class_finalize (void)
 Shut down the class system and release all memory. More...
 
static void opal_obj_run_constructors (opal_object_t *object)
 Run the hierarchy of class constructors for this object, in a parent-first order. More...
 
static void opal_obj_run_destructors (opal_object_t *object)
 Run the hierarchy of class destructors for this object, in a parent-last order. More...
 
static int opal_obj_update (opal_object_t *object, int inc) __opal_attribute_always_inline__
 Atomically update the object's reference count by some increment. More...
 

Detailed Description

A simple C-language object-oriented system with single inheritance and ownership-based memory management using a retain/release model.

A class consists of a struct and singly-instantiated class descriptor. The first element of the struct must be the parent class's struct. The class descriptor must be given a well-known name based upon the class struct name (if the struct is sally_t, the class descriptor should be sally_t_class) and must be statically initialized as discussed below.

(a) To define a class

In a interface (.h) file, define the class. The first element should always be the parent class, for example

struct sally_t
{
parent_t parent;
void *first_member;
...
};
typedef struct sally_t sally_t;

All classes must have a parent which is also class.

In an implementation (.c) file, instantiate a class descriptor for the class like this:

OBJ_CLASS_INSTANCE(sally_t, parent_t, sally_construct, sally_destruct);

This macro actually expands to

opal_class_t sally_t_class = {
"sally_t",
OBJ_CLASS(parent_t), // pointer to parent_t_class
sally_construct,
sally_destruct,
0, 0, NULL, NULL,
sizeof ("sally_t")
};

This variable should be declared in the interface (.h) file using the OBJ_CLASS_DECLARATION macro as shown above.

sally_construct, and sally_destruct are function pointers to the constructor and destructor for the class and are best defined as static functions in the implementation file. NULL pointers maybe supplied instead.

Other class methods may be added to the struct.

(b) Class instantiation: dynamic

To create a instance of a class (an object) use OBJ_NEW:

sally_t *sally = OBJ_NEW(sally_t);

which allocates memory of sizeof(sally_t) and runs the class's constructors.

Use OBJ_RETAIN, OBJ_RELEASE to do reference-count-based memory management:

OBJ_RETAIN(sally);
OBJ_RELEASE(sally);
OBJ_RELEASE(sally);

When the reference count reaches zero, the class's destructor, and those of its parents, are run and the memory is freed.

N.B. There is no explicit free/delete method for dynamic objects in this model.

(c) Class instantiation: static

For an object with static (or stack) allocation, it is only necessary to initialize the memory, which is done using OBJ_CONSTRUCT:

sally_t sally;
OBJ_CONSTRUCT(&sally, sally_t);

The retain/release model is not necessary here, but before the object goes out of scope, OBJ_DESTRUCT should be run to release initialized resources:

OBJ_DESTRUCT(&sally);

Macro Definition Documentation

#define OBJ_CLASS (   NAME)    (&(NAME ## _class))
#define OBJ_CLASS_DECLARATION (   NAME)    extern opal_class_t NAME ## _class

Declaration for class descriptor.

Parameters
NAMEName of class

Put this in NAME.h

#define OBJ_CLASS_INSTANCE (   NAME,
  PARENT,
  CONSTRUCTOR,
  DESTRUCTOR 
)
Value:
opal_class_t NAME ## _class = { \
# NAME, \
OBJ_CLASS(PARENT), \
(opal_construct_t) CONSTRUCTOR, \
(opal_destruct_t) DESTRUCTOR, \
0, 0, NULL, NULL, \
sizeof(NAME) \
}
Class descriptor.
Definition: opal_object.h:152

Static initializer for a class descriptor.

Parameters
NAMEName of class
PARENTName of parent class
CONSTRUCTORPointer to constructor
DESTRUCTORPointer to destructor

Put this in NAME.c

#define OBJ_CONSTRUCT (   object,
  type 
)
Value:
do { \
OBJ_CONSTRUCT_INTERNAL((object), OBJ_CLASS(type)); \
} while (0)
#define OBJ_CLASS(NAME)
Return a pointer to the class descriptor associated with a class type.
Definition: opal_object.h:205

Construct (initialize) objects that are not dynamically allocated.

Parameters
objectPointer to the object
typeThe object type

Referenced by mca_allocator_basic_component_init(), mca_allocator_bucket_init(), mca_base_param_init(), mca_btl_base_open(), mca_btl_elan_component_init(), mca_btl_gm_component_open(), mca_btl_mx_component_init(), mca_btl_self_component_open(), mca_btl_ud_add_procs(), mca_btl_ud_component_init(), mca_btl_udapl_component_open(), mca_btl_udapl_init(), mca_coll_base_find_available(), mca_coll_sm_bcast_intra(), mca_io_base_find_available(), mca_mpool_base_open(), mca_oob_base_open(), mca_pml_bfo_comm_init_size(), mca_pml_bfo_enable(), mca_pml_csum_comm_init_size(), mca_pml_csum_enable(), mca_pml_ob1_comm_init_size(), mca_pml_ob1_enable(), mca_rcache_base_open(), mca_rcache_rb_module_init(), mca_rcache_vma_module_init(), ompi_attr_init(), ompi_errcode_intern_init(), ompi_errhandler_init(), ompi_group_init(), ompi_modex_recv_key_value(), ompi_modex_send_key_value(), ompi_mpi_errcode_init(), ompi_mpi_init(), ompi_op_base_find_available(), ompi_osc_base_open(), ompi_osc_base_process_op(), ompi_proc_init(), ompi_rb_tree_construct(), ompi_request_init(), ompi_wait_for_debugger(), opal_cmd_line_create(), opal_cr_init(), opal_dss_open(), opal_hash_table_init(), opal_malloc_init(), opal_output_init(), orte_ess_base_open(), orte_ess_base_orted_setup(), orte_iof_base_open(), orte_notifier_base_open(), orte_odls_base_open(), orte_plm_base_open(), orte_plm_base_orted_exit(), orte_register_params(), orte_rmaps_base_open(), orte_rml_base_open(), orte_sensor_base_open(), orte_sensor_base_select(), orte_show_help_init(), orte_show_help_norender(), orte_show_help_suppress(), and orte_util_add_hostfile_nodes().

#define OBJ_CONSTRUCT_INTERNAL (   object,
  type 
)
Value:
do { \
OBJ_SET_MAGIC_ID((object), OPAL_OBJ_MAGIC_ID); \
if (0 == (type)->cls_initialized) { \
} \
((opal_object_t *) (object))->obj_class = (type); \
((opal_object_t *) (object))->obj_reference_count = 1; \
OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
} while (0)
OPAL_DECLSPEC void opal_class_initialize(opal_class_t *)
Lazy initialization of class descriptor.
Definition: opal_object.c:70
#define OBJ_REMEMBER_FILE_AND_LINENO(OBJECT, FILE, LINENO)
Helper macro for the debug mode to store the locations where the status of an object change...
Definition: opal_object.h:296
Base object.
Definition: opal_object.h:182
static void opal_obj_run_constructors(opal_object_t *object)
Run the hierarchy of class constructors for this object, in a parent-first order. ...
Definition: opal_object.h:418
#define OBJ_DESTRUCT (   object)
Value:
do { \
OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
} while (0)
static void opal_obj_run_destructors(opal_object_t *object)
Run the hierarchy of class destructors for this object, in a parent-last order.
Definition: opal_object.h:440
#define OBJ_REMEMBER_FILE_AND_LINENO(OBJECT, FILE, LINENO)
Helper macro for the debug mode to store the locations where the status of an object change...
Definition: opal_object.h:296
Base object.
Definition: opal_object.h:182

Destruct (finalize) an object that is not dynamically allocated.

Parameters
objectPointer to the object

Referenced by mca_allocator_basic_finalize(), mca_base_param_finalize(), mca_btl_elan_component_close(), mca_btl_gm_finalize(), mca_btl_mx_finalize(), mca_btl_self_component_close(), mca_btl_template_finalize(), mca_btl_ud_component_init(), mca_btl_ud_finalize(), mca_btl_udapl_finalize(), mca_coll_base_close(), mca_coll_base_find_available(), mca_io_base_close(), mca_io_base_find_available(), mca_mpool_gpusm_finalize(), mca_mpool_grdma_finalize(), mca_mpool_rdma_finalize(), mca_mpool_rgpusm_finalize(), ompi_errcode_intern_finalize(), ompi_errhandler_finalize(), ompi_group_finalize(), ompi_modex_recv_key_value(), ompi_modex_send_key_value(), ompi_mpi_errcode_finalize(), ompi_mpi_finalize(), ompi_op_base_close(), ompi_op_base_find_available(), ompi_op_finalize(), ompi_osc_base_process_op(), ompi_proc_finalize(), ompi_rb_tree_destruct(), ompi_request_finalize(), ompi_wait_for_debugger(), opal_cr_finalize(), opal_dss_close(), opal_malloc_finalize(), opal_output_finalize(), orte_ess_base_close(), orte_plm_base_orted_exit(), orte_register_params(), orte_rmaps_base_close(), orte_rml_base_close(), orte_sensor_base_select(), orte_show_help_finalize(), orte_show_help_norender(), orte_show_help_suppress(), and orte_util_add_hostfile_nodes().

#define OBJ_RELEASE (   object)
Value:
do { \
if (0 == opal_obj_update((opal_object_t *) (object), -1)) { \
free(object); \
object = NULL; \
} \
} while (0)
static void opal_obj_run_destructors(opal_object_t *object)
Run the hierarchy of class destructors for this object, in a parent-last order.
Definition: opal_object.h:440
static int opal_obj_update(opal_object_t *object, int inc) __opal_attribute_always_inline__
Atomically update the object's reference count by some increment.
Definition: opal_object.h:493
Base object.
Definition: opal_object.h:182

Release an object (by decrementing its reference count).

If the reference count reaches zero, destruct (finalize) the object and free its storage.

Note: If the object is freed, then the value of the pointer is set to NULL.

Parameters
objectPointer to the object

Referenced by mca_base_param_dump_release(), mca_base_param_finalize(), mca_btl_gm_add_procs(), mca_btl_mx_add_procs(), mca_btl_sctp_add_procs(), mca_btl_sctp_del_procs(), mca_btl_sctp_finalize(), mca_btl_tcp_add_procs(), mca_btl_tcp_del_procs(), mca_btl_tcp_finalize(), mca_btl_template_add_procs(), mca_btl_template_free(), mca_btl_ud_add_procs(), mca_btl_ud_del_procs(), mca_btl_udapl_add_procs(), mca_coll_base_comm_select(), mca_coll_base_find_available(), mca_io_base_delete(), mca_io_base_file_select(), mca_io_base_find_available(), mca_mpool_grdma_finalize(), mca_oob_tcp_fini(), mca_oob_tcp_set_addr(), ompi_attr_copy_all(), ompi_attr_delete(), ompi_attr_finalize(), ompi_attr_free_keyval(), ompi_errhandler_create(), ompi_group_allocate(), ompi_group_decrement_proc_count(), ompi_group_finalize(), ompi_group_free(), ompi_mpi_errcode_finalize(), ompi_mpi_finalize(), ompi_op_base_find_available(), ompi_op_base_op_select(), ompi_op_create_user(), ompi_op_finalize(), ompi_proc_complete_init(), ompi_proc_finalize(), ompi_proc_refresh(), ompi_proc_unpack(), ompi_request_persistent_proc_null_free(), opal_carto_base_duplicate_graph_fn(), opal_carto_base_free_graph_fn(), opal_cmd_line_parse(), opal_dss_close(), opal_graph_remove_vertex(), opal_graph_spf(), opal_hash_table_remove_all(), orte_dt_std_obj_release(), orte_ess_base_close(), orte_ras_base_node_insert(), orte_rmaps_base_close(), orte_rmaps_base_get_target_nodes(), orte_rml_base_select(), and orte_util_add_hostfile_nodes().

#define OPAL_OBJ_STATIC_INIT (   BASE_CLASS)    { OBJ_CLASS(BASE_CLASS), 1 }

For static initializations of OBJects.

Parameters
NAMEName of the class to initialize

Function Documentation

OPAL_DECLSPEC int opal_class_finalize ( void  )

Shut down the class system and release all memory.

This function should be invoked as the ABSOLUTE LAST function to use the class subsystem. It frees all associated memory with ALL classes, rendering all of them inoperable. It is here so that tools like valgrind and purify don't report still-reachable memory upon process termination.

Referenced by opal_finalize_util().

OPAL_DECLSPEC void opal_class_initialize ( opal_class_t )

Lazy initialization of class descriptor.

Specifically cache arrays of function pointers for the constructor and destructor hierarchies for this class.

Parameters
classPointer to class descriptor

References opal_class_t::cls_construct, opal_class_t::cls_construct_array, opal_class_t::cls_depth, opal_class_t::cls_destruct, opal_class_t::cls_destruct_array, opal_class_t::cls_initialized, opal_class_t::cls_parent, opal_atomic_lock(), and opal_atomic_unlock().

Referenced by opal_obj_new().

static opal_object_t * opal_obj_new ( opal_class_t cls)
inlinestatic

Create an object: dynamically allocate storage and run the class constructor.

Create new object: dynamically allocate storage and run the class constructor.

Parameters
typeType (class) of the object
Returns
Pointer to the object

Do not use this function directly: use OBJ_NEW() instead.

Parameters
sizeSize of the object
clsPointer to the class descriptor of this object
Returns
Pointer to the object

References opal_class_t::cls_initialized, opal_class_t::cls_sizeof, opal_class_initialize(), and opal_obj_run_constructors().

static void opal_obj_run_constructors ( opal_object_t object)
inlinestatic

Run the hierarchy of class constructors for this object, in a parent-first order.

Do not use this function directly: use OBJ_CONSTRUCT() instead.

WARNING: This implementation relies on a hardwired maximum depth of the inheritance tree!!!

Hardwired for fairly shallow inheritance trees

Parameters
sizePointer to the object.

References opal_object_t::obj_class.

Referenced by opal_obj_new().

static void opal_obj_run_destructors ( opal_object_t object)
inlinestatic

Run the hierarchy of class destructors for this object, in a parent-last order.

Do not use this function directly: use OBJ_DESTRUCT() instead.

Parameters
sizePointer to the object.

References opal_object_t::obj_class.

static int opal_obj_update ( opal_object_t object,
int  inc 
)
inlinestatic

Atomically update the object's reference count by some increment.

This function should not be used directly: it is called via the macros OBJ_RETAIN and OBJ_RELEASE

Parameters
objectPointer to the object
incIncrement by which to update reference count
Returns
New value of the reference count

References opal_object_t::obj_reference_count.