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:
parent
3f97940252
commit
319afed20f
Notes:
git
2020-10-20 01:05:41 +09:00
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
|
static inline void
|
||||||
rb_ractor_set_current_ec(rb_ractor_t *cr, rb_execution_context_t *ec)
|
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);
|
native_tls_set(ruby_current_ec_key, ec);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (cr->threads.running_ec != ec) {
|
if (cr->threads.running_ec != ec) {
|
||||||
if (0) fprintf(stderr, "rb_ractor_set_current_ec ec:%p->%p\n",
|
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_push pthread_cleanup_push
|
||||||
#define native_cleanup_pop pthread_cleanup_pop
|
#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;
|
static pthread_key_t ruby_native_thread_key;
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
null_func(int i)
|
null_func(int i)
|
||||||
@ -561,7 +565,11 @@ null_func(int i)
|
|||||||
static rb_thread_t *
|
static rb_thread_t *
|
||||||
ruby_thread_from_native(void)
|
ruby_thread_from_native(void)
|
||||||
{
|
{
|
||||||
|
#ifdef RB_THREAD_LOCAL_SPECIFIER
|
||||||
|
return ruby_native_thread;
|
||||||
|
#else
|
||||||
return pthread_getspecific(ruby_native_thread_key);
|
return pthread_getspecific(ruby_native_thread_key);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -570,7 +578,12 @@ ruby_thread_set_native(rb_thread_t *th)
|
|||||||
if (th && th->ec) {
|
if (th && th->ec) {
|
||||||
rb_ractor_set_current_ec(th->ractor, 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;
|
return pthread_setspecific(ruby_native_thread_key, th) == 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void native_thread_init(rb_thread_t *th);
|
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;
|
if (r) condattr_monotonic = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef RB_THREAD_LOCAL_SPECIFIER
|
||||||
if (pthread_key_create(&ruby_native_thread_key, 0) == EAGAIN) {
|
if (pthread_key_create(&ruby_native_thread_key, 0) == EAGAIN) {
|
||||||
rb_bug("pthread_key_create failed (ruby_native_thread_key)");
|
rb_bug("pthread_key_create failed (ruby_native_thread_key)");
|
||||||
}
|
}
|
||||||
if (pthread_key_create(&ruby_current_ec_key, 0) == EAGAIN) {
|
if (pthread_key_create(&ruby_current_ec_key, 0) == EAGAIN) {
|
||||||
rb_bug("pthread_key_create failed (ruby_current_ec_key)");
|
rb_bug("pthread_key_create failed (ruby_current_ec_key)");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
th->thread_id = pthread_self();
|
th->thread_id = pthread_self();
|
||||||
ruby_thread_set_native(th);
|
ruby_thread_set_native(th);
|
||||||
fill_thread_id_str(th);
|
fill_thread_id_str(th);
|
||||||
|
@ -83,6 +83,14 @@ typedef struct rb_global_vm_lock_struct {
|
|||||||
int wait_yield;
|
int wait_yield;
|
||||||
} rb_global_vm_lock_t;
|
} 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;
|
typedef pthread_key_t native_tls_key_t;
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
@ -102,5 +110,20 @@ native_tls_set(native_tls_key_t key, void *ptr)
|
|||||||
rb_bug("pthread_setspecific error");
|
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 */
|
#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_initialize(rb_nativethread_cond_t *cond);
|
||||||
void rb_native_cond_destroy(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 */
|
#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
|
#define ruby_vm_redefined_flag GET_VM()->redefined_flag
|
||||||
VALUE ruby_vm_const_missing_count = 0;
|
VALUE ruby_vm_const_missing_count = 0;
|
||||||
rb_vm_t *ruby_current_vm_ptr = NULL;
|
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;
|
native_tls_key_t ruby_current_ec_key;
|
||||||
|
#endif
|
||||||
|
|
||||||
rb_event_flag_t ruby_vm_event_flags;
|
rb_event_flag_t ruby_vm_event_flags;
|
||||||
rb_event_flag_t ruby_vm_event_enabled_global_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 rb_event_flag_t ruby_vm_event_enabled_global_flags;
|
||||||
RUBY_EXTERN unsigned int ruby_vm_event_local_num;
|
RUBY_EXTERN unsigned int ruby_vm_event_local_num;
|
||||||
|
|
||||||
RUBY_EXTERN native_tls_key_t ruby_current_ec_key;
|
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
#define GET_VM() rb_current_vm()
|
#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 *
|
static inline rb_execution_context_t *
|
||||||
rb_current_execution_context(void)
|
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);
|
rb_execution_context_t *ec = native_tls_get(ruby_current_ec_key);
|
||||||
|
#endif
|
||||||
VM_ASSERT(ec != NULL);
|
VM_ASSERT(ec != NULL);
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user