openmpi  3.1.6
About: Open MPI is a high performance Message Passing Interface (MPI) library project combining technologies and resources from several other projects (FT-MPI, LA-MPI, LAM/MPI, and PACX-MPI) in order to build the best MPI library available. 3.x series.
  Fossies Dox: openmpi-3.1.6.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

opal_object.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4  * University Research and Technology
5  * Corporation. All rights reserved.
6  * Copyright (c) 2004-2007 The University of Tennessee and The University
7  * of Tennessee Research Foundation. All rights
8  * reserved.
9  * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
10  * University of Stuttgart. All rights reserved.
11  * Copyright (c) 2004-2005 The Regents of the University of California.
12  * All rights reserved.
13  * Copyright (c) 2007-2014 Cisco Systems, Inc. All rights reserved.
14  * Copyright (c) 2014 Research Organization for Information Science
15  * and Technology (RIST). All rights reserved.
16  * Copyright (c) 2015 Los Alamos National Security, LLC. All rights
17  * reserved.
18  * $COPYRIGHT$
19  * Additional copyrights may follow
20  * $HEADER$
21  */
22 
119 #ifndef OPAL_OBJECT_H
120 #define OPAL_OBJECT_H
121 
122 #include "opal_config.h"
123 #include <assert.h>
124 #include <stdlib.h>
125 
127 
129 
130 #if OPAL_ENABLE_DEBUG
131 /* Any kind of unique ID should do the job */
132 #define OPAL_OBJ_MAGIC_ID ((0xdeafbeedULL << 32) + 0xdeafbeedULL)
133 #endif
134 
135 /* typedefs ***********************************************************/
136 
137 typedef struct opal_object_t opal_object_t;
138 typedef struct opal_class_t opal_class_t;
139 typedef void (*opal_construct_t) (opal_object_t *);
140 typedef void (*opal_destruct_t) (opal_object_t *);
141 
142 
143 /* types **************************************************************/
144 
151 struct opal_class_t {
152  const char *cls_name;
157  int cls_depth;
162  size_t cls_sizeof;
163 };
164 
165 extern int opal_class_init_epoch;
166 
172 #if OPAL_ENABLE_DEBUG
173 #define OPAL_OBJ_STATIC_INIT(BASE_CLASS) \
174  { \
175  .obj_magic_id = OPAL_OBJ_MAGIC_ID, \
176  .obj_class = OBJ_CLASS(BASE_CLASS), \
177  .obj_reference_count = 1, \
178  .cls_init_file_name = __FILE__, \
179  .cls_init_lineno = __LINE__, \
180  }
181 #else
182 #define OPAL_OBJ_STATIC_INIT(BASE_CLASS) \
183  { \
184  .obj_class = OBJ_CLASS(BASE_CLASS), \
185  .obj_reference_count = 1, \
186  }
187 #endif
188 
195 #if OPAL_ENABLE_DEBUG
196 
198  uint64_t obj_magic_id;
199 #endif
201  volatile int32_t obj_reference_count;
202 #if OPAL_ENABLE_DEBUG
203  const char* cls_init_file_name;
204  int cls_init_lineno;
205 #endif /* OPAL_ENABLE_DEBUG */
206 };
207 
208 /* macros ************************************************************/
209 
217 #define OBJ_CLASS(NAME) (&(NAME ## _class))
218 
219 
230 #define OBJ_CLASS_INSTANCE(NAME, PARENT, CONSTRUCTOR, DESTRUCTOR) \
231  opal_class_t NAME ## _class = { \
232  # NAME, \
233  OBJ_CLASS(PARENT), \
234  (opal_construct_t) CONSTRUCTOR, \
235  (opal_destruct_t) DESTRUCTOR, \
236  0, 0, NULL, NULL, \
237  sizeof(NAME) \
238  }
239 
240 
248 #define OBJ_CLASS_DECLARATION(NAME) \
249  extern opal_class_t NAME ## _class
250 
251 
259 static inline opal_object_t *opal_obj_new(opal_class_t * cls);
260 #if OPAL_ENABLE_DEBUG
261 static inline opal_object_t *opal_obj_new_debug(opal_class_t* type, const char* file, int line)
262 {
263  opal_object_t* object = opal_obj_new(type);
264  object->obj_magic_id = OPAL_OBJ_MAGIC_ID;
265  object->cls_init_file_name = file;
266  object->cls_init_lineno = line;
267  return object;
268 }
269 #define OBJ_NEW(type) \
270  ((type *)opal_obj_new_debug(OBJ_CLASS(type), __FILE__, __LINE__))
271 #else
272 #define OBJ_NEW(type) \
273  ((type *) opal_obj_new(OBJ_CLASS(type)))
274 #endif /* OPAL_ENABLE_DEBUG */
275 
281 #if OPAL_ENABLE_DEBUG
282 #define OBJ_RETAIN(object) \
283  do { \
284  assert(NULL != ((opal_object_t *) (object))->obj_class); \
285  assert(OPAL_OBJ_MAGIC_ID == ((opal_object_t *) (object))->obj_magic_id); \
286  opal_obj_update((opal_object_t *) (object), 1); \
287  assert(((opal_object_t *) (object))->obj_reference_count >= 0); \
288  } while (0)
289 #else
290 #define OBJ_RETAIN(object) opal_obj_update((opal_object_t *) (object), 1);
291 #endif
292 
297 #if OPAL_ENABLE_DEBUG
298 #define OBJ_REMEMBER_FILE_AND_LINENO( OBJECT, FILE, LINENO ) \
299  do { \
300  ((opal_object_t*)(OBJECT))->cls_init_file_name = FILE; \
301  ((opal_object_t*)(OBJECT))->cls_init_lineno = LINENO; \
302  } while(0)
303 #define OBJ_SET_MAGIC_ID( OBJECT, VALUE ) \
304  do { \
305  ((opal_object_t*)(OBJECT))->obj_magic_id = (VALUE); \
306  } while(0)
307 #else
308 #define OBJ_REMEMBER_FILE_AND_LINENO( OBJECT, FILE, LINENO )
309 #define OBJ_SET_MAGIC_ID( OBJECT, VALUE )
310 #endif /* OPAL_ENABLE_DEBUG */
311 
324 #if OPAL_ENABLE_DEBUG
325 #define OBJ_RELEASE(object) \
326  do { \
327  assert(OPAL_OBJ_MAGIC_ID == ((opal_object_t *) (object))->obj_magic_id); \
328  assert(NULL != ((opal_object_t *) (object))->obj_class); \
329  if (0 == opal_obj_update((opal_object_t *) (object), -1)) { \
330  OBJ_SET_MAGIC_ID((object), 0); \
331  opal_obj_run_destructors((opal_object_t *) (object)); \
332  OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
333  free(object); \
334  object = NULL; \
335  } \
336  } while (0)
337 #else
338 #define OBJ_RELEASE(object) \
339  do { \
340  if (0 == opal_obj_update((opal_object_t *) (object), -1)) { \
341  opal_obj_run_destructors((opal_object_t *) (object)); \
342  free(object); \
343  object = NULL; \
344  } \
345  } while (0)
346 #endif
347 
348 
356 #define OBJ_CONSTRUCT(object, type) \
357 do { \
358  OBJ_CONSTRUCT_INTERNAL((object), OBJ_CLASS(type)); \
359 } while (0)
360 
361 #define OBJ_CONSTRUCT_INTERNAL(object, type) \
362 do { \
363  OBJ_SET_MAGIC_ID((object), OPAL_OBJ_MAGIC_ID); \
364  if (opal_class_init_epoch != (type)->cls_initialized) { \
365  opal_class_initialize((type)); \
366  } \
367  ((opal_object_t *) (object))->obj_class = (type); \
368  ((opal_object_t *) (object))->obj_reference_count = 1; \
369  opal_obj_run_constructors((opal_object_t *) (object)); \
370  OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
371 } while (0)
372 
373 
379 #if OPAL_ENABLE_DEBUG
380 #define OBJ_DESTRUCT(object) \
381 do { \
382  assert(OPAL_OBJ_MAGIC_ID == ((opal_object_t *) (object))->obj_magic_id); \
383  OBJ_SET_MAGIC_ID((object), 0); \
384  opal_obj_run_destructors((opal_object_t *) (object)); \
385  OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
386 } while (0)
387 #else
388 #define OBJ_DESTRUCT(object) \
389 do { \
390  opal_obj_run_destructors((opal_object_t *) (object)); \
391  OBJ_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
392 } while (0)
393 #endif
394 
396 
397 /* declarations *******************************************************/
398 
408 
419 
432 static inline void opal_obj_run_constructors(opal_object_t * object)
433 {
434  opal_construct_t* cls_construct;
435 
436  assert(NULL != object->obj_class);
437 
438  cls_construct = object->obj_class->cls_construct_array;
439  while( NULL != *cls_construct ) {
440  (*cls_construct)(object);
441  cls_construct++;
442  }
443 }
444 
445 
454 static inline void opal_obj_run_destructors(opal_object_t * object)
455 {
456  opal_destruct_t* cls_destruct;
457 
458  assert(NULL != object->obj_class);
459 
460  cls_destruct = object->obj_class->cls_destruct_array;
461  while( NULL != *cls_destruct ) {
462  (*cls_destruct)(object);
463  cls_destruct++;
464  }
465 }
466 
467 
479 {
480  opal_object_t *object;
481  assert(cls->cls_sizeof >= sizeof(opal_object_t));
482 
483 #if OPAL_WANT_MEMCHECKER
484  object = (opal_object_t *) calloc(1, cls->cls_sizeof);
485 #else
486  object = (opal_object_t *) malloc(cls->cls_sizeof);
487 #endif
490  }
491  if (NULL != object) {
492  object->obj_class = cls;
493  object->obj_reference_count = 1;
495  }
496  return object;
497 }
498 
499 
510 static inline int opal_obj_update(opal_object_t *object, int inc) __opal_attribute_always_inline__;
511 static inline int opal_obj_update(opal_object_t *object, int inc)
512 {
513  return OPAL_THREAD_ADD32(&object->obj_reference_count, inc);
514 }
515 
517 
518 #endif
opal_obj_new
static opal_object_t * opal_obj_new(opal_class_t *cls)
Create an object: dynamically allocate storage and run the class constructor.
Definition: opal_object.h:478
opal_obj_update
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:511
opal_class_t::cls_destruct_array
opal_destruct_t * cls_destruct_array
array of parent class destructors
Definition: opal_object.h:160
opal_class_t::cls_destruct
opal_destruct_t cls_destruct
class destructor
Definition: opal_object.h:155
__opal_attribute_always_inline__
#define __opal_attribute_always_inline__
Definition: opal_config_bottom.h:104
opal_object_t::obj_class
opal_class_t * obj_class
class descriptor
Definition: opal_object.h:200
opal_class_t::cls_initialized
int cls_initialized
is class initialized
Definition: opal_object.h:156
thread_usage.h
opal_class_finalize
OPAL_DECLSPEC int opal_class_finalize(void)
Shut down the class system and release all memory.
Definition: opal_object.c:171
BEGIN_C_DECLS
#define BEGIN_C_DECLS
code that should be in ompi_config_bottom.h regardless of build status
Definition: opal_config_bottom.h:85
opal_object_t
Base object.
Definition: opal_object.h:194
opal_object_t::obj_reference_count
volatile int32_t obj_reference_count
reference count
Definition: opal_object.h:201
opal_construct_t
void(* opal_construct_t)(opal_object_t *)
Definition: opal_object.h:139
opal_obj_run_constructors
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:432
OPAL_THREAD_ADD32
#define OPAL_THREAD_ADD32
Definition: thread_usage.h:152
opal_class_t::cls_parent
opal_class_t * cls_parent
parent class descriptor
Definition: opal_object.h:153
OBJ_CLASS_DECLARATION
#define OBJ_CLASS_DECLARATION(NAME)
Declaration for class descriptor.
Definition: opal_object.h:248
opal_class_t
Class descriptor.
Definition: opal_object.h:151
OPAL_DECLSPEC
#define OPAL_DECLSPEC
Definition: opal_config_bottom.h:253
opal_class_t::cls_sizeof
size_t cls_sizeof
size of an object instance
Definition: opal_object.h:162
opal_class_initialize
OPAL_DECLSPEC void opal_class_initialize(opal_class_t *)
Lazy initialization of class descriptor.
Definition: opal_object.c:75
opal_obj_run_destructors
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:454
opal_class_t::cls_construct
opal_construct_t cls_construct
class constructor
Definition: opal_object.h:154
opal_class_init_epoch
int opal_class_init_epoch
Definition: opal_object.c:53
opal_class_t::cls_construct_array
opal_construct_t * cls_construct_array
array of parent class constructors
Definition: opal_object.h:158
opal_destruct_t
void(* opal_destruct_t)(opal_object_t *)
Definition: opal_object.h:140
opal_class_t::cls_name
const char * cls_name
symbolic name for class
Definition: opal_object.h:152
END_C_DECLS
#define END_C_DECLS
Definition: opal_config_bottom.h:86
opal_class_t::cls_depth
int cls_depth
depth of class hierarchy tree
Definition: opal_object.h:157
NULL
#define NULL
Copyright (C) 2000-2004 by Etnus, LLC.
Definition: ompi_msgq_dll.c:136