99#define CONCURRENT_SET_KEY_MASK (~CONCURRENT_SET_CONTINUATION_BIT)
1010
1111/*#define CONCURRENT_SET_DEBUG 0*/
12- #define CONCURRENT_SET_DEBUG 1
12+ #define CONCURRENT_SET_DEBUG 0
1313
1414enum concurrent_set_special_values {
1515 CONCURRENT_SET_EMPTY = 0 ,
@@ -35,6 +35,14 @@ struct concurrent_set {
3535 const struct rb_concurrent_set_funcs * funcs ;
3636 struct concurrent_set_entry * entries ;
3737 int key_type ;
38+ #if CONCURRENT_SET_DEBUG
39+ rb_atomic_t find_count ;
40+ rb_atomic_t find_probe_total ;
41+ rb_atomic_t find_probe_max ;
42+ rb_atomic_t insert_count ;
43+ rb_atomic_t insert_probe_total ;
44+ rb_atomic_t insert_probe_max ;
45+ #endif
3846};
3947
4048static bool
@@ -143,6 +151,42 @@ rb_concurrent_set_capacity(VALUE set_obj)
143151 return set -> capacity ;
144152}
145153
154+ void
155+ rb_concurrent_set_probe_stats (VALUE set_obj ,
156+ rb_atomic_t * find_count , rb_atomic_t * find_probe_total , rb_atomic_t * find_probe_max ,
157+ rb_atomic_t * insert_count , rb_atomic_t * insert_probe_total , rb_atomic_t * insert_probe_max )
158+ {
159+ #if CONCURRENT_SET_DEBUG
160+ struct concurrent_set * set = RTYPEDDATA_GET_DATA (set_obj );
161+ * find_count = RUBY_ATOMIC_LOAD (set -> find_count );
162+ * find_probe_total = RUBY_ATOMIC_LOAD (set -> find_probe_total );
163+ * find_probe_max = RUBY_ATOMIC_LOAD (set -> find_probe_max );
164+ * insert_count = RUBY_ATOMIC_LOAD (set -> insert_count );
165+ * insert_probe_total = RUBY_ATOMIC_LOAD (set -> insert_probe_total );
166+ * insert_probe_max = RUBY_ATOMIC_LOAD (set -> insert_probe_max );
167+ #else
168+ * find_count = 0 ;
169+ * find_probe_total = 0 ;
170+ * find_probe_max = 0 ;
171+ * insert_count = 0 ;
172+ * insert_probe_total = 0 ;
173+ * insert_probe_max = 0 ;
174+ #endif
175+ }
176+
177+ #if CONCURRENT_SET_DEBUG
178+ static void
179+ concurrent_set_atomic_max (rb_atomic_t * target , rb_atomic_t val )
180+ {
181+ rb_atomic_t cur = RUBY_ATOMIC_LOAD (* target );
182+ while (val > cur ) {
183+ rb_atomic_t prev = rbimpl_atomic_cas (target , cur , val , RBIMPL_ATOMIC_RELAXED , RBIMPL_ATOMIC_RELAXED );
184+ if (prev == cur ) break ;
185+ cur = prev ;
186+ }
187+ }
188+ #endif
189+
146190struct concurrent_set_probe {
147191 int idx ;
148192 int d ;
@@ -354,6 +398,11 @@ rb_concurrent_set_find(VALUE *set_obj_ptr, VALUE key)
354398 VALUE curr_hash = rbimpl_atomic_value_load (& entry -> hash , RBIMPL_ATOMIC_ACQUIRE ) & CONCURRENT_SET_HASH_MASK ;
355399
356400 if (curr_hash == 0 ) {
401+ #if CONCURRENT_SET_DEBUG
402+ rbimpl_atomic_fetch_add (& set -> find_count , 1 , RBIMPL_ATOMIC_RELAXED );
403+ rbimpl_atomic_fetch_add (& set -> find_probe_total , probe .d , RBIMPL_ATOMIC_RELAXED );
404+ concurrent_set_atomic_max (& set -> find_probe_max , probe .d );
405+ #endif
357406 return 0 ;
358407 }
359408
@@ -363,6 +412,11 @@ rb_concurrent_set_find(VALUE *set_obj_ptr, VALUE key)
363412
364413 if (curr_hash != hash ) {
365414 if (!continuation ) {
415+ #if CONCURRENT_SET_DEBUG
416+ rbimpl_atomic_fetch_add (& set -> find_count , 1 , RBIMPL_ATOMIC_RELAXED );
417+ rbimpl_atomic_fetch_add (& set -> find_probe_total , probe .d , RBIMPL_ATOMIC_RELAXED );
418+ concurrent_set_atomic_max (& set -> find_probe_max , probe .d );
419+ #endif
366420 return 0 ;
367421 }
368422 idx = concurrent_set_probe_next (& probe );
@@ -389,11 +443,21 @@ rb_concurrent_set_find(VALUE *set_obj_ptr, VALUE key)
389443
390444 if (set -> funcs -> cmp (key , curr_key )) {
391445 // We've found a match.
446+ #if CONCURRENT_SET_DEBUG
447+ rbimpl_atomic_fetch_add (& set -> find_count , 1 , RBIMPL_ATOMIC_RELAXED );
448+ rbimpl_atomic_fetch_add (& set -> find_probe_total , probe .d , RBIMPL_ATOMIC_RELAXED );
449+ concurrent_set_atomic_max (& set -> find_probe_max , probe .d );
450+ #endif
392451 RB_GC_GUARD (set_obj );
393452 return curr_key ;
394453 }
395454
396455 if (!continuation ) {
456+ #if CONCURRENT_SET_DEBUG
457+ rbimpl_atomic_fetch_add (& set -> find_count , 1 , RBIMPL_ATOMIC_RELAXED );
458+ rbimpl_atomic_fetch_add (& set -> find_probe_total , probe .d , RBIMPL_ATOMIC_RELAXED );
459+ concurrent_set_atomic_max (& set -> find_probe_max , probe .d );
460+ #endif
397461 return 0 ;
398462 }
399463
@@ -488,6 +552,11 @@ rb_concurrent_set_find_or_insert(VALUE *set_obj_ptr, VALUE key, void *data)
488552
489553 VALUE prev_raw_key = rbimpl_atomic_value_cas (& entry -> key , raw_key , key | (continuation ? CONCURRENT_SET_CONTINUATION_BIT : 0 ), RBIMPL_ATOMIC_RELEASE , RBIMPL_ATOMIC_ACQUIRE );
490554 if (prev_raw_key == raw_key ) {
555+ #if CONCURRENT_SET_DEBUG
556+ rbimpl_atomic_fetch_add (& set -> insert_count , 1 , RBIMPL_ATOMIC_RELAXED );
557+ rbimpl_atomic_fetch_add (& set -> insert_probe_total , probe .d , RBIMPL_ATOMIC_RELAXED );
558+ concurrent_set_atomic_max (& set -> insert_probe_max , probe .d );
559+ #endif
491560 RB_GC_GUARD (set_obj );
492561 return key ;
493562 }
@@ -525,6 +594,11 @@ rb_concurrent_set_find_or_insert(VALUE *set_obj_ptr, VALUE key, void *data)
525594
526595 if (set -> funcs -> cmp (key , curr_key )) {
527596 // We've found a live match.
597+ #if CONCURRENT_SET_DEBUG
598+ rbimpl_atomic_fetch_add (& set -> insert_count , 1 , RBIMPL_ATOMIC_RELAXED );
599+ rbimpl_atomic_fetch_add (& set -> insert_probe_total , probe .d , RBIMPL_ATOMIC_RELAXED );
600+ concurrent_set_atomic_max (& set -> insert_probe_max , probe .d );
601+ #endif
528602 RB_GC_GUARD (set_obj );
529603
530604 // We created key using set->funcs->create, but we didn't end
0 commit comments