Skip to content

Commit 0a6cd03

Browse files
jhawthornluke-gru
andcommitted
Add ASSERT_vm_locking_with_barrier
Previously we just had a comment stating that the code required a barrier. Turns out it's not too difficult to properly assert that. Co-authored-by: Luke Gruber <luke.gru@gmail.com>
1 parent 2de13f4 commit 0a6cd03

File tree

4 files changed

+20
-6
lines changed

4 files changed

+20
-6
lines changed

concurrent_set.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,7 @@ rb_concurrent_set_find_or_insert(VALUE *set_obj_ptr, VALUE key, void *data)
352352
VALUE
353353
rb_concurrent_set_delete_by_identity(VALUE set_obj, VALUE key)
354354
{
355-
// Assume locking and barrier (which there is no assert for).
356-
ASSERT_vm_locking();
355+
ASSERT_vm_locking_with_barrier();
357356

358357
struct concurrent_set *set = RTYPEDDATA_GET_DATA(set_obj);
359358

@@ -391,8 +390,7 @@ rb_concurrent_set_delete_by_identity(VALUE set_obj, VALUE key)
391390
void
392391
rb_concurrent_set_foreach_with_replace(VALUE set_obj, int (*callback)(VALUE *key, void *data), void *data)
393392
{
394-
// Assume locking and barrier (which there is no assert for).
395-
ASSERT_vm_locking();
393+
ASSERT_vm_locking_with_barrier();
396394

397395
struct concurrent_set *set = RTYPEDDATA_GET_DATA(set_obj);
398396

string.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,8 +600,7 @@ rb_obj_is_fstring_table(VALUE obj)
600600
void
601601
rb_gc_free_fstring(VALUE obj)
602602
{
603-
// Assume locking and barrier (which there is no assert for)
604-
ASSERT_vm_locking();
603+
ASSERT_vm_locking_with_barrier();
605604

606605
rb_concurrent_set_delete_by_identity(fstring_table_obj, obj);
607606

vm_sync.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ RUBY_ASSERT_vm_locking(void)
2525
}
2626
}
2727

28+
void
29+
RUBY_ASSERT_vm_locking_with_barrier(void)
30+
{
31+
if (rb_multi_ractor_p()) {
32+
rb_vm_t *vm = GET_VM();
33+
VM_ASSERT(vm_locked(vm));
34+
35+
if (vm->ractor.cnt > 1) {
36+
/* Written to only when holding both ractor.sync and ractor.sched lock */
37+
VM_ASSERT(vm->ractor.sched.barrier_waiting);
38+
}
39+
}
40+
}
41+
2842
void
2943
RUBY_ASSERT_vm_unlocking(void)
3044
{

vm_sync.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,14 @@ rb_vm_lock_leave_cr(struct rb_ractor_struct *cr, unsigned int *levp, const char
142142

143143
#if RUBY_DEBUG > 0
144144
void RUBY_ASSERT_vm_locking(void);
145+
void RUBY_ASSERT_vm_locking_with_barrier(void);
145146
void RUBY_ASSERT_vm_unlocking(void);
146147
#define ASSERT_vm_locking() RUBY_ASSERT_vm_locking()
148+
#define ASSERT_vm_locking_with_barrier() RUBY_ASSERT_vm_locking_with_barrier()
147149
#define ASSERT_vm_unlocking() RUBY_ASSERT_vm_unlocking()
148150
#else
149151
#define ASSERT_vm_locking()
152+
#define ASSERT_vm_locking_with_barrier()
150153
#define ASSERT_vm_unlocking()
151154
#endif
152155

0 commit comments

Comments
 (0)