2929
3030#include "opal/util/output.h"
3131#include "rcache_base_vma_tree.h"
32+ #include "opal/mca/rcache/base/base.h"
3233
3334OBJ_CLASS_INSTANCE (mca_rcache_base_vma_reg_list_item_t , opal_list_item_t , NULL , NULL );
3435
3536static void mca_rcache_base_vma_item_construct (mca_rcache_base_vma_item_t * vma_item )
3637{
3738 OBJ_CONSTRUCT (& vma_item -> reg_list , opal_list_t );
39+ vma_item -> in_use = false;
3840}
3941
4042static void mca_rcache_base_vma_item_destruct (mca_rcache_base_vma_item_t * vma_item )
4143{
4244 OPAL_LIST_DESTRUCT (& vma_item -> reg_list );
4345}
4446
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 ,
4648 mca_rcache_base_vma_item_construct ,
4749 mca_rcache_base_vma_item_destruct );
4850
@@ -116,8 +118,7 @@ static inline
116118mca_rcache_base_vma_item_t * mca_rcache_base_vma_new (mca_rcache_base_vma_module_t * vma_module ,
117119 uintptr_t start , uintptr_t end )
118120{
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 );
121122 if (NULL == vma_item ) {
122123 return NULL ;
123124 }
@@ -131,6 +132,17 @@ mca_rcache_base_vma_item_t *mca_rcache_base_vma_new (mca_rcache_base_vma_module_
131132 return vma_item ;
132133}
133134
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+
134146static inline int mca_rcache_base_vma_compare_regs (mca_rcache_base_registration_t * reg1 ,
135147 mca_rcache_base_registration_t * reg2 )
136148{
@@ -186,7 +198,7 @@ static inline void mca_rcache_base_vma_remove_reg (mca_rcache_base_vma_item_t *v
186198 mca_rcache_base_vma_reg_list_item_t * item ;
187199
188200 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 ) {
190202 opal_list_remove_item (& vma_item -> reg_list , & item -> super );
191203 OBJ_RELEASE (item );
192204 break ;
@@ -388,7 +400,7 @@ int mca_rcache_base_vma_tree_iterate (mca_rcache_base_vma_module_t *vma_module,
388400
389401 /* all the registrations in the vma may be deleted by the callback so keep a
390402 * reference until we are done with it. */
391- OBJ_RETAIN ( vma ) ;
403+ vma -> in_use = true ;
392404
393405 OPAL_LIST_FOREACH_SAFE (vma_item , next , & vma -> reg_list , mca_rcache_base_vma_reg_list_item_t ) {
394406 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,
397409 }
398410 }
399411
400- OBJ_RELEASE ( vma ) ;
412+ vma -> in_use = false ;
401413
402414 if (OPAL_SUCCESS != rc ) {
403415 break ;
@@ -419,12 +431,26 @@ static inline int mca_rcache_base_vma_can_insert (mca_rcache_base_vma_module_t *
419431 * into deadlock problems with some libc versions. The caller MUST hold the vma_lock
420432 * when calling this function.
421433 */
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 )
423435{
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+ }
425445
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 );
428454 }
429455}
430456
@@ -434,7 +460,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
434460 mca_rcache_base_vma_item_t * i ;
435461 uintptr_t begin = (uintptr_t )reg -> base , end = (uintptr_t )reg -> bound ;
436462
437- mca_rcache_base_vma_cleanup (vma_module );
463+ mca_rcache_base_vma_cleanup (vma_module , 0 );
438464
439465 opal_mutex_lock (& vma_module -> vma_lock );
440466
@@ -448,7 +474,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
448474 while (begin <= end ) {
449475 mca_rcache_base_vma_item_t * vma = NULL ;
450476
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 ) {
452478 if (mca_rcache_base_vma_can_insert (vma_module , end - begin + 1 , limit )) {
453479 vma = mca_rcache_base_vma_new (vma_module , begin , end );
454480 }
@@ -459,7 +485,7 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
459485
460486 mca_rcache_base_vma_update_byte_count (vma_module , end - begin + 1 );
461487
462- opal_list_append (& vma_module -> vma_list , & vma -> super );
488+ opal_list_append (& vma_module -> vma_list , & vma -> super . super );
463489 begin = vma -> end + 1 ;
464490 mca_rcache_base_vma_add_reg (vma , reg );
465491 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,
479505 mca_rcache_base_vma_update_byte_count (vma_module , tend - begin + 1 );
480506
481507 /* 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 );
483509 i = vma ;
484510 begin = vma -> end + 1 ;
485511 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,
497523 /* add after */
498524 opal_list_insert_pos (& vma_module -> vma_list ,
499525 opal_list_get_next (& i -> super ),
500- & vma -> super );
526+ & vma -> super . super );
501527 mca_rcache_base_vma_add_reg (i , reg );
502528 begin = end + 1 ;
503529 } else {
@@ -517,8 +543,8 @@ int mca_rcache_base_vma_tree_insert (mca_rcache_base_vma_module_t *vma_module,
517543
518544 /* add after */
519545 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 );
522548 }
523549
524550 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,
569595 opal_rb_tree_delete (& vma_module -> rb_tree , vma );
570596 mca_rcache_base_vma_update_byte_count (vma_module ,
571597 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 );
574600 vma = next ;
575601 } else {
576602 int merged ;
577603
578604 do {
579605 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 ) {
581607 prev = (mca_rcache_base_vma_item_t * ) opal_list_get_prev (vma );
582608 }
583609
@@ -586,23 +612,23 @@ int mca_rcache_base_vma_tree_delete (mca_rcache_base_vma_module_t *vma_module,
586612 if (prev && vma -> start == prev -> end + 1 &&
587613 mca_rcache_base_vma_compare_reg_lists (vma , prev )) {
588614 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 );
590616 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 );
592618 vma = prev ;
593619 merged = 1 ;
594620 }
595621
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 ) {
597623 next = (mca_rcache_base_vma_item_t * ) opal_list_get_next (vma );
598624 }
599625
600626 if (next && vma -> end + 1 == next -> start &&
601627 mca_rcache_base_vma_compare_reg_lists (vma , next )) {
602628 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 );
604630 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 );
606632 merged = 1 ;
607633 }
608634 } while (merged );
0 commit comments