mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	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 
				
			
			
			
		
		
					 6 changed files with 78 additions and 2 deletions
				
			
		
							
								
								
									
										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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue