This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pthread_cond_timedwait vs pthread_mutex_timedlock


But if the thread can just be woken when a condition occurs, then why is a mutex even needed?

Here is the relevant code:

shared_ptr<pthread_t> Log::TimerOn(int const sec)
{
	if (Acquire(_delay)) return _thread;
	Release(_delay, sec);
	pthread_mutex_lock(_timeout.get());
	_thread.reset(new pthread_t);
	if (!_thread || pthread_create(_thread.get(), 0, Timer, this)) Release(_delay, 0);
	return _thread;
}

bool Log::TimerOff(void)
{
	// TODO: check for values of thread, timeout, etc.
	if (!Acquire(_delay)) return true;
	Release(_delay, 0); // Timer() loop condition is _delay != 0
	timespec tDelay;
	tDelay.tv_sec = 0;
	tDelay.tv_nsec = 200000000;
	for (int i = 0; Acquire(_cycle) && i < 10; ++i) // Timer() is currently executing a Flush() while _cycle is set; give it more time
	{
		pthread_mutex_unlock(_timeout.get());
		pthread_delay_np(&tDelay);
	}
	if (Acquire(_cycle)) // Timer() thread still hasn't quit; terminate it
	{
		pthread_cancel(*_thread);
		return false;
	}
	pthread_mutex_unlock(_timeout.get());
	return true;
}

void *Log::Timer(void *obj)
{
	SetThreadName("Log timer"); // For Windows debugger
	Log *log(static_cast<Log *>(obj));
	timespec tDelay;
	tDelay.tv_nsec = 0;
	while (Acquire(log->_delay))
	{
		Release(log->_cycle, true);
		// TODO: Use relative time when pthread_mutex_timedlock_np() available
		tDelay.tv_sec = static_cast<long>(time(0)) + log->_delay;
		pthread_mutex_timedlock(log->_timeout.get(), &tDelay);
		if (log->_ind >= 0) log->Flush();
		Release(log->_cycle, false);
	}
	return 0;
}

Timer() is a static member; Acquire() and Release() just wrap volatile access and memory barriers; _thread, _lock, and _timeout are shared_ptr holding the corresponding pthread types.

> ------Original Message------
> From: Carlos O'Donell
> Sender: libc-help-owner@sourceware.org
> To: Borislav Trifonov
> Cc: libc-help@sourceware.org
> Subject: Re: pthread_cond_timedwait vs pthread_mutex_timedlock
> Sent: May 4, 2009 09:14
> 
> On Mon, May 4, 2009 at 2:15 AM, Borislav Trifonov 
> <trifonov@cs.ubc.ca> wrote:
> > It's not clear to me which one I should use. ?I have a log-
> flushing thread
> > that I need to wake every X seconds and flush the log (and 
> also wake when
> > signaled by a full log buffer or log destructor--by unlocking 
> the mutex if I
> > had used a mutex, or signaling the condition if I had used that).
> >
> > What is most important to me is to guarantee that no busy wait 
> will occur.
> >
> > A possible complication is that I need my code to build on 
> both Linux and
> > Windows, so I'm using pthreads for Win32/64 in the latter case.
> 
> You will have to determine the intersection of supported functions
> between pthreads and glibc's pthreads, and choose from that.
> 
> I would recommend pthread_cond_timedwait and pthread_cond_signal,
> since it was designed for this type of work, and it's easy to loop
> e.g. take the mutex, wait on the condition, do work, repeat, with
> another thread signaling.
> 
> I know nothing about the pthreads for Win32/64 implemenation. POSIX
> does not guarantee that an implementation will not use busy 
> waits, you
> will have to read the source code.
> 
> Any linux glibc port using NPTL (not Linuxthreads) is certainly free
> of busy waits since the primitives use kernel futexes which are
> busy-wait free.
> 
> Cheers,
> Carlos.
> 
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]