Commit 25cc1d1f authored by Simon Marlow's avatar Simon Marlow
Browse files

fix a deadlock in atomicModifyMutVar#

atomicModifyMutVar# was re-using the storage manager mutex (sm_mutex)
to get its atomicity guarantee in SMP mode. But recently the addition
of a call to dirty_MUT_VAR() to implement the read barrier lead to a
rare deadlock case, because dirty_MUT_VAR() very occasionally needs to
allocate a new block to chain on the mutable list, which requires
sm_mutex.
parent 5d9f7faf
......@@ -200,6 +200,7 @@ extern void GarbageCollect(void (*get_roots)(evac_fn),rtsBool force_major_gc);
*/
#if defined(THREADED_RTS)
extern Mutex sm_mutex;
extern Mutex atomic_modify_mutvar_mutex;
#endif
#if defined(THREADED_RTS)
......
......@@ -207,7 +207,7 @@ atomicModifyMutVarzh_fast
HP_CHK_GEN_TICKY(SIZE, R1_PTR & R2_PTR, atomicModifyMutVarzh_fast);
#if defined(THREADED_RTS)
foreign "C" ACQUIRE_LOCK(sm_mutex "ptr") [R1,R2];
foreign "C" ACQUIRE_LOCK(atomic_modify_mutvar_mutex "ptr") [R1,R2];
#endif
x = StgMutVar_var(R1);
......@@ -238,7 +238,7 @@ atomicModifyMutVarzh_fast
StgThunk_payload(r,0) = z;
#if defined(THREADED_RTS)
foreign "C" RELEASE_LOCK(sm_mutex "ptr") [];
foreign "C" RELEASE_LOCK(atomic_modify_mutvar_mutex "ptr") [];
#endif
RET_P(r);
......
......@@ -51,14 +51,19 @@ ullong total_allocated = 0; /* total memory allocated during run */
nat n_nurseries = 0; /* == RtsFlags.ParFlags.nNodes, convenience */
step *nurseries = NULL; /* array of nurseries, >1 only if THREADED_RTS */
#ifdef THREADED_RTS
/*
* Storage manager mutex: protects all the above state from
* simultaneous access by two STG threads.
*/
#ifdef THREADED_RTS
Mutex sm_mutex;
/*
* This mutex is used by atomicModifyMutVar# only
*/
Mutex atomic_modify_mutvar_mutex;
#endif
/*
* Forward references
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment