Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Oct 1998 18:24:42 +0400
From:      Dmitrij Tejblum <tejblum@arc.hq.cti.ru>
To:        "Richard Seaman, Jr." <lists@tar.com>
Cc:        "HighWind Software Information" <info@highwind.com>, "current@freebsd.org" <current@FreeBSD.ORG>
Subject:   Re: Another Serious libc_r problem 
Message-ID:  <199810201424.SAA29616@arc.hq.cti.ru>
In-Reply-To: Your message of "Tue, 20 Oct 1998 08:30:30 CDT." <199810201330.IAA09508@ns.tar.com> 

next in thread | previous in thread | raw e-mail | index | archive | help

> On Tue, 20 Oct 98 08:01:12 -0500, Richard Seaman, Jr. wrote:
> 
> >I will try to look at this later, if I have time.  However, there are
> >others who know a lot more about this than I do who could probably
> >do a better fix.
> 
> You could try the following patch.  However, someone else should look at
> it too before its committed.

Heh. I was just about post a very similar patch when received your posting. 
I think, howewer, that your patch is slightly wrong, so I will post mine 
anyway. As far as I understand, it is better to do pthread_mutex_unlock and 
_thread_queue_enc under same _SPINLOCK. (I'm afraid, there is still some 
races in this code).

Here is my patch:

*** uthread_cond.c	Tue Oct 20 13:55:49 1998
--- uthread_cond.c	Tue Oct 20 14:14:55 1998
***************
*** 137,149 ****
  	 */
  	else if (*cond != NULL ||
  	    (rval = pthread_cond_init(cond,NULL)) == 0) {
- 		/* Lock the condition variable structure: */
- 		_SPINLOCK(&(*cond)->lock);
- 
  		/* Process according to condition variable type: */
  		switch ((*cond)->c_type) {
  		/* Fast condition variable: */
  		case COND_TYPE_FAST:
  			/*
  			 * Queue the running thread for the condition
  			 * variable:
--- 137,152 ----
  	 */
  	else if (*cond != NULL ||
  	    (rval = pthread_cond_init(cond,NULL)) == 0) {
  		/* Process according to condition variable type: */
  		switch ((*cond)->c_type) {
  		/* Fast condition variable: */
  		case COND_TYPE_FAST:
+ 			/* Wait forever: */
+ 			_thread_run->wakeup_time.tv_sec = -1;
+ 
+ 			/* Lock the condition variable structure: */
+ 			_SPINLOCK(&(*cond)->lock);
+ 
  			/*
  			 * Queue the running thread for the condition
  			 * variable:
***************
*** 151,173 ****
  			_thread_queue_enq(&(*cond)->c_queue, _thread_run);
  
  			/* Unlock the mutex: */
! 			pthread_mutex_unlock(mutex);
! 
! 			/* Wait forever: */
! 			_thread_run->wakeup_time.tv_sec = -1;
! 
! 			/* Unlock the condition variable structure: */
! 			_SPINUNLOCK(&(*cond)->lock);
  
! 			/* Schedule the next thread: */
! 			_thread_kern_sched_state(PS_COND_WAIT,
! 			    __FILE__, __LINE__);
  
! 			/* Lock the condition variable structure: */
! 			_SPINLOCK(&(*cond)->lock);
  
! 			/* Lock the mutex: */
! 			rval = pthread_mutex_lock(mutex);
  			break;
  
  		/* Trap invalid condition variable types: */
--- 154,180 ----
  			_thread_queue_enq(&(*cond)->c_queue, _thread_run);
  
  			/* Unlock the mutex: */
! 			if ((rval = pthread_mutex_unlock(mutex)) != 0) {
! 				/*
! 				 * Cannot unlock the mutex, so remove the
! 				 * running thread from the condition
! 				 * variable queue: 
! 				 */
! 				_thread_queue_deq(&(*cond)->c_queue);
  
! 				/* Unlock the condition variable structure: */
! 				_SPINUNLOCK(&(*cond)->lock);
! 			} else {
! 				/* Unlock the condition variable structure: */
! 				_SPINUNLOCK(&(*cond)->lock);
  
! 				/* Schedule the next thread: */
! 				_thread_kern_sched_state(PS_COND_WAIT,
! 				    __FILE__, __LINE__);
  
! 				/* Lock the mutex: */
! 				rval = pthread_mutex_lock(mutex);
! 			}
  			break;
  
  		/* Trap invalid condition variable types: */
***************
*** 177,184 ****
  			break;
  		}
  
- 	/* Unlock the condition variable structure: */
- 	_SPINUNLOCK(&(*cond)->lock);
  	}
  
  	/* Return the completion status: */
--- 184,189 ----
***************
*** 201,209 ****
  	 */
  	else if (*cond != NULL ||
  	    (rval = pthread_cond_init(cond,NULL)) == 0) {
- 		/* Lock the condition variable structure: */
- 		_SPINLOCK(&(*cond)->lock);
- 
  		/* Process according to condition variable type: */
  		switch ((*cond)->c_type) {
  		/* Fast condition variable: */
--- 206,211 ----
***************
*** 215,220 ****
--- 217,225 ----
  			/* Reset the timeout flag: */
  			_thread_run->timeout = 0;
  
+ 			/* Lock the condition variable structure: */
+ 			_SPINLOCK(&(*cond)->lock);
+ 
  			/*
  			 * Queue the running thread for the condition
  			 * variable:
***************
*** 229,234 ****
--- 234,242 ----
  				 * variable queue: 
  				 */
  				_thread_queue_deq(&(*cond)->c_queue);
+ 
+ 				/* Unlock the condition variable structure: */
+ 				_SPINUNLOCK(&(*cond)->lock);
  			} else {
  				/* Unlock the condition variable structure: */
  				_SPINUNLOCK(&(*cond)->lock);
***************
*** 237,245 ****
  				_thread_kern_sched_state(PS_COND_WAIT,
  				    __FILE__, __LINE__);
  
- 				/* Lock the condition variable structure: */
- 				_SPINLOCK(&(*cond)->lock);
- 
  				/* Lock the mutex: */
  				if ((rval = pthread_mutex_lock(mutex)) != 0) {
  				}
--- 245,250 ----
***************
*** 258,265 ****
  			break;
  		}
  
- 	/* Unlock the condition variable structure: */
- 	_SPINUNLOCK(&(*cond)->lock);
  	}
  
  	/* Return the completion status: */
--- 263,268 ----





To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199810201424.SAA29616>