Skip to content

Commit

Permalink
[wip] Allow callbacks to be registered for GVL related events
Browse files Browse the repository at this point in the history
  • Loading branch information
eightbitraptor committed Jan 24, 2022
1 parent 374904b commit c3fa0fd
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 0 deletions.
22 changes: 22 additions & 0 deletions ext/-test-/gvl/call_without_gvl/call_without_gvl.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "ruby/ruby.h"
#include "ruby/thread.h"
#include "ruby/thread_native.h"

static void*
native_sleep_callback(void *data)
Expand Down Expand Up @@ -68,11 +69,32 @@ thread_ubf_async_safe(VALUE thread, VALUE notify_fd)
return Qnil;
}

void
ex_callback(uint32_t e, struct gvl_hook_event_args args) {
fprintf(stderr, "calling callback\n");
}

static VALUE
thread_register_gvl_callback(VALUE thread) {
rb_gvl_event_new(*ex_callback, 0x12);


return Qnil;
}

static VALUE
thread_call_gvl_callback(VALUE thread) {
rb_gvl_execute_hooks(0x12);
return Qnil;
}

void
Init_call_without_gvl(void)
{
VALUE mBug = rb_define_module("Bug");
VALUE klass = rb_define_module_under(mBug, "Thread");
rb_define_singleton_method(klass, "runnable_sleep", thread_runnable_sleep, 1);
rb_define_singleton_method(klass, "ubf_async_safe", thread_ubf_async_safe, 1);
rb_define_singleton_method(klass, "register_callback", thread_register_gvl_callback, 0);
rb_define_singleton_method(klass, "call_callbacks", thread_call_gvl_callback, 0);
}
1 change: 1 addition & 0 deletions include/ruby/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ void *rb_nogvl(void *(*func)(void *), void *data1,
*/
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_


RBIMPL_SYMBOL_EXPORT_END()

#endif /* RUBY_THREAD_H */
7 changes: 7 additions & 0 deletions include/ruby/thread_native.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,5 +201,12 @@ void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
*/
void rb_native_cond_destroy(rb_nativethread_cond_t *cond);

#include <stdint.h>
struct gvl_hook_event_args {
//
};
typedef void (*rb_gvl_callback)(uint32_t event, struct gvl_hook_event_args args);
void rb_gvl_event_new(void *callback, uint32_t event);
void rb_gvl_execute_hooks(uint32_t event);
RBIMPL_SYMBOL_EXPORT_END()
#endif
7 changes: 7 additions & 0 deletions test/-ext-/gvl/test_last_thread.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,12 @@ def test_last_thread
assert_in_delta(1.0, t, 0.16)
end;
end

def test_gvl_instrumentation
require '-test-/gvl/call_without_gvl'
Bug::Thread::register_callback

Bug::Thread::call_callbacks
end
end

31 changes: 31 additions & 0 deletions thread_pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,37 @@
# endif
#endif

static gvl_hook_t * rb_gvl_hooks = NULL;

void
rb_gvl_event_new(void *callback, uint32_t event) {
gvl_hook_t *hook = ALLOC_N(gvl_hook_t, 1);
hook->callback = callback;
hook->event = event;

if(!rb_gvl_hooks) {
rb_gvl_hooks = hook;
} else {
hook->next = rb_gvl_hooks;
rb_gvl_hooks = hook;
}
}

void
rb_gvl_execute_hooks(uint32_t event) {
if (!rb_gvl_hooks) {
return;
}
gvl_hook_t *h = rb_gvl_hooks;
struct gvl_hook_event_args args = {};

do {
if (h->event & event) {
(*h->callback)(event, args);
}
} while((h = h->next));
}

enum rtimer_state {
/* alive, after timer_create: */
RTIMER_DISARM,
Expand Down
11 changes: 11 additions & 0 deletions thread_pthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ typedef struct rb_global_vm_lock_struct {
int wait_yield;
} rb_global_vm_lock_t;

#include <stdint.h>

// TODO: this is going to be the same on Windows so move it somewhere sensible
typedef struct gvl_hook {
rb_gvl_callback callback;
uint32_t event;

struct gvl_hook *next;
} gvl_hook_t;

#include "ruby/internal/memory.h"

#if __STDC_VERSION__ >= 201112
#define RB_THREAD_LOCAL_SPECIFIER _Thread_local
Expand Down

0 comments on commit c3fa0fd

Please sign in to comment.