Skip to content

Commit b90b712

Browse files
Only do it after.
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent ea424f0 commit b90b712

1 file changed

Lines changed: 16 additions & 17 deletions

File tree

scheduler.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,29 +1097,28 @@ VALUE rb_fiber_scheduler_blocking_operation_wait(VALUE scheduler, void* (*functi
10971097

10981098
// Create a new BlockingOperation with the blocking operation
10991099
VALUE blocking_operation = rb_fiber_scheduler_blocking_operation_new(function, data, unblock_function, data2, flags, state);
1100-
// Success, this works:
1101-
rb_fiber_scheduler_blocking_operation_t *operation = get_blocking_operation(blocking_operation);
11021100

1103-
size_t gc_count_before = rb_gc_count();
1104-
size_t minor_before = rb_gc_stat(ID2SYM(rb_intern("minor_gc_count")));
1105-
size_t major_before = rb_gc_stat(ID2SYM(rb_intern("major_gc_count")));
1106-
fprintf(stderr, "before rb_funcall: gc_count=%zu minor=%zu major=%zu operation=%p\n",
1107-
gc_count_before, minor_before, major_before, operation);
1101+
// Case under investigation:
1102+
// CASE_A (fails): operation = NULL -- no pre-funcall get_blocking_operation
1103+
// CASE_B (works): operation = get_blocking_operation(blocking_operation)
1104+
rb_fiber_scheduler_blocking_operation_t *operation = NULL; // get_blocking_operation(blocking_operation);
11081105

1109-
VALUE result = rb_funcall(scheduler, id_blocking_operation_wait, 1, blocking_operation);
1106+
// Read [rsp+0x10] directly before rb_funcall so we know what was there:
1107+
VALUE rsp_slot_before;
1108+
__asm__ volatile ("mov 0x10(%%rsp), %0" : "=r"(rsp_slot_before));
1109+
fprintf(stderr, "BEFORE funcall: blocking_operation=%p rsp+0x10=%p\n",
1110+
(void*)blocking_operation, (void*)rsp_slot_before);
11101111

1111-
size_t gc_count_after = rb_gc_count();
1112-
size_t minor_after = rb_gc_stat(ID2SYM(rb_intern("minor_gc_count")));
1113-
size_t major_after = rb_gc_stat(ID2SYM(rb_intern("major_gc_count")));
1114-
fprintf(stderr, "after rb_funcall: gc_count=%zu minor=%zu major=%zu (delta: %zu minor, %zu major)\n",
1115-
gc_count_after, minor_after, major_after,
1116-
minor_after - minor_before, major_after - major_before);
1112+
VALUE result = rb_funcall(scheduler, id_blocking_operation_wait, 1, blocking_operation);
11171113

1118-
fprintf(stderr, "blocking_operation_wait: operation=%p, operation->status=%d\n", operation, operation->status);
1114+
// Read [rsp+0x10] again after rb_funcall returns:
1115+
VALUE rsp_slot_after;
1116+
__asm__ volatile ("mov 0x10(%%rsp), %0" : "=r"(rsp_slot_after));
1117+
fprintf(stderr, "AFTER funcall: blocking_operation=%p rsp+0x10=%p match=%d\n",
1118+
(void*)blocking_operation, (void*)rsp_slot_after,
1119+
blocking_operation == rsp_slot_after);
11191120

1120-
// Evidence suggests this fails:
11211121
operation = get_blocking_operation(blocking_operation);
1122-
fprintf(stderr, "get_blocking_operation: operation=%p, operation->status=%d\n", operation, operation->status);
11231122

11241123
// Get the operation data to check if it was executed
11251124
rb_atomic_t current_status = RUBY_ATOMIC_LOAD(operation->status);

0 commit comments

Comments
 (0)