mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	thread_pthread.c: reset timeslice delay when uncontended
This matches the behavior of old timer thread more closely and seems to fix [Bug #14999] when limited to a single CPU. I cannot reproduce the error on a multi-core system unless I use schedtool to force affinity to a single CPU: schedtool -a 0x01 -e make test-spec \ MSPECOPT='-R1000 spec/ruby/library/conditionvariable/wait_spec.rb' While it may be good enough to pass the spec, I don't have huge degree of confidence in the interrupt handling robustness under extremely heavy load (these may be ancient bugs, though). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64467 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									77038f9f82
								
							
						
					
					
						commit
						d2afeb9445
					
				
					 2 changed files with 7 additions and 3 deletions
				
			
		|  | @ -180,19 +180,18 @@ static void | |||
| do_gvl_timer(rb_vm_t *vm, rb_thread_t *th) | ||||
| { | ||||
|     static struct timespec ts; | ||||
|     static int err = ETIMEDOUT; | ||||
|     native_thread_data_t *nd = &th->native_thread_data; | ||||
| 
 | ||||
|     /* take over wakeups from UBF_TIMER */ | ||||
|     ubf_timer_disarm(); | ||||
| 
 | ||||
|     if (err == ETIMEDOUT) { | ||||
|     if (vm->gvl.timer_err == ETIMEDOUT) { | ||||
|         ts.tv_sec = 0; | ||||
|         ts.tv_nsec = TIME_QUANTUM_NSEC; | ||||
|         ts = native_cond_timeout(&nd->cond.gvlq, ts); | ||||
|     } | ||||
|     vm->gvl.timer = th; | ||||
|     err = native_cond_timedwait(&nd->cond.gvlq, &vm->gvl.lock, &ts); | ||||
|     vm->gvl.timer_err = native_cond_timedwait(&nd->cond.gvlq, &vm->gvl.lock, &ts); | ||||
|     vm->gvl.timer = 0; | ||||
| 
 | ||||
|     ubf_wakeup_all_threads(); | ||||
|  | @ -244,6 +243,9 @@ gvl_acquire_common(rb_vm_t *vm, rb_thread_t *th) | |||
|             rb_native_cond_signal(&vm->gvl.switch_cond); | ||||
|         } | ||||
|     } | ||||
|     else { /* reset timer if uncontended */ | ||||
|         vm->gvl.timer_err = ETIMEDOUT; | ||||
|     } | ||||
|     vm->gvl.acquired = th; | ||||
|     if (!vm->gvl.timer) { | ||||
|         if (!designate_timer_thread(vm) && !ubf_threads_empty()) { | ||||
|  | @ -325,6 +327,7 @@ gvl_init(rb_vm_t *vm) | |||
|     list_head_init(&vm->gvl.waitq); | ||||
|     vm->gvl.acquired = 0; | ||||
|     vm->gvl.timer = 0; | ||||
|     vm->gvl.timer_err = ETIMEDOUT; | ||||
|     vm->gvl.need_yield = 0; | ||||
|     vm->gvl.wait_yield = 0; | ||||
| } | ||||
|  |  | |||
|  | @ -53,6 +53,7 @@ typedef struct rb_global_vm_lock_struct { | |||
|     /* slow path */ | ||||
|     struct list_head waitq; | ||||
|     const struct rb_thread_struct *timer; | ||||
|     int timer_err; | ||||
| 
 | ||||
|     /* yield */ | ||||
|     rb_nativethread_cond_t switch_cond; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 normal
						normal