29
29
30
30
#include "opal/util/output.h"
31
31
#include "rcache_base_vma_tree.h"
32
+ #include "opal/mca/rcache/base/base.h"
32
33
33
34
OBJ_CLASS_INSTANCE (mca_rcache_base_vma_reg_list_item_t , opal_list_item_t , NULL , NULL );
34
35
35
36
static void mca_rcache_base_vma_item_construct (mca_rcache_base_vma_item_t * vma_item )
36
37
{
37
38
OBJ_CONSTRUCT (& vma_item -> reg_list , opal_list_t );
39
+ vma_item -> in_use = false;
38
40
}
39
41
40
42
static void mca_rcache_base_vma_item_destruct (mca_rcache_base_vma_item_t * vma_item )
41
43
{
42
44
OPAL_LIST_DESTRUCT (& vma_item -> reg_list );
43
45
}
44
46
45
- OBJ_CLASS_INSTANCE (mca_rcache_base_vma_item_t , opal_list_item_t ,
47
+ OBJ_CLASS_INSTANCE (mca_rcache_base_vma_item_t , opal_free_list_item_t ,
46
48
mca_rcache_base_vma_item_construct ,
47
49
mca_rcache_base_vma_item_destruct );
48
50
@@ -116,8 +118,7 @@ static inline
116
118
mca_rcache_base_vma_item_t * mca_rcache_base_vma_new (mca_rcache_base_vma_module_t * vma_module ,
117
119
uintptr_t start , uintptr_t end )
118
120
{
119
- mca_rcache_base_vma_item_t * vma_item = OBJ_NEW (mca_rcache_base_vma_item_t );
120
-
121
+ mca_rcache_base_vma_item_t * vma_item = (mca_rcache_base_vma_item_t * ) opal_free_list_get (& mca_rcache_base_vma_tree_items );
121
122
if (NULL == vma_item ) {
122
123
return NULL ;
123
124
}
@@ -131,6 +132,17 @@ mca_rcache_base_vma_item_t *mca_rcache_base_vma_new (mca_rcache_base_vma_module_
131
132
return vma_item ;
132
133
}
133
134
135
+ /* NTH: this function MUST not allocate or deallocate memory */
136
+ static void mca_rcache_base_vma_return (mca_rcache_base_vma_module_t * vma_module , mca_rcache_base_vma_item_t * vma_item )
137
+ {
138
+ opal_list_item_t * item ;
139
+ while (NULL != (item = opal_list_remove_first (& vma_item -> reg_list ))) {
140
+ OBJ_RELEASE (item );
141
+ }
142
+
143
+ opal_free_list_return (& mca_rcache_base_vma_tree_items , & vma_item -> super );
144
+ }
145
+
134
146
static inline int mca_rcache_base_vma_compare_regs (mca_rcache_base_registration_t * reg1 ,
135
147
mca_rcache_base_registration_t * reg2 )
136
148
{
@@ -186,7 +198,7 @@ static inline void mca_rcache_base_vma_remove_reg (mca_rcache_base_vma_item_t *v
186
198
mca_rcache_base_vma_reg_list_item_t * item ;
187
199
188
200
OPAL_LIST_FOREACH (item , & vma_item -> reg_list , mca_rcache_base_vma_reg_list_item_t ) {
189
- if (item -> reg == reg ) {
201
+ if (item -> reg == reg ) {
190
202
opal_list_remove_item (& vma_item -> reg_list , & item -> super );
191
203
OBJ_RELEASE (item );
192
204
break ;
@@ -388,7 +400,7 @@ int mca_rcache_base_vma_tree_iterate (mca_rcache_base_vma_module_t *vma_module,
388
400
389
401
/* all the registrations in the vma may be deleted by the callback so keep a
390
402
* reference until we are done with it. */
391
- OBJ_RETAIN ( vma ) ;
403
+ vma -> in_use = true ;
392
404
393
405
OPAL_LIST_FOREACH_SAFE (vma_item , next , & vma -> reg_list , mca_rcache_base_vma_reg_list_item_t ) {
394
406
rc = callback_fn (vma_item -> reg , ctx );
@@ -397,7 +409,7 @@ int mca_rcache_base_vma_tree_iterate (mca_rcache_base_vma_module_t *vma_module,
397
409
}
398
410
}
399
411
400
- OBJ_RELEASE ( vma ) ;
412
+ vma -> in_use = false ;
401
413
402
414
if (OPAL_SUCCESS != rc ) {
403
415
break ;
@@ -419,12 +431,26 @@ static inline int mca_rcache_base_vma_can_insert (mca_rcache_base_vma_module_t *
419
431
* into deadlock problems with some libc versions. The caller MUST hold the vma_lock
420
432
* when calling this function.
421
433
*/
422
- static void mca_rcache_base_vma_cleanup (mca_rcache_base_vma_module_t * vma_module )
434
+ static void mca_rcache_base_vma_cleanup (mca_rcache_base_vma_module_t * vma_module , int depth )
423
435
{
424
- opal_list_item_t * item ;
436
+ mca_rcache_base_vma_item_t * item ;
437
+
438
+ while (NULL != (item = (mca_rcache_base_vma_item_t * ) opal_lifo_pop_atomic (& vma_module -> vma_gc_lifo ))) {
439
+ if (OPAL_UNLIKELY (item -> in_use )) {
440
+ /* another thread is currently iterating on this vma and its registrations */
441
+ if (depth < 8 ) {
442
+ /* try to clean up additional vmas before returning */
443
+ mca_rcache_base_vma_cleanup (vma_module , depth + 1 );
444
+ }
425
445
426
- while (NULL != (item = opal_lifo_pop_atomic (& vma_module -> vma_gc_lifo ))) {
427
- OBJ_RELEASE (item );
446
+ if (item -> in_use ) {
447
+ /* will clean it up later */
448
+ opal_lifo_push_atomic (& vma_module -> vma_gc_lifo , & item -> super .super );
449
+ return ;
450
+ }
451
+ }
452
+
453
+ mca_rcache_base_vma_return (vma_module , (mca_rcache_base_vma_item_t * ) item );
428
454
}
429
455
}
430
456
@@ -434,7 +460,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
434
460
mca_rcache_base_vma_item_t * i ;
435
461
uintptr_t begin = (uintptr_t )reg -> base , end = (uintptr_t )reg -> bound ;
436
462
437
- mca_rcache_base_vma_cleanup (vma_module );
463
+ mca_rcache_base_vma_cleanup (vma_module , 0 );
438
464
439
465
opal_mutex_lock (& vma_module -> vma_lock );
440
466
@@ -448,7 +474,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
448
474
while (begin <= end ) {
449
475
mca_rcache_base_vma_item_t * vma = NULL ;
450
476
451
- if (opal_list_get_end (& vma_module -> vma_list ) == & i -> super ) {
477
+ if (opal_list_get_end (& vma_module -> vma_list ) == & i -> super . super ) {
452
478
if (mca_rcache_base_vma_can_insert (vma_module , end - begin + 1 , limit )) {
453
479
vma = mca_rcache_base_vma_new (vma_module , begin , end );
454
480
}
@@ -459,7 +485,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
459
485
460
486
mca_rcache_base_vma_update_byte_count (vma_module , end - begin + 1 );
461
487
462
- opal_list_append (& vma_module -> vma_list , & vma -> super );
488
+ opal_list_append (& vma_module -> vma_list , & vma -> super . super );
463
489
begin = vma -> end + 1 ;
464
490
mca_rcache_base_vma_add_reg (vma , reg );
465
491
opal_mutex_unlock (& vma_module -> vma_lock );
@@ -479,7 +505,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
479
505
mca_rcache_base_vma_update_byte_count (vma_module , tend - begin + 1 );
480
506
481
507
/* insert before */
482
- opal_list_insert_pos (& vma_module -> vma_list , & i -> super , & vma -> super );
508
+ opal_list_insert_pos (& vma_module -> vma_list , & i -> super . super , & vma -> super . super );
483
509
i = vma ;
484
510
begin = vma -> end + 1 ;
485
511
mca_rcache_base_vma_add_reg (vma , reg );
@@ -497,7 +523,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
497
523
/* add after */
498
524
opal_list_insert_pos (& vma_module -> vma_list ,
499
525
opal_list_get_next (& i -> super ),
500
- & vma -> super );
526
+ & vma -> super . super );
501
527
mca_rcache_base_vma_add_reg (i , reg );
502
528
begin = end + 1 ;
503
529
} else {
@@ -517,8 +543,8 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
517
543
518
544
/* add after */
519
545
opal_list_insert_pos (& vma_module -> vma_list ,
520
- opal_list_get_next (& i -> super ),
521
- & vma -> super );
546
+ opal_list_get_next (& i -> super . super ),
547
+ & vma -> super . super );
522
548
}
523
549
524
550
i = (mca_rcache_base_vma_item_t * ) opal_list_get_next (& i -> super );
@@ -569,15 +595,15 @@ int mca_rcache_base_vma_tree_delete (mca_rcache_base_vma_module_t *vma_module,
569
595
opal_rb_tree_delete (& vma_module -> rb_tree , vma );
570
596
mca_rcache_base_vma_update_byte_count (vma_module ,
571
597
vma -> start - vma -> end - 1 );
572
- opal_list_remove_item (& vma_module -> vma_list , & vma -> super );
573
- opal_lifo_push_atomic (& vma_module -> vma_gc_lifo , & vma -> super );
598
+ opal_list_remove_item (& vma_module -> vma_list , & vma -> super . super );
599
+ opal_lifo_push_atomic (& vma_module -> vma_gc_lifo , & vma -> super . super );
574
600
vma = next ;
575
601
} else {
576
602
int merged ;
577
603
578
604
do {
579
605
mca_rcache_base_vma_item_t * prev = NULL , * next = NULL ;
580
- if (opal_list_get_first (& vma_module -> vma_list ) != & vma -> super ) {
606
+ if (opal_list_get_first (& vma_module -> vma_list ) != & vma -> super . super ) {
581
607
prev = (mca_rcache_base_vma_item_t * ) opal_list_get_prev (vma );
582
608
}
583
609
@@ -586,23 +612,23 @@ int mca_rcache_base_vma_tree_delete (mca_rcache_base_vma_module_t *vma_module,
586
612
if (prev && vma -> start == prev -> end + 1 &&
587
613
mca_rcache_base_vma_compare_reg_lists (vma , prev )) {
588
614
prev -> end = vma -> end ;
589
- opal_list_remove_item (& vma_module -> vma_list , & vma -> super );
615
+ opal_list_remove_item (& vma_module -> vma_list , & vma -> super . super );
590
616
opal_rb_tree_delete (& vma_module -> rb_tree , vma );
591
- opal_lifo_push_atomic (& vma_module -> vma_gc_lifo , & vma -> super );
617
+ opal_lifo_push_atomic (& vma_module -> vma_gc_lifo , & vma -> super . super );
592
618
vma = prev ;
593
619
merged = 1 ;
594
620
}
595
621
596
- if (opal_list_get_last (& vma_module -> vma_list ) != & vma -> super ) {
622
+ if (opal_list_get_last (& vma_module -> vma_list ) != & vma -> super . super ) {
597
623
next = (mca_rcache_base_vma_item_t * ) opal_list_get_next (vma );
598
624
}
599
625
600
626
if (next && vma -> end + 1 == next -> start &&
601
627
mca_rcache_base_vma_compare_reg_lists (vma , next )) {
602
628
vma -> end = next -> end ;
603
- opal_list_remove_item (& vma_module -> vma_list , & next -> super );
629
+ opal_list_remove_item (& vma_module -> vma_list , & next -> super . super );
604
630
opal_rb_tree_delete (& vma_module -> rb_tree , next );
605
- opal_lifo_push_atomic (& vma_module -> vma_gc_lifo , & next -> super );
631
+ opal_lifo_push_atomic (& vma_module -> vma_gc_lifo , & next -> super . super );
606
632
merged = 1 ;
607
633
}
608
634
} while (merged );
0 commit comments