Hold the sm_mutex around access to the mutable list.
The SMP RTS now seems quite stable, I've run my simple test program
with 64 threads without crashes.
*
* Accessing OS threads functionality in a (mostly) OS-independent
* manner.
- *
*
* --------------------------------------------------------------------------*/
+
#ifndef __OSTHREADS_H__
#define __OSTHREADS_H__
+
#if defined(RTS_SUPPORTS_THREADS) /* to the end */
# if defined(HAVE_PTHREAD_H) && !defined(WANT_NATIVE_WIN32_THREADS)
#define INIT_COND_VAR PTHREAD_COND_INITIALIZER
#ifdef LOCK_DEBUG
-#define ACQUIRE_LOCK(mutex) debugBelch("ACQUIRE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); pthread_mutex_lock(mutex)
-#define RELEASE_LOCK(mutex) debugBelch("RELEASE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); pthread_mutex_unlock(mutex)
+#define ACQUIRE_LOCK(mutex) \
+ debugBelch("ACQUIRE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); \
+ pthread_mutex_lock(mutex)
+#define RELEASE_LOCK(mutex) \
+ debugBelch("RELEASE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); \
+ pthread_mutex_unlock(mutex)
#else
#define ACQUIRE_LOCK(mutex) pthread_mutex_lock(mutex)
#define RELEASE_LOCK(mutex) pthread_mutex_unlock(mutex)
# elif defined(HAVE_WINDOWS_H)
#include <windows.h>
-#include "RtsUtils.h"
-
typedef HANDLE Condition;
typedef HANDLE Mutex;
typedef DWORD OSThreadId;
#define INIT_MUTEX_VAR 0
#define INIT_COND_VAR 0
-static inline void
+INLINE_HEADER void
ACQUIRE_LOCK(Mutex *mutex)
{
if (WaitForSingleObject(*mutex,INFINITE) == WAIT_FAILED) {
}
}
-static inline void
+INLINE_HEADER void
RELEASE_LOCK(Mutex *mutex)
{
if (ReleaseMutex(*mutex) == 0) {
#define STORAGE_H
#include <stddef.h>
+#include "OSThreads.h"
/* -----------------------------------------------------------------------------
* Generational GC
-------------------------------------------------------------------------- */
-/* ToDo: shouldn't recordMutable acquire some
- * kind of lock in the SMP case? Or do we need per-processor
- * mutable lists?
+/*
+ * Storage manager mutex
*/
+#if defined(SMP)
+extern Mutex sm_mutex;
+#define ACQUIRE_SM_LOCK ACQUIRE_LOCK(&sm_mutex);
+#define RELEASE_SM_LOCK RELEASE_LOCK(&sm_mutex);
+#else
+#define ACQUIRE_SM_LOCK
+#define RELEASE_SM_LOCK
+#endif
+
INLINE_HEADER void
recordMutableGen(StgClosure *p, generation *gen)
{
gen->mut_list = bd;
}
*bd->free++ = (StgWord)p;
+
+}
+
+INLINE_HEADER void
+recordMutableGenLock(StgClosure *p, generation *gen)
+{
+ ACQUIRE_SM_LOCK;
+ recordMutableGen(p,gen);
+ RELEASE_SM_LOCK;
}
INLINE_HEADER void
if (bd->gen_no > 0) recordMutableGen(p, &RTS_DEREF(generations)[bd->gen_no]);
}
+INLINE_HEADER void
+recordMutableLock(StgClosure *p)
+{
+ ACQUIRE_SM_LOCK;
+ recordMutable(p);
+ RELEASE_SM_LOCK;
+}
+
/* -----------------------------------------------------------------------------
The CAF table - used to let us revert CAFs in GHCi
-------------------------------------------------------------------------- */
and_then; \
} else { \
DEBUG_FILL_SLOP(p1); \
- foreign "C" recordMutableGen(p1 "ptr", \
+ foreign "C" recordMutableGenLock(p1 "ptr", \
generation(TO_W_(bdescr_gen_no(bd))) "ptr"); \
StgInd_indirectee(p1) = p2; \
SET_INFO(p1, stg_IND_OLDGEN_info); \
and_then; \
} else { \
DEBUG_FILL_SLOP(p1); \
- recordMutableGen(p1, &generations[bd->gen_no]); \
+ recordMutableGenLock(p1, &generations[bd->gen_no]); \
((StgInd *)p1)->indirectee = p2; \
SET_INFO(p1, &stg_IND_OLDGEN_info); \
TICK_UPD_OLD_IND(); \
LDV_RECORD_CREATE(p1);
TICK_UPD_NEW_PERM_IND(p1);
} else {
- recordMutableGen(p1, &generations[bd->gen_no]);
+ recordMutableGenLock(p1, &generations[bd->gen_no]);
((StgInd *)p1)->indirectee = p2;
SET_INFO(p1, &stg_IND_OLDGEN_PERM_info);
/*
-\#include ProfHeap.h \
-\#include LdvProfile.h \
-\#include Profiling.h \
- -\#include StoragePriv.h \
-\#include OSThreads.h \
-\#include Apply.h
// maintains this invariant.
//
if (%INFO_TYPE(%GET_STD_INFO(R1)) != HALF_W_(MUT_ARR_PTRS_FROZEN0)) {
- foreign "C" recordMutable(R1 "ptr");
+ foreign "C" recordMutableLock(R1 "ptr");
}
SET_INFO(R1,stg_MUT_ARR_PTRS_info);
#include "Storage.h"
#include "Schedule.h"
#include "RetainerProfile.h" // for counting memory blocks (memInventory)
-#include "StoragePriv.h"
#include <stdlib.h>
#include <string.h>
+++ /dev/null
-/* -----------------------------------------------------------------------------
- *
- * (c) The GHC Team, 1998-2005
- *
- * Storage manager bits visible to the rest of the RTS only
- *
- * ---------------------------------------------------------------------------*/
-
-#ifndef STORAGEPRIV_H
-#define STORAGEPRIV_H
-
-/*
- * Storage manager mutex
- */
-#if defined(SMP)
-extern Mutex sm_mutex;
-#define ACQUIRE_SM_LOCK ACQUIRE_LOCK(&sm_mutex)
-#define RELEASE_SM_LOCK RELEASE_LOCK(&sm_mutex)
-#else
-#define ACQUIRE_SM_LOCK
-#define RELEASE_SM_LOCK
-#endif
-
-#endif /* STORAGEPRIV_H */