This source file includes following definitions.
- pmix_obj_new_debug
- pmix_obj_run_constructors
- pmix_obj_run_destructors
- pmix_obj_new
- pmix_obj_update
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 #ifndef PMIX_OBJECT_H
121 #define PMIX_OBJECT_H
122
123 #include <src/include/pmix_config.h>
124 #include <pmix_common.h>
125
126 #include <assert.h>
127 #ifdef HAVE_STDLIB_H
128 #include <stdlib.h>
129 #endif
130
131 #include "src/threads/thread_usage.h"
132
133 BEGIN_C_DECLS
134
135 #if PMIX_ENABLE_DEBUG
136
137 #define PMIX_OBJ_MAGIC_ID ((0xdeafbeedULL << 32) + 0xdeafbeedULL)
138 #endif
139
140
141
142 typedef struct pmix_object_t pmix_object_t;
143 typedef struct pmix_class_t pmix_class_t;
144 typedef void (*pmix_construct_t) (pmix_object_t *);
145 typedef void (*pmix_destruct_t) (pmix_object_t *);
146
147
148
149
150
151
152
153
154
155
156 struct pmix_class_t {
157 const char *cls_name;
158 pmix_class_t *cls_parent;
159 pmix_construct_t cls_construct;
160 pmix_destruct_t cls_destruct;
161 int cls_initialized;
162 int cls_depth;
163 pmix_construct_t *cls_construct_array;
164
165 pmix_destruct_t *cls_destruct_array;
166
167 size_t cls_sizeof;
168 };
169
170 PMIX_EXPORT extern int pmix_class_init_epoch;
171
172
173
174
175
176
177 #if PMIX_ENABLE_DEBUG
178 #define PMIX_OBJ_STATIC_INIT(BASE_CLASS) { PMIX_OBJ_MAGIC_ID, PMIX_CLASS(BASE_CLASS), 1, __FILE__, __LINE__ }
179 #else
180 #define PMIX_OBJ_STATIC_INIT(BASE_CLASS) { PMIX_CLASS(BASE_CLASS), 1 }
181 #endif
182
183
184
185
186
187
188 struct pmix_object_t {
189 #if PMIX_ENABLE_DEBUG
190
191
192 uint64_t obj_magic_id;
193 #endif
194 pmix_class_t *obj_class;
195 pmix_atomic_int32_t obj_reference_count;
196 #if PMIX_ENABLE_DEBUG
197 const char* cls_init_file_name;
198 int cls_init_lineno;
199 #endif
200 };
201
202
203
204
205
206
207
208
209
210
211 #define PMIX_CLASS(NAME) (&(NAME ## _class))
212
213
214
215
216
217
218
219
220
221
222
223
224 #define PMIX_CLASS_INSTANCE(NAME, PARENT, CONSTRUCTOR, DESTRUCTOR) \
225 pmix_class_t NAME ## _class = { \
226 # NAME, \
227 PMIX_CLASS(PARENT), \
228 (pmix_construct_t) CONSTRUCTOR, \
229 (pmix_destruct_t) DESTRUCTOR, \
230 0, 0, NULL, NULL, \
231 sizeof(NAME) \
232 }
233
234
235
236
237
238
239
240
241
242 #define PMIX_CLASS_DECLARATION(NAME) \
243 extern pmix_class_t NAME ## _class
244
245
246
247
248
249
250
251
252
253 static inline pmix_object_t *pmix_obj_new(pmix_class_t * cls);
254 #if PMIX_ENABLE_DEBUG
255 static inline pmix_object_t *pmix_obj_new_debug(pmix_class_t* type, const char* file, int line)
256 {
257 pmix_object_t* object = pmix_obj_new(type);
258 object->obj_magic_id = PMIX_OBJ_MAGIC_ID;
259 object->cls_init_file_name = file;
260 object->cls_init_lineno = line;
261 return object;
262 }
263 #define PMIX_NEW(type) \
264 ((type *)pmix_obj_new_debug(PMIX_CLASS(type), __FILE__, __LINE__))
265 #else
266 #define PMIX_NEW(type) \
267 ((type *) pmix_obj_new(PMIX_CLASS(type)))
268 #endif
269
270
271
272
273
274
275 #if PMIX_ENABLE_DEBUG
276 #define PMIX_RETAIN(object) \
277 do { \
278 assert(NULL != ((pmix_object_t *) (object))->obj_class); \
279 assert(PMIX_OBJ_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \
280 pmix_obj_update((pmix_object_t *) (object), 1); \
281 assert(((pmix_object_t *) (object))->obj_reference_count >= 0); \
282 } while (0)
283 #else
284 #define PMIX_RETAIN(object) pmix_obj_update((pmix_object_t *) (object), 1);
285 #endif
286
287
288
289
290
291 #if PMIX_ENABLE_DEBUG
292 #define PMIX_REMEMBER_FILE_AND_LINENO( OBJECT, FILE, LINENO ) \
293 do { \
294 ((pmix_object_t*)(OBJECT))->cls_init_file_name = FILE; \
295 ((pmix_object_t*)(OBJECT))->cls_init_lineno = LINENO; \
296 } while (0)
297 #define PMIX_SET_MAGIC_ID( OBJECT, VALUE ) \
298 do { \
299 ((pmix_object_t*)(OBJECT))->obj_magic_id = (VALUE); \
300 } while (0)
301 #else
302 #define PMIX_REMEMBER_FILE_AND_LINENO( OBJECT, FILE, LINENO )
303 #define PMIX_SET_MAGIC_ID( OBJECT, VALUE )
304 #endif
305
306
307
308
309
310
311
312
313
314
315
316 #if PMIX_ENABLE_DEBUG
317 #define PMIX_RELEASE(object) \
318 do { \
319 assert(NULL != ((pmix_object_t *) (object))->obj_class); \
320 assert(PMIX_OBJ_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \
321 if (0 == pmix_obj_update((pmix_object_t *) (object), -1)) { \
322 PMIX_SET_MAGIC_ID((object), 0); \
323 pmix_obj_run_destructors((pmix_object_t *) (object)); \
324 PMIX_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
325 free(object); \
326 object = NULL; \
327 } \
328 } while (0)
329 #else
330 #define PMIX_RELEASE(object) \
331 do { \
332 if (0 == pmix_obj_update((pmix_object_t *) (object), -1)) { \
333 pmix_obj_run_destructors((pmix_object_t *) (object)); \
334 free(object); \
335 object = NULL; \
336 } \
337 } while (0)
338 #endif
339
340
341
342
343
344
345
346
347
348 #define PMIX_CONSTRUCT(object, type) \
349 do { \
350 PMIX_CONSTRUCT_INTERNAL((object), PMIX_CLASS(type)); \
351 } while (0)
352
353 #define PMIX_CONSTRUCT_INTERNAL(object, type) \
354 do { \
355 PMIX_SET_MAGIC_ID((object), PMIX_OBJ_MAGIC_ID); \
356 if (pmix_class_init_epoch != (type)->cls_initialized) { \
357 pmix_class_initialize((type)); \
358 } \
359 ((pmix_object_t *) (object))->obj_class = (type); \
360 ((pmix_object_t *) (object))->obj_reference_count = 1; \
361 pmix_obj_run_constructors((pmix_object_t *) (object)); \
362 PMIX_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
363 } while (0)
364
365
366
367
368
369
370
371 #if PMIX_ENABLE_DEBUG
372 #define PMIX_DESTRUCT(object) \
373 do { \
374 assert(PMIX_OBJ_MAGIC_ID == ((pmix_object_t *) (object))->obj_magic_id); \
375 PMIX_SET_MAGIC_ID((object), 0); \
376 pmix_obj_run_destructors((pmix_object_t *) (object)); \
377 PMIX_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
378 } while (0)
379 #else
380 #define PMIX_DESTRUCT(object) \
381 do { \
382 pmix_obj_run_destructors((pmix_object_t *) (object)); \
383 PMIX_REMEMBER_FILE_AND_LINENO( object, __FILE__, __LINE__ ); \
384 } while (0)
385 #endif
386
387 PMIX_CLASS_DECLARATION(pmix_object_t);
388
389
390
391
392
393
394
395
396
397
398
399 PMIX_EXPORT void pmix_class_initialize(pmix_class_t *);
400
401
402
403
404
405
406
407
408
409
410 PMIX_EXPORT int pmix_class_finalize(void);
411
412
413
414
415
416
417
418
419
420
421
422
423
424 static inline void pmix_obj_run_constructors(pmix_object_t * object)
425 {
426 pmix_construct_t* cls_construct;
427
428 assert(NULL != object->obj_class);
429
430 cls_construct = object->obj_class->cls_construct_array;
431 while( NULL != *cls_construct ) {
432 (*cls_construct)(object);
433 cls_construct++;
434 }
435 }
436
437
438
439
440
441
442
443
444
445
446 static inline void pmix_obj_run_destructors(pmix_object_t * object)
447 {
448 pmix_destruct_t* cls_destruct;
449
450 assert(NULL != object->obj_class);
451
452 cls_destruct = object->obj_class->cls_destruct_array;
453 while( NULL != *cls_destruct ) {
454 (*cls_destruct)(object);
455 cls_destruct++;
456 }
457 }
458
459
460
461
462
463
464
465
466
467
468
469
470 static inline pmix_object_t *pmix_obj_new(pmix_class_t * cls)
471 {
472 pmix_object_t *object;
473 assert(cls->cls_sizeof >= sizeof(pmix_object_t));
474
475 object = (pmix_object_t *) malloc(cls->cls_sizeof);
476 if (pmix_class_init_epoch != cls->cls_initialized) {
477 pmix_class_initialize(cls);
478 }
479 if (NULL != object) {
480 object->obj_class = cls;
481 object->obj_reference_count = 1;
482 pmix_obj_run_constructors(object);
483 }
484 return object;
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498 static inline int pmix_obj_update(pmix_object_t *object, int inc) __pmix_attribute_always_inline__;
499 static inline int pmix_obj_update(pmix_object_t *object, int inc)
500 {
501 return PMIX_THREAD_ADD_FETCH32(&object->obj_reference_count, inc);
502 }
503
504 END_C_DECLS
505
506 #endif