From 25cc1d1f2d9bf9a83725e49884bd83ab35000e3e Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 21 Feb 2006 16:37:11 +0000 Subject: [PATCH] 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. --- ghc/includes/Storage.h | 1 + ghc/rts/PrimOps.cmm | 4 ++-- ghc/rts/Storage.c | 7 ++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ghc/includes/Storage.h b/ghc/includes/Storage.h index a04a411..46081ad 100644 --- a/ghc/includes/Storage.h +++ b/ghc/includes/Storage.h @@ -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) diff --git a/ghc/rts/PrimOps.cmm b/ghc/rts/PrimOps.cmm index 7d57092..2e81c1a 100644 --- a/ghc/rts/PrimOps.cmm +++ b/ghc/rts/PrimOps.cmm @@ -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); diff --git a/ghc/rts/Storage.c b/ghc/rts/Storage.c index 195f410..ef58c1f 100644 --- a/ghc/rts/Storage.c +++ b/ghc/rts/Storage.c @@ -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 */ -- 1.7.10.4