Date: Thu, 6 Aug 1998 17:13:02 -0400 (EDT) From: Daniel Eischen <eischen@vigrid.com> To: eischen@vigrid.com, shmit@kublai.com Cc: freebsd-current@FreeBSD.ORG Subject: Re: Pthreads woes revisited. Message-ID: <199808062113.RAA18177@pcnet1.pcnet.com>
next in thread | raw e-mail | index | archive | help
> On Thu, Aug 06, 1998 at 01:51:57PM -0400, Daniel M. Eischen wrote: > > But your not yielding the CPU after the pthread_cond_signal(). > > The waiter thread (thr_wait) should also take the mutex lock (busy) > > before the pthread_cond_wait(). See the comments in the revised > > copy of your code. > > From what I can tell by looking at uthread_mutex.c:pthread_mutex_unlock() > and uthread_cond.c:pthread_cond_wait(), I don't have to lock the mutex > before calling pthread_cond_wait(). True, the source for pthread_cond_wait ignores any error code returned by pthread_mutex_lock(). I don't know if this behaviour is defined in the POSIX spec (for whatever rev we're currently supporting), but the intended use is to acquire the mutex before the cond_wait/cond_timedwait. You're not adding the pthread_yield() call that I added after the pthread_cond_signal(). Your program is bogus because there is no guarantee that the main thread will release the CPU in order for the other task to run. You need to perform some sort of blocking operation after the pthread_cond_signal. I chose to use pthread_yield, although sleep would work just as well. Furthermore, thr_routine() will never return from the pthread_cond_wait() unless the busy mutex is available. You're main thread is taking the mutex before the sleep and releasing it after the sleep. There is no way that thr_routine can wakeup because it needs to acquire the busy mutex in order to return from the pthread_cond_wait(). Look: (from thr_routine) printf("%d: Waiting for signal.\n", (int) pthread_self ()); rc = pthread_cond_wait(&wakeup, &busy); if (rc) { fprintf(stderr, "ERROR: couldn't wait for condition: %s.\n", strerror(rc)); return NULL; } (from main) printf("MASTER: Acquiring lock.\n"); rc = pthread_mutex_lock(&busy); if (rc) { fprintf(stderr, "ERROR: couldn't lock mutex: %s.\n", strerror(rc)); return 1; } sleep(1); printf("MASTER: Releasing lock.\n"); rc = pthread_mutex_unlock(&busy); Sleeping while holding the mutex will obviously not allow the other thread to run. When the main thread returns from the sleep, it will run until its time quantum expires, preempted, or blocks (perhaps signals can affect it too?). I ran the same test on Solaris and the main thread *never* yielded the processor to the other thread until I placed a pthread_yield (sched_yield) after the pthread_cond_signal. Please try adding some sort of blocking operation after the pthread_cond_signal in the main thread. If you do not want to use pthread_yield(), then use sleep, select, or anything that will block the main thread. I suspect that you want the thread to run while the main thread is sleeping. If that is the case, then you must use another mutex in the main thread. Dan Eischen eischen@vigrid.com 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?199808062113.RAA18177>