/* ----------------------------------------------------------------------------
- * $Id: Closures.h,v 1.3 1999/01/13 17:25:53 simonm Exp $
+ * $Id: Closures.h,v 1.26 2001/02/11 17:51:08 simonmar Exp $
+ *
+ * (c) The GHC Team, 1998-1999
*
* Closures
*
The parallel header
-------------------------------------------------------------------------- */
-#ifdef GRAN
+#ifdef PAR
typedef struct {
- W_ procs;
-} StgGranHeader;
+ /* StgWord ga; */ /* nope! global addresses are managed via a hash table */
+} StgParHeader;
#else /* !PAR */
typedef struct {
/* empty */
-} StgGranHeader;
+} StgParHeader;
#endif /* PAR */
/* -----------------------------------------------------------------------------
+ The GranSim header
+ -------------------------------------------------------------------------- */
+
+#if defined(GRAN)
+
+typedef struct {
+ StgWord procs; /* bitmask indicating on which PEs this closure resides */
+} StgGranHeader;
+
+#else /* !GRAN */
+
+typedef struct {
+ /* empty */
+} StgGranHeader;
+
+#endif /* GRAN */
+
+/* -----------------------------------------------------------------------------
The ticky-ticky header
Comment from old Ticky.h:
info tables to be @_Evacuate_1@ and @_Scavenge_1_0@.
-------------------------------------------------------------------------- */
-#ifdef TICKY
+#ifdef TICKY_TICKY
typedef struct {
- W_ updated;
+ /* old: W_ updated; */
} StgTickyHeader;
-#else /* !TICKY */
+#else /* !TICKY_TICKY */
typedef struct {
/* empty */
} StgTickyHeader;
-#endif /* TICKY */
+#endif /* TICKY_TICKY */
/* -----------------------------------------------------------------------------
The full fixed-size closure header
typedef struct {
const struct _StgInfoTable* info;
+#ifdef PROFILING
StgProfHeader prof;
- StgGranHeader par;
+#endif
+#ifdef PAR
+ StgParHeader par;
+#endif
+#ifdef GRAN
+ StgGranHeader gran;
+#endif
+#ifdef TICKY_TICKY
StgTickyHeader ticky;
+#endif
} StgHeader;
#define FIXED_HS (sizeof(StgHeader))
/* All closures follow the generic format */
-typedef struct StgClosure_ {
+struct StgClosure_ {
StgHeader header;
struct StgClosure_ *payload[0];
-} StgClosure;
+};
/* What a stroke of luck - all our mutable closures follow the same
* basic layout, with the mutable link field as the second field after
typedef struct StgMutClosure_ {
StgHeader header;
- StgPtr *padding;
+ StgWord padding;
struct StgMutClosure_ *mut_link;
struct StgClosure_ *payload[0];
} StgMutClosure;
StgHeader header;
StgWord n_args;
StgClosure *fun;
- StgPtr payload[0];
+ StgClosure *payload[0];
} StgPAP;
typedef struct {
StgHeader header;
StgWord n_args;
StgClosure *fun;
- StgPtr payload[0];
+ StgClosure *payload[0];
} StgAP_UPD;
typedef struct {
- StgHeader header;
- StgWord n_ptrs;
- StgWord n_words;
- StgWord n_instrs;
- StgPtr payload[0];
-} StgBCO;
-
-typedef struct {
StgHeader header;
StgClosure *indirectee;
} StgInd;
} StgIndOldGen;
typedef struct {
- StgHeader header;
- StgClosure *indirectee;
- StgClosure *static_link;
+ StgHeader header;
+ StgClosure *indirectee;
+ StgClosure *static_link;
+ struct _StgInfoTable *saved_info;
} StgIndStatic;
-typedef struct StgCAF_ {
- StgHeader header;
- StgClosure *body;
- StgClosure *value;
- struct StgCAF_ *link;
-} StgCAF;
-
-typedef struct {
- StgHeader header;
- struct StgTSO_ *blocking_queue;
-} StgBlackHole;
-
typedef struct {
StgHeader header;
StgWord words;
StgMutClosure *mut_link;
} StgMutVar;
+typedef struct {
+ StgHeader header;
+ StgArrWords *instrs; /* a pointer to an ArrWords */
+ StgArrWords *literals; /* a pointer to an ArrWords */
+ StgMutArrPtrs *ptrs; /* a pointer to a MutArrPtrs */
+ StgArrWords *itbls; /* a pointer to an ArrWords */
+} StgBCO;
+
+/*
+ A collective typedef for all linkable stack frames i.e.
+ StgUpdateFrame, StgSeqFrame, StgCatchFrame
+*/
+typedef struct _StgFrame {
+ StgHeader header;
+ struct _StgFrame *link;
+} StgFrame;
+
typedef struct _StgUpdateFrame {
StgHeader header;
struct _StgUpdateFrame *link;
typedef struct {
StgHeader header;
struct _StgUpdateFrame *link;
+ StgInt exceptions_blocked;
StgClosure *handler;
} StgCatchFrame;
StgAddr data; /* pointer to data in non-haskell-land */
} StgForeignObj;
+typedef struct _StgStableName {
+ StgHeader header;
+ StgWord sn;
+} StgStableName;
+
typedef struct _StgWeak { /* Weak v */
StgHeader header;
StgClosure *key;
StgClosure *value; /* v */
- StgClosure *finaliser;
+ StgClosure *finalizer;
struct _StgWeak *link;
} StgWeak;
+typedef struct _StgDeadWeak { /* Weak v */
+ StgHeader header;
+ struct _StgWeak *link;
+} StgDeadWeak;
+
/* Dynamic stack frames - these have a liveness mask in the object
* itself, rather than in the info table. Useful for generic heap
* check code.
*/
typedef struct {
- StgHeader header;
+ const struct _StgInfoTable* info;
StgWord liveness;
StgWord ret_addr;
StgWord payload[0];
StgClosure* value;
} StgMVar;
-/* Parallel FETCH_ME closures */
-#ifdef PAR
-typedef struct {
+#if defined(PAR) || defined(GRAN)
+/*
+ StgBlockingQueueElement is a ``collective type'' representing the types
+ of closures that can be found on a blocking queue: StgTSO, StgRBHSave,
+ StgBlockedFetch. (StgRBHSave can only appear at the end of a blocking
+ queue). Logically, this is a union type, but defining another struct
+ with a common layout is easier to handle in the code (same as for
+ StgMutClosures).
+ Note that in the standard setup only StgTSOs can be on a blocking queue.
+ This is one of the main reasons for slightly different code in files
+ such as Schedule.c.
+*/
+typedef struct StgBlockingQueueElement_ {
+ StgHeader header;
+ struct StgBlockingQueueElement_ *link; /* next elem in BQ */
+ StgMutClosure *mut_link; /* next elem in mutable list */
+ struct StgClosure_ *payload[0];/* contents of the closure */
+} StgBlockingQueueElement;
+
+/* only difference to std code is type of the elem in the BQ */
+typedef struct StgBlockingQueue_ {
+ StgHeader header;
+ struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
+ StgMutClosure *mut_link; /* next elem in mutable list */
+} StgBlockingQueue;
+
+/* this closure is hanging at the end of a blocking queue in (see RBH.c) */
+typedef struct StgRBHSave_ {
StgHeader header;
- void *ga; /* type globalAddr is abstract here */
+ StgClosure *payload[0]; /* 2 words ripped out of the guts of the */
+} StgRBHSave; /* closure holding the blocking queue */
+
+typedef struct StgRBH_ {
+ StgHeader header;
+ struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
+ StgMutClosure *mut_link; /* next elem in mutable list */
+} StgRBH;
+
+#else
+
+typedef struct StgBlockingQueue_ {
+ StgHeader header;
+ struct StgTSO_ *blocking_queue;
+ StgMutClosure *mut_link;
+} StgBlockingQueue;
+
+#endif
+
+#if defined(PAR)
+/* global indirections aka FETCH_ME closures */
+typedef struct StgFetchMe_ {
+ StgHeader header;
+ globalAddr *ga; /* ptr to unique id for a closure */
+ StgMutClosure *mut_link; /* next elem in mutable list */
} StgFetchMe;
+
+/* same contents as an ordinary StgBlockingQueue */
+typedef struct StgFetchMeBlockingQueue_ {
+ StgHeader header;
+ struct StgBlockingQueueElement_ *blocking_queue; /* start of the BQ */
+ StgMutClosure *mut_link; /* next elem in mutable list */
+} StgFetchMeBlockingQueue;
+
+/* This is an entry in a blocking queue. It indicates a fetch request from a
+ TSO on another PE demanding the value of this closur. Note that a
+ StgBlockedFetch can only occur in a BQ. Once the node is evaluated and
+ updated with the result, the result will be sent back (the PE is encoded
+ in the globalAddr) and the StgBlockedFetch closure will be nuked.
+*/
+typedef struct StgBlockedFetch_ {
+ StgHeader header;
+ struct StgBlockingQueueElement_ *link; /* next elem in the BQ */
+ StgMutClosure *mut_link; /* next elem in mutable list */
+ StgClosure *node; /* node to fetch */
+ globalAddr ga; /* where to send the result to */
+} StgBlockedFetch; /* NB: not just a ptr to a GA */
#endif
#endif /* CLOSURES_H */