On Sat, Jan 17, 2009 at 11:21:03PM +0000, Ian Lynagh wrote:
> OK, that mostly worked, but ffi014 timed out.
>
> It turns out that "hello world" linked with -threaded -debug deadlocks
> at:
> ASSERT_LOCK_HELD(&sched_mutex);
> at the start of newBoundTask. This is doing
> ASSERT(pthread_mutex_lock(&sched_mutex) == EDEADLK)
> which requires us to be using error-checking mutexes. However, initMutex
> says:
> void
> initMutex(Mutex* pMut)
> {
> #if defined(DEBUG)
> pthread_mutexattr_t attr;
> pthread_mutexattr_init(&attr);
> pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK_NP);
> pthread_mutex_init(pMut,&attr);
> #else
> pthread_mutex_init(pMut,NULL);
> #endif
> return;
> }
Err... whats the special meaning of PTHREAD_MUTEX_ERRORCHECK_NP?
It doesn't exist on OpenBSD and it isn't mentioned in IEEE Std
1003.1.
> so on OS X we were using the default normal/fast mutexes. OS X does have
> PTHREAD_MUTEX_ERRORCHECK (and validate passes if we use it, apart from
> hpc_ghc_ghci working on OS X), but I don't know what other OSes use, or
> if they have no equivalent.
On OpenBSD, PTHREAD_MUTEX_ERRORCHECK is the default (if you pass
NULL as the second argument to pthread_mutex_init()), and
PTHREAD_MUTEX_ERRORCHECK is mentioned in 1003.1. But see below...
> So what's the best way forward? Use PTHREAD_MUTEX_ERRORCHECK for
> non-Linux platforms, and see if anyone reports build failures? Then we
> can fix any reported failures, either by setting the appropriate type
> for that OS, or by not defining ASSERT_LOCK_HELD on that platform if
> none exists.
I think the ASSERT_LOCK_HELD is the problem, at least here on
OpenBSD. ASSERT_LOCK_HELD tries to obtain a lock on a mutex that
already is locked, and will either block or err out, depending of
the mutex type (PTHREAD_MUTEX_ERRORCHECK or PTHREAD_MUTEX_NORMAL).
It will do so even if the thread calling pthread_mutex_lock() owns
the lock on the mutex. For example, this one will block at the
second call to pthread_mutex_lock:
pthread_mutexattr_t a;
pthread_mutex_t m;
pthread_mutexattr_init(&a);
pthread_mutexattr_settype(&a, PTHREAD_MUTEX_NORMAL);
pthread_mutex_init(&m, &a);
pthread_mutex_lock(&m);
pthread_mutex_lock(&m); /* blocking here */
IMHO there's no portable and clean way to check wether you already
have a lock on a mutex or not (but I didn't yet have breakfast, so
this statement may be wrong). Regardless of wether you're trying
pthread_mutex_lock with a mutex type of PTHREAD_MUTEX_ERRORCHECK
or wether you're trying pthread_mutex_trylock (which never blocks),
you get the wrong result, at least on OpenBSD.
Even on Linux, ASSERT_LOCK_HELD may have undesired effects: if you
call it on an unlocked mutex, you will get a positive result and
at the same time have locked the mutex.
The only way to implement ASSERT_LOCK_HELD I can think at the moment
would be something like
#define ASSERT_LOCK_HELD(m) \
ASSERT(pthread_mutex_unlock(m) == 0 && pthread_mutex_lock(m) == 0)
which would introduce the risk that some other thread obtains the
lock between the two calls and causes the thread with the ASSERT
beeing blocked on pthread_mutex_lock() until the mutex is unlocked
again.
Ciao,
Kili
_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc