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 Cvs-ghc@haskell.org http://www.haskell.org/mailman/listinfo/cvs-ghc