summaryrefslogtreecommitdiff
path: root/includes/rts/storage
diff options
context:
space:
mode:
Diffstat (limited to 'includes/rts/storage')
-rw-r--r--includes/rts/storage/Closures.h14
-rw-r--r--includes/rts/storage/GC.h10
-rw-r--r--includes/rts/storage/SMPClosureOps.h77
3 files changed, 74 insertions, 27 deletions
diff --git a/includes/rts/storage/Closures.h b/includes/rts/storage/Closures.h
index 2302b7d2a1..09e702149a 100644
--- a/includes/rts/storage/Closures.h
+++ b/includes/rts/storage/Closures.h
@@ -80,7 +80,7 @@ typedef struct {
typedef struct StgClosure_ {
StgHeader header;
struct StgClosure_ *payload[FLEXIBLE_ARRAY];
-} *StgClosurePtr; // StgClosure defined in Rts.h
+} *StgClosurePtr; // StgClosure defined in rts/Types.h
typedef struct {
StgThunkHeader header;
@@ -191,17 +191,21 @@ typedef struct _StgStableName {
typedef struct _StgWeak { /* Weak v */
StgHeader header;
- StgClosure *cfinalizer;
+ StgClosure *cfinalizers;
StgClosure *key;
StgClosure *value; /* v */
StgClosure *finalizer;
struct _StgWeak *link;
} StgWeak;
-typedef struct _StgDeadWeak { /* Weak v */
+typedef struct _StgCFinalizerList {
StgHeader header;
- struct _StgWeak *link;
-} StgDeadWeak;
+ StgClosure *link;
+ void (*fptr)(void);
+ void *ptr;
+ void *eptr;
+ StgWord flag; /* has environment (0 or 1) */
+} StgCFinalizerList;
/* Byte code objects. These are fixed size objects with pointers to
* four arrays, designed so that a BCO can be easily "re-linked" to
diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h
index 80f11d3ee1..fb5e21e832 100644
--- a/includes/rts/storage/GC.h
+++ b/includes/rts/storage/GC.h
@@ -83,6 +83,8 @@ typedef struct generation_ {
StgTSO * threads; // threads in this gen
// linked via global_link
+ StgWeak * weak_ptr_list; // weak pointers in this gen
+
struct generation_ *to; // destination gen for live objects
// stats information
@@ -116,6 +118,7 @@ typedef struct generation_ {
bdescr * bitmap; // bitmap for compacting collection
StgTSO * old_threads;
+ StgWeak * old_weak_ptr_list;
} generation;
extern generation * generations;
@@ -154,8 +157,11 @@ StgPtr allocate ( Capability *cap, W_ n );
StgPtr allocatePinned ( Capability *cap, W_ n );
/* memory allocator for executable memory */
-void * allocateExec(W_ len, void **exec_addr);
-void freeExec (void *p);
+typedef void* AdjustorWritable;
+typedef void* AdjustorExecutable;
+
+AdjustorWritable allocateExec(W_ len, AdjustorExecutable *exec_addr);
+void freeExec (AdjustorExecutable p);
// Used by GC checks in external .cmm code:
extern W_ large_alloc_lim;
diff --git a/includes/rts/storage/SMPClosureOps.h b/includes/rts/storage/SMPClosureOps.h
index 39349874f7..a8ebb5d0ed 100644
--- a/includes/rts/storage/SMPClosureOps.h
+++ b/includes/rts/storage/SMPClosureOps.h
@@ -11,13 +11,27 @@
#ifdef CMINUSMINUS
+/* Lock closure, equivalent to ccall lockClosure but the condition is inlined.
+ * Arguments are swapped for uniformity with unlockClosure. */
+#if defined(THREADED_RTS)
+#define LOCK_CLOSURE(closure, info) \
+ if (CInt[n_capabilities] == 1 :: CInt) { \
+ info = GET_INFO(closure); \
+ } else { \
+ ("ptr" info) = ccall reallyLockClosure(closure "ptr"); \
+ }
+#else
+#define LOCK_CLOSURE(closure, info) info = GET_INFO(closure)
+#endif
+
#define unlockClosure(ptr,info) \
prim_write_barrier; \
- StgHeader_info(ptr) = info;
+ StgHeader_info(ptr) = info;
#else
-EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p);
+INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p);
+EXTERN_INLINE StgInfoTable *reallyLockClosure(StgClosure *p);
EXTERN_INLINE StgInfoTable *tryLockClosure(StgClosure *p);
EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info);
@@ -29,35 +43,58 @@ EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info);
* This is used primarily in the implementation of MVars.
* -------------------------------------------------------------------------- */
-// We want a callable copy of lockClosure() so that we can refer to it
-// from .cmm files compiled using the native codegen.
-EXTERN_INLINE StgInfoTable *lockClosure(StgClosure *p)
+// We want a callable copy of reallyLockClosure() so that we can refer to it
+// from .cmm files compiled using the native codegen, so these are given
+// EXTERN_INLINE. C-- should use LOCK_CLOSURE not lockClosure, so we've
+// kept it INLINE_HEADER.
+EXTERN_INLINE StgInfoTable *reallyLockClosure(StgClosure *p)
{
StgWord info;
do {
- nat i = 0;
- do {
- info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
- if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
- } while (++i < SPIN_COUNT);
- yieldThread();
+ nat i = 0;
+ do {
+ info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ if (info != (W_)&stg_WHITEHOLE_info) return (StgInfoTable *)info;
+ } while (++i < SPIN_COUNT);
+ yieldThread();
} while (1);
}
+INLINE_HEADER StgInfoTable *lockClosure(StgClosure *p)
+{
+ if (n_capabilities == 1) {
+ return (StgInfoTable *)p->header.info;
+ }
+ else {
+ return reallyLockClosure(p);
+ }
+}
+
+// ToDo: consider splitting tryLockClosure into reallyTryLockClosure,
+// same as lockClosure
EXTERN_INLINE StgInfoTable *tryLockClosure(StgClosure *p)
{
StgWord info;
- info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
- if (info != (W_)&stg_WHITEHOLE_info) {
- return (StgInfoTable *)info;
- } else {
- return NULL;
+ if (n_capabilities == 1) {
+ return (StgInfoTable *)p->header.info;
+ }
+ else {
+ info = xchg((P_)(void *)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ if (info != (W_)&stg_WHITEHOLE_info) {
+ return (StgInfoTable *)info;
+ } else {
+ return NULL;
+ }
}
}
#else /* !THREADED_RTS */
EXTERN_INLINE StgInfoTable *
+reallyLockClosure(StgClosure *p)
+{ return (StgInfoTable *)p->header.info; }
+
+INLINE_HEADER StgInfoTable *
lockClosure(StgClosure *p)
{ return (StgInfoTable *)p->header.info; }
@@ -75,12 +112,12 @@ EXTERN_INLINE void unlockClosure(StgClosure *p, const StgInfoTable *info)
}
// Handy specialised versions of lockClosure()/unlockClosure()
-EXTERN_INLINE void lockTSO(StgTSO *tso);
-EXTERN_INLINE void lockTSO(StgTSO *tso)
+INLINE_HEADER void lockTSO(StgTSO *tso);
+INLINE_HEADER void lockTSO(StgTSO *tso)
{ lockClosure((StgClosure *)tso); }
-EXTERN_INLINE void unlockTSO(StgTSO *tso);
-EXTERN_INLINE void unlockTSO(StgTSO *tso)
+INLINE_HEADER void unlockTSO(StgTSO *tso);
+INLINE_HEADER void unlockTSO(StgTSO *tso)
{ unlockClosure((StgClosure*)tso, (const StgInfoTable *)&stg_TSO_info); }
#endif /* CMINUSMINUS */