@@ -105,7 +105,7 @@ static gvl_hook_t * rb_gvl_hooks = NULL;
105
105
static pthread_rwlock_t rb_gvl_hooks_rw_lock = PTHREAD_RWLOCK_INITIALIZER ;
106
106
107
107
gvl_hook_t *
108
- rb_gvl_event_new (void * callback , uint32_t event ) {
108
+ rb_gvl_event_new (void * callback , rb_event_flag_t event ) {
109
109
gvl_hook_t * hook = ALLOC_N (gvl_hook_t , 1 );
110
110
hook -> callback = callback ;
111
111
hook -> event = event ;
@@ -155,25 +155,21 @@ rb_gvl_event_delete(gvl_hook_t * hook) {
155
155
}
156
156
157
157
void
158
- rb_gvl_execute_hooks (uint32_t event ) {
159
- if (!rb_gvl_hooks ) {
160
- return ;
161
- }
162
-
158
+ rb_gvl_execute_hooks (rb_event_flag_t event , unsigned long waiting ) {
163
159
if (pthread_rwlock_rdlock (& rb_gvl_hooks_rw_lock )) {
164
160
// TODO: better way to deal with error?
165
161
return ;
166
162
}
167
163
168
- gvl_hook_t * h = rb_gvl_hooks ;
169
- struct gvl_hook_event_args args = {} ;
170
-
171
- do {
172
- if (h -> event & event ) {
173
- (* h -> callback )(event , args );
174
- }
175
- } while ((h = h -> next ));
176
-
164
+ if ( rb_gvl_hooks ) {
165
+ gvl_hook_t * h = rb_gvl_hooks ;
166
+ gvl_hook_event_args_t args = { . waiting = waiting };
167
+ do {
168
+ if (h -> event & event ) {
169
+ (* h -> callback )(event , args );
170
+ }
171
+ } while ((h = h -> next ));
172
+ }
177
173
pthread_rwlock_unlock (& rb_gvl_hooks_rw_lock );
178
174
}
179
175
@@ -366,6 +362,10 @@ gvl_acquire_common(rb_global_vm_lock_t *gvl, rb_thread_t *th)
366
362
"we must not be in ubf_list and GVL waitq at the same time" );
367
363
368
364
list_add_tail (& gvl -> waitq , & nd -> node .gvl );
365
+ gvl -> waiting ++ ;
366
+ if (rb_gvl_hooks ) {
367
+ rb_gvl_execute_hooks (RUBY_INTERNAL_EVENT_GVL_ACQUIRE_ENTER , gvl -> waiting );
368
+ }
369
369
370
370
do {
371
371
if (!gvl -> timer ) {
@@ -377,6 +377,7 @@ gvl_acquire_common(rb_global_vm_lock_t *gvl, rb_thread_t *th)
377
377
} while (gvl -> owner );
378
378
379
379
list_del_init (& nd -> node .gvl );
380
+ gvl -> waiting -- ;
380
381
381
382
if (gvl -> need_yield ) {
382
383
gvl -> need_yield = 0 ;
@@ -387,6 +388,11 @@ gvl_acquire_common(rb_global_vm_lock_t *gvl, rb_thread_t *th)
387
388
gvl -> timer_err = ETIMEDOUT ;
388
389
}
389
390
gvl -> owner = th ;
391
+
392
+ if (rb_gvl_hooks ) {
393
+ rb_gvl_execute_hooks (RUBY_INTERNAL_EVENT_GVL_ACQUIRE_EXIT , gvl -> waiting );
394
+ }
395
+
390
396
if (!gvl -> timer ) {
391
397
if (!designate_timer_thread (gvl ) && !ubf_threads_empty ()) {
392
398
rb_thread_wakeup_timer_thread (-1 );
@@ -405,6 +411,10 @@ gvl_acquire(rb_global_vm_lock_t *gvl, rb_thread_t *th)
405
411
static const native_thread_data_t *
406
412
gvl_release_common (rb_global_vm_lock_t * gvl )
407
413
{
414
+ if (rb_gvl_hooks ) {
415
+ rb_gvl_execute_hooks (RUBY_INTERNAL_EVENT_GVL_RELEASE , gvl -> waiting );
416
+ }
417
+
408
418
native_thread_data_t * next ;
409
419
gvl -> owner = 0 ;
410
420
next = list_top (& gvl -> waitq , native_thread_data_t , node .ubf );
@@ -466,6 +476,7 @@ rb_gvl_init(rb_global_vm_lock_t *gvl)
466
476
rb_native_cond_initialize (& gvl -> switch_wait_cond );
467
477
list_head_init (& gvl -> waitq );
468
478
gvl -> owner = 0 ;
479
+ gvl -> waiting = 0 ;
469
480
gvl -> timer = 0 ;
470
481
gvl -> timer_err = ETIMEDOUT ;
471
482
gvl -> need_yield = 0 ;
0 commit comments