зеркало из https://github.com/github/ruby.git
Use language TLS specifier if it is possible.
To access TLS, it is faster to use language TLS specifier instead of using pthread_get/setspecific functions. Original proposal is: Use native thread locals. #3665
This commit is contained in:
Родитель
3f97940252
Коммит
319afed20f
8
ractor.h
8
ractor.h
|
@ -205,7 +205,15 @@ rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th)
|
|||
static inline void
|
||||
rb_ractor_set_current_ec(rb_ractor_t *cr, rb_execution_context_t *ec)
|
||||
{
|
||||
#ifdef RB_THREAD_LOCAL_SPECIFIER
|
||||
#if __APPLE__
|
||||
rb_current_ec_set(ec);
|
||||
#else
|
||||
ruby_current_ec = ec;
|
||||
#endif
|
||||
#else
|
||||
native_tls_set(ruby_current_ec_key, ec);
|
||||
#endif
|
||||
|
||||
if (cr->threads.running_ec != ec) {
|
||||
if (0) fprintf(stderr, "rb_ractor_set_current_ec ec:%p->%p\n",
|
||||
|
|
|
@ -550,7 +550,11 @@ native_cond_timeout(rb_nativethread_cond_t *cond, const rb_hrtime_t rel)
|
|||
#define native_cleanup_push pthread_cleanup_push
|
||||
#define native_cleanup_pop pthread_cleanup_pop
|
||||
|
||||
#ifdef RB_THREAD_LOCAL_SPECIFIER
|
||||
static RB_THREAD_LOCAL_SPECIFIER rb_thread_t *ruby_native_thread;
|
||||
#else
|
||||
static pthread_key_t ruby_native_thread_key;
|
||||
#endif
|
||||
|
||||
static void
|
||||
null_func(int i)
|
||||
|
@ -561,7 +565,11 @@ null_func(int i)
|
|||
static rb_thread_t *
|
||||
ruby_thread_from_native(void)
|
||||
{
|
||||
#ifdef RB_THREAD_LOCAL_SPECIFIER
|
||||
return ruby_native_thread;
|
||||
#else
|
||||
return pthread_getspecific(ruby_native_thread_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -570,7 +578,12 @@ ruby_thread_set_native(rb_thread_t *th)
|
|||
if (th && th->ec) {
|
||||
rb_ractor_set_current_ec(th->ractor, th->ec);
|
||||
}
|
||||
#ifdef RB_THREAD_LOCAL_SPECIFIER
|
||||
ruby_native_thread = th;
|
||||
return 1;
|
||||
#else
|
||||
return pthread_setspecific(ruby_native_thread_key, th) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void native_thread_init(rb_thread_t *th);
|
||||
|
@ -587,12 +600,15 @@ Init_native_thread(rb_thread_t *th)
|
|||
if (r) condattr_monotonic = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RB_THREAD_LOCAL_SPECIFIER
|
||||
if (pthread_key_create(&ruby_native_thread_key, 0) == EAGAIN) {
|
||||
rb_bug("pthread_key_create failed (ruby_native_thread_key)");
|
||||
}
|
||||
if (pthread_key_create(&ruby_current_ec_key, 0) == EAGAIN) {
|
||||
rb_bug("pthread_key_create failed (ruby_current_ec_key)");
|
||||
}
|
||||
#endif
|
||||
th->thread_id = pthread_self();
|
||||
ruby_thread_set_native(th);
|
||||
fill_thread_id_str(th);
|
||||
|
|
|
@ -83,6 +83,14 @@ typedef struct rb_global_vm_lock_struct {
|
|||
int wait_yield;
|
||||
} rb_global_vm_lock_t;
|
||||
|
||||
|
||||
#if __STDC_VERSION__ >= 201112
|
||||
#define RB_THREAD_LOCAL_SPECIFIER _Thread_local
|
||||
#elif defined(__GNUC__)
|
||||
/* note that ICC (linux) and Clang are covered by __GNUC__ */
|
||||
#define RB_THREAD_LOCAL_SPECIFIER __thread
|
||||
#else
|
||||
|
||||
typedef pthread_key_t native_tls_key_t;
|
||||
|
||||
static inline void *
|
||||
|
@ -102,5 +110,20 @@ native_tls_set(native_tls_key_t key, void *ptr)
|
|||
rb_bug("pthread_setspecific error");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
#ifdef RB_THREAD_LOCAL_SPECIFIER
|
||||
#if __APPLE__
|
||||
// on Darwin, TLS can not be accessed across .so
|
||||
struct rb_execution_context_struct *rb_current_ec();
|
||||
void rb_current_ec_set(struct rb_execution_context_struct *);
|
||||
#else
|
||||
RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct *ruby_current_ec;
|
||||
#endif
|
||||
#else
|
||||
RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
|
||||
#endif
|
||||
RUBY_SYMBOL_EXPORT_END
|
||||
|
||||
#endif /* RUBY_THREAD_PTHREAD_H */
|
||||
|
|
|
@ -63,4 +63,8 @@ void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock
|
|||
void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
|
||||
void rb_native_cond_destroy(rb_nativethread_cond_t *cond);
|
||||
|
||||
RUBY_SYMBOL_EXPORT_BEGIN
|
||||
RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
|
||||
RUBY_SYMBOL_EXPORT_END
|
||||
|
||||
#endif /* RUBY_THREAD_WIN32_H */
|
||||
|
|
19
vm.c
19
vm.c
|
@ -379,7 +379,26 @@ VALUE rb_block_param_proxy;
|
|||
#define ruby_vm_redefined_flag GET_VM()->redefined_flag
|
||||
VALUE ruby_vm_const_missing_count = 0;
|
||||
rb_vm_t *ruby_current_vm_ptr = NULL;
|
||||
|
||||
#ifdef RB_THREAD_LOCAL_SPECIFIER
|
||||
RB_THREAD_LOCAL_SPECIFIER rb_execution_context_t *ruby_current_ec;
|
||||
|
||||
#ifdef __APPLE__
|
||||
rb_execution_context_t *
|
||||
rb_current_ec(void)
|
||||
{
|
||||
return ruby_current_ec;
|
||||
}
|
||||
void
|
||||
rb_current_ec_set(rb_execution_context_t *ec)
|
||||
{
|
||||
ruby_current_ec = ec;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
native_tls_key_t ruby_current_ec_key;
|
||||
#endif
|
||||
|
||||
rb_event_flag_t ruby_vm_event_flags;
|
||||
rb_event_flag_t ruby_vm_event_enabled_global_flags;
|
||||
|
|
10
vm_core.h
10
vm_core.h
|
@ -1721,8 +1721,6 @@ RUBY_EXTERN rb_event_flag_t ruby_vm_event_flags;
|
|||
RUBY_EXTERN rb_event_flag_t ruby_vm_event_enabled_global_flags;
|
||||
RUBY_EXTERN unsigned int ruby_vm_event_local_num;
|
||||
|
||||
RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
|
||||
|
||||
RUBY_SYMBOL_EXPORT_END
|
||||
|
||||
#define GET_VM() rb_current_vm()
|
||||
|
@ -1764,7 +1762,15 @@ rb_ec_vm_ptr(const rb_execution_context_t *ec)
|
|||
static inline rb_execution_context_t *
|
||||
rb_current_execution_context(void)
|
||||
{
|
||||
#ifdef RB_THREAD_LOCAL_SPECIFIER
|
||||
#if __APPLE__
|
||||
rb_execution_context_t *ec = rb_current_ec();
|
||||
#else
|
||||
rb_execution_context_t *ec = ruby_current_ec;
|
||||
#endif
|
||||
#else
|
||||
rb_execution_context_t *ec = native_tls_get(ruby_current_ec_key);
|
||||
#endif
|
||||
VM_ASSERT(ec != NULL);
|
||||
return ec;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче