@@ -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