This source file includes following definitions.
- opal_obj_new_debug
- opal_obj_run_constructors
- opal_obj_run_destructors
- opal_obj_new
- opal_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 #ifndef OPAL_OBJECT_H
120 #define OPAL_OBJECT_H
121
122 #include "opal_config.h"
123 #include <assert.h>
124 #include <stdlib.h>
125
126 #include "opal/threads/thread_usage.h"
127
128 BEGIN_C_DECLS
129
130 #if OPAL_ENABLE_DEBUG
131
132 #define OPAL_OBJ_MAGIC_ID ((0xdeafbeedULL << 32) + 0xdeafbeedULL)
133 #endif
134
135
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
144
145
146
147
148
149
150
151 struct opal_class_t {
152 const char *cls_name;
153 opal_class_t *cls_parent;
154 opal_construct_t cls_construct;
155 opal_destruct_t cls_destruct;
156 int cls_initialized;
157 int cls_depth;
158 opal_construct_t *cls_construct_array;
159
160 opal_destruct_t *cls_destruct_array;
161
162 size_t cls_sizeof;
163 };
164
165 extern int opal_class_init_epoch;
166
167
168
169
170
171
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
189
190
191
192
193
194 struct opal_object_t {
195 #if OPAL_ENABLE_DEBUG
196
197
198 uint64_t obj_magic_id;
199 #endif
200 opal_class_t *obj_class;
201 opal_atomic_int32_t obj_reference_count;
202 #if OPAL_ENABLE_DEBUG
203 const char* cls_init_file_name;
204 int cls_init_lineno;
205 #endif
206 };
207
208
209
210
211
212
213
214
215
216
217 #define OBJ_CLASS(NAME) (&(NAME ## _class))
218
219
220
221
222
223
224
225
226
227
228
229
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
241
242
243
244
245
246
247
248 #define OBJ_CLASS_DECLARATION(NAME) \
249 extern opal_class_t NAME ## _class
250
251
252
253
254
255
256
257
258
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
275
276
277
278
279
280
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
293
294
295
296
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
311
312
313
314
315
316
317
318
319
320
321
322
323
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
349
350
351
352
353
354
355
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
374
375
376
377
378
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
395 OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_object_t);
396
397
398
399
400
401
402
403
404
405
406
407 OPAL_DECLSPEC void opal_class_initialize(opal_class_t *);
408
409
410
411
412
413
414
415
416
417
418 OPAL_DECLSPEC int opal_class_finalize(void);
419
420
421
422
423
424
425
426
427
428
429
430
431
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
446
447
448
449
450
451
452
453
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
468
469
470
471
472
473
474
475
476
477
478 static inline opal_object_t *opal_obj_new(opal_class_t * cls)
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
488 if (opal_class_init_epoch != cls->cls_initialized) {
489 opal_class_initialize(cls);
490 }
491 if (NULL != object) {
492 object->obj_class = cls;
493 object->obj_reference_count = 1;
494 opal_obj_run_constructors(object);
495 }
496 return object;
497 }
498
499
500
501
502
503
504
505
506
507
508
509
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_ADD_FETCH32(&object->obj_reference_count, inc);
514 }
515
516 END_C_DECLS
517
518 #endif