summaryrefslogtreecommitdiff
path: root/ghc/includes/StgMacros.lh
diff options
context:
space:
mode:
Diffstat (limited to 'ghc/includes/StgMacros.lh')
-rw-r--r--ghc/includes/StgMacros.lh265
1 files changed, 183 insertions, 82 deletions
diff --git a/ghc/includes/StgMacros.lh b/ghc/includes/StgMacros.lh
index 54352204f2..baefd8076d 100644
--- a/ghc/includes/StgMacros.lh
+++ b/ghc/includes/StgMacros.lh
@@ -54,7 +54,15 @@ Mere abbreviations:
General things; note: general-but-``machine-dependent'' macros are
given in \tr{StgMachDeps.lh}.
\begin{code}
-#define STG_MAX(a,b) (((a)>=(b)) ? (a) : (b))
+I_ STG_MAX PROTO((I_, I_)); /* GCC -Wall loves prototypes */
+
+extern STG_INLINE
+I_
+STG_MAX(I_ a, I_ b) { return((a >= b) ? a : b); }
+/* NB: the naive #define macro version of STG_MAX
+ can lead to exponential CPP explosion, if you
+ have very-nested STG_MAXes.
+*/
/*
Macros to combine two short words into a single
@@ -1012,10 +1020,10 @@ which uses these anyway.)
#if ! defined(__GNUC__) || ! defined(__STG_GCC_REGS__)
-extern void ASSIGN_DBL PROTO((W_ [], StgDouble));
-extern StgDouble PK_DBL PROTO((W_ []));
-extern void ASSIGN_FLT PROTO((W_ [], StgFloat));
-extern StgFloat PK_FLT PROTO((W_ []));
+void ASSIGN_DBL PROTO((W_ [], StgDouble));
+StgDouble PK_DBL PROTO((W_ []));
+void ASSIGN_FLT PROTO((W_ [], StgFloat));
+StgFloat PK_FLT PROTO((W_ []));
#else /* yes, its __GNUC__ && we really want them */
@@ -1036,6 +1044,12 @@ extern StgFloat PK_FLT PROTO((W_ []));
#else /* ! sparc */
+/* (not very) forward prototype declarations */
+void ASSIGN_DBL PROTO((W_ [], StgDouble));
+StgDouble PK_DBL PROTO((W_ []));
+void ASSIGN_FLT PROTO((W_ [], StgFloat));
+StgFloat PK_FLT PROTO((W_ []));
+
extern STG_INLINE
void
ASSIGN_DBL(W_ p_dest[], StgDouble src)
@@ -1291,14 +1305,14 @@ void newArrZh_init PROTO((P_ result, I_ n, P_ init));
%************************************************************************
\begin{code}
-ED_(Nil_closure);
+ED_(Prelude_Z91Z93_closure);
#define newSynchVarZh(r, hp) \
{ \
ALLOC_PRIM(MUTUPLE_HS,3,0,MUTUPLE_HS+3) /* ticky ticky */; \
CC_ALLOC(CCC,MUTUPLE_HS+3,ARR_K); /* cc prof */ \
SET_SVAR_HDR(hp,EmptySVar_info,CCC); \
- SVAR_HEAD(hp) = SVAR_TAIL(hp) = SVAR_VALUE(hp) = Nil_closure; \
+ SVAR_HEAD(hp) = SVAR_TAIL(hp) = SVAR_VALUE(hp) = Prelude_Z91Z93_closure; \
r = hp; \
}
\end{code}
@@ -1311,17 +1325,17 @@ extern void Yield PROTO((W_));
#define takeMVarZh(r, liveness, node) \
{ \
while (INFO_PTR(node) != (W_) FullSVar_info) { \
- if (SVAR_HEAD(node) == Nil_closure) \
+ if (SVAR_HEAD(node) == Prelude_Z91Z93_closure) \
SVAR_HEAD(node) = CurrentTSO; \
else \
TSO_LINK(SVAR_TAIL(node)) = CurrentTSO; \
- TSO_LINK(CurrentTSO) = (P_) Nil_closure; \
+ TSO_LINK(CurrentTSO) = (P_) Prelude_Z91Z93_closure; \
SVAR_TAIL(node) = CurrentTSO; \
DO_YIELD(liveness << 1); \
} \
SET_INFO_PTR(node, EmptySVar_info); \
r = SVAR_VALUE(node); \
- SVAR_VALUE(node) = Nil_closure; \
+ SVAR_VALUE(node) = Prelude_Z91Z93_closure; \
}
#else
@@ -1336,7 +1350,7 @@ extern void Yield PROTO((W_));
} \
SET_INFO_PTR(node, EmptySVar_info); \
r = SVAR_VALUE(node); \
- SVAR_VALUE(node) = Nil_closure; \
+ SVAR_VALUE(node) = Prelude_Z91Z93_closure; \
}
#endif
@@ -1364,18 +1378,18 @@ extern void Yield PROTO((W_));
SET_INFO_PTR(node, FullSVar_info); \
SVAR_VALUE(node) = value; \
tso = SVAR_HEAD(node); \
- if (tso != (P_) Nil_closure) { \
+ if (tso != (P_) Prelude_Z91Z93_closure) { \
if (DO_QP_PROF) \
STGCALL3(void,(void *, char *, P_, P_),QP_Event2,do_qp_prof > 1 ? "RA" : "RG",tso,CurrentTSO); \
- if (ThreadQueueHd == Nil_closure) \
+ if (ThreadQueueHd == Prelude_Z91Z93_closure) \
ThreadQueueHd = tso; \
else \
TSO_LINK(ThreadQueueTl) = tso; \
ThreadQueueTl = tso; \
SVAR_HEAD(node) = TSO_LINK(tso); \
- TSO_LINK(tso) = (P_) Nil_closure; \
- if(SVAR_HEAD(node) == (P_) Nil_closure) \
- SVAR_TAIL(node) = (P_) Nil_closure; \
+ TSO_LINK(tso) = (P_) Prelude_Z91Z93_closure; \
+ if(SVAR_HEAD(node) == (P_) Prelude_Z91Z93_closure) \
+ SVAR_TAIL(node) = (P_) Prelude_Z91Z93_closure; \
} \
}
@@ -1393,18 +1407,18 @@ extern void Yield PROTO((W_));
SET_INFO_PTR(node, FullSVar_info); \
SVAR_VALUE(node) = value; \
tso = SVAR_HEAD(node); \
- if (tso != (P_) Nil_closure) { \
+ if (tso != (P_) Prelude_Z91Z93_closure) { \
if (DO_QP_PROF) \
STGCALL3(void,(void *, char *, P_, P_),QP_Event2,do_qp_prof > 1 ? "RA" : "RG",tso,CurrentTSO); \
- if (RunnableThreadsHd == Nil_closure) \
+ if (RunnableThreadsHd == Prelude_Z91Z93_closure) \
RunnableThreadsHd = tso; \
else \
TSO_LINK(RunnableThreadsTl) = tso; \
RunnableThreadsTl = tso; \
SVAR_HEAD(node) = TSO_LINK(tso); \
- TSO_LINK(tso) = (P_) Nil_closure; \
- if(SVAR_HEAD(node) == (P_) Nil_closure) \
- SVAR_TAIL(node) = (P_) Nil_closure; \
+ TSO_LINK(tso) = (P_) Prelude_Z91Z93_closure; \
+ if(SVAR_HEAD(node) == (P_) Prelude_Z91Z93_closure) \
+ SVAR_TAIL(node) = (P_) Prelude_Z91Z93_closure; \
} \
}
@@ -1434,11 +1448,11 @@ extern void Yield PROTO((W_));
#define readIVarZh(r, liveness, node) \
{ \
if (INFO_PTR(node) != (W_) ImMutArrayOfPtrs_info) { \
- if (SVAR_HEAD(node) == Nil_closure) \
+ if (SVAR_HEAD(node) == Prelude_Z91Z93_closure) \
SVAR_HEAD(node) = CurrentTSO; \
else \
TSO_LINK(SVAR_TAIL(node)) = CurrentTSO; \
- TSO_LINK(CurrentTSO) = (P_) Nil_closure; \
+ TSO_LINK(CurrentTSO) = (P_) Prelude_Z91Z93_closure; \
SVAR_TAIL(node) = CurrentTSO; \
DO_YIELD(liveness << 1); \
} \
@@ -1481,12 +1495,12 @@ extern void Yield PROTO((W_));
EXIT(EXIT_FAILURE); \
} \
tso = SVAR_HEAD(node); \
- if (tso != (P_) Nil_closure) { \
- if (ThreadQueueHd == Nil_closure) \
+ if (tso != (P_) Prelude_Z91Z93_closure) { \
+ if (ThreadQueueHd == Prelude_Z91Z93_closure) \
ThreadQueueHd = tso; \
else \
TSO_LINK(ThreadQueueTl) = tso; \
- while(TSO_LINK(tso) != Nil_closure) { \
+ while(TSO_LINK(tso) != Prelude_Z91Z93_closure) { \
if (DO_QP_PROF) \
STGCALL3(void,(void *, char *, P_, P_),QP_Event2,do_qp_prof > 1 ? "RA" : "RG",tso,CurrentTSO); \
tso = TSO_LINK(tso); \
@@ -1513,12 +1527,12 @@ extern void Yield PROTO((W_));
EXIT(EXIT_FAILURE); \
} \
tso = SVAR_HEAD(node); \
- if (tso != (P_) Nil_closure) { \
- if (RunnableThreadsHd == Nil_closure) \
+ if (tso != (P_) Prelude_Z91Z93_closure) { \
+ if (RunnableThreadsHd == Prelude_Z91Z93_closure) \
RunnableThreadsHd = tso; \
else \
TSO_LINK(RunnableThreadsTl) = tso; \
- while(TSO_LINK(tso) != Nil_closure) { \
+ while(TSO_LINK(tso) != Prelude_Z91Z93_closure) { \
if (DO_QP_PROF) \
STGCALL3(void,(void *, char *, P_, P_),QP_Event2,do_qp_prof > 1 ? "RA" : "RG",tso,CurrentTSO); \
tso = TSO_LINK(tso); \
@@ -1568,12 +1582,12 @@ extern void Yield PROTO((W_));
#define delayZh(liveness, us) \
{ \
- if (WaitingThreadsTl == Nil_closure) \
+ if (WaitingThreadsTl == Prelude_Z91Z93_closure) \
WaitingThreadsHd = CurrentTSO; \
else \
TSO_LINK(WaitingThreadsTl) = CurrentTSO; \
WaitingThreadsTl = CurrentTSO; \
- TSO_LINK(CurrentTSO) = Nil_closure; \
+ TSO_LINK(CurrentTSO) = Prelude_Z91Z93_closure; \
TSO_EVENT(CurrentTSO) = (W_) ((us) < 1 ? 1 : (us)); \
DO_YIELD(liveness << 1); \
}
@@ -1593,24 +1607,55 @@ extern void Yield PROTO((W_));
/* ToDo: something for GRAN */
-#define waitZh(liveness, fd) \
+#define waitReadZh(liveness, fd) \
{ \
- if (WaitingThreadsTl == Nil_closure) \
+ if (WaitingThreadsTl == Prelude_Z91Z93_closure) \
WaitingThreadsHd = CurrentTSO; \
else \
TSO_LINK(WaitingThreadsTl) = CurrentTSO; \
WaitingThreadsTl = CurrentTSO; \
- TSO_LINK(CurrentTSO) = Nil_closure; \
+ TSO_LINK(CurrentTSO) = Prelude_Z91Z93_closure; \
TSO_EVENT(CurrentTSO) = (W_) (-(fd)); \
DO_YIELD(liveness << 1); \
}
#else
-#define waitZh(liveness, fd) \
+#define waitReadZh(liveness, fd) \
+ { \
+ fflush(stdout); \
+ fprintf(stderr, "waitRead#: unthreaded build.\n"); \
+ EXIT(EXIT_FAILURE); \
+ }
+
+#endif
+
+#ifdef CONCURRENT
+
+/* ToDo: something for GRAN */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif HAVE_SYS_TYPES_H */
+
+#define waitWriteZh(liveness, fd) \
+ { \
+ if (WaitingThreadsTl == Prelude_Z91Z93_closure) \
+ WaitingThreadsHd = CurrentTSO; \
+ else \
+ TSO_LINK(WaitingThreadsTl) = CurrentTSO; \
+ WaitingThreadsTl = CurrentTSO; \
+ TSO_LINK(CurrentTSO) = Prelude_Z91Z93_closure; \
+ TSO_EVENT(CurrentTSO) = (W_) (-(fd+FD_SETSIZE)); \
+ DO_YIELD(liveness << 1); \
+ }
+
+#else
+
+#define waitWriteZh(liveness, fd) \
{ \
fflush(stdout); \
- fprintf(stderr, "wait#: unthreaded build.\n"); \
+ fprintf(stderr, "waitWrite#: unthreaded build.\n"); \
EXIT(EXIT_FAILURE); \
}
@@ -1806,6 +1851,7 @@ do { \
\
newSP = SPT_POP(StorageMgrInfo.StablePointerTable); \
SPT_SPTR(StorageMgrInfo.StablePointerTable, newSP) = unstablePtr; \
+ CHECK_SPT_CLOSURE( StorageMgrInfo.StablePointerTable ); \
stablePtr = newSP; \
} while (0)
@@ -1864,53 +1910,100 @@ Anything with tag >= 0 is in WHNF, so we discard it.
\begin{code}
#ifdef CONCURRENT
-ED_(Nil_closure);
+ED_(Prelude_Z91Z93_closure);
ED_(True_closure);
#if defined(GRAN)
-#define parZh(r,hp,node,rest) \
- PARZh(r,hp,node,rest,0,0)
+#define parZh(r,node) \
+ PARZh(r,node,1,0,0,0,0,0)
+
+#define parAtZh(r,node,where,identifier,gran_info,size_info,par_info,rest) \
+ parATZh(r,node,where,identifier,gran_info,size_info,par_info,rest,1)
-#define parAtZh(r,hp,node,where,identifier,rest) \
- parATZh(r,hp,node,where,identifier,rest,1)
+#define parAtAbsZh(r,node,proc,identifier,gran_info,size_info,par_info,rest) \
+ parATZh(r,node,proc,identifier,gran_info,size_info,par_info,rest,2)
-#define parAtForNowZh(r,hp,node,where,identifier,rest) \
- parATZh(r,hp,node,where,identifier,rest,0)
+#define parAtRelZh(r,node,proc,identifier,gran_info,size_info,par_info,rest) \
+ parATZh(r,node,proc,identifier,gran_info,size_info,par_info,rest,3)
-#define parATZh(r,hp,node,where,identifier,rest,local) \
+#define parAtForNowZh(r,node,where,identifier,gran_info,size_info,par_info,rest) \
+ parATZh(r,node,where,identifier,gran_info,size_info,par_info,rest,0)
+
+#define parATZh(r,node,where,identifier,gran_info,size_info,par_info,rest,local) \
{ \
sparkq result; \
if (SHOULD_SPARK(node)) { \
- result = NewSpark((P_)node,identifier,local); \
- SAFESTGCALL3(void,(W_),GranSimSparkAt,result,where,identifier); \
+ SaveAllStgRegs(); \
+ { sparkq result; \
+ result = NewSpark((P_)node,identifier,gran_info,size_info,par_info,local); \
+ if (local==2) { /* special case for parAtAbs */ \
+ GranSimSparkAtAbs(result,(I_)where,identifier);\
+ } else if (local==3) { /* special case for parAtRel */ \
+ GranSimSparkAtAbs(result,(I_)(CurrentProc+where),identifier); \
+ } else { \
+ GranSimSparkAt(result,where,identifier); \
+ } \
+ context_switch = 1; \
+ } \
+ RestoreAllStgRegs(); \
} else if (do_qp_prof) { \
I_ tid = threadId++; \
SAFESTGCALL2(void,(I_, P_),QP_Event0,tid,node); \
} \
- r = (rest); \
+ r = 1; /* return code for successful spark -- HWL */ \
}
-#define parLocalZh(r,hp,node,identifier,rest) \
- PARZh(r,hp,node,rest,identifier,1)
+#define parLocalZh(r,node,identifier,gran_info,size_info,par_info,rest) \
+ PARZh(r,node,rest,identifier,gran_info,size_info,par_info,1)
+
+#define parGlobalZh(r,node,identifier,gran_info,size_info,par_info,rest) \
+ PARZh(r,node,rest,identifier,gran_info,size_info,par_info,0)
-#define parGlobalZh(r,hp,node,identifier,rest) \
- PARZh(r,hp,node,rest,identifier,0)
+#if 1
-#define PARZh(r,hp,node,rest,identifier,local) \
+#define PARZh(r,node,rest,identifier,gran_info,size_info,par_info,local) \
+{ \
+ if (SHOULD_SPARK(node)) { \
+ SaveAllStgRegs(); \
+ { sparkq result; \
+ result = NewSpark((P_)node,identifier,gran_info,size_info,par_info,local);\
+ add_to_spark_queue(result); \
+ GranSimSpark(local,(P_)node); \
+ context_switch = 1; \
+ } \
+ RestoreAllStgRegs(); \
+ } else if (do_qp_prof) { \
+ I_ tid = threadId++; \
+ SAFESTGCALL2(void,(I_, P_),QP_Event0,tid,node); \
+ } \
+ r = 1; /* return code for successful spark -- HWL */ \
+}
+
+#else
+
+#define PARZh(r,node,rest,identifier,gran_info,size_info,par_info,local) \
{ \
sparkq result; \
if (SHOULD_SPARK(node)) { \
- result = NewSpark((P_)node,identifier,local); \
+ result = NewSpark((P_)node,identifier,gran_info,size_info,par_info,local);\
ADD_TO_SPARK_QUEUE(result); \
SAFESTGCALL2(void,(W_),GranSimSpark,local,(P_)node); \
- /* context_switch = 1; not needed any more -- HWL */ \
+ /* context_switch = 1; not needed any more -- HWL */ \
} else if (do_qp_prof) { \
I_ tid = threadId++; \
SAFESTGCALL2(void,(I_, P_),QP_Event0,tid,node); \
} \
- r = (rest); \
+ r = 1; /* return code for successful spark -- HWL */ \
}
+#endif
+
+#define copyableZh(r,node) \
+ /* copyable not yet implemented!! */
+
+#define noFollowZh(r,node) \
+ /* noFollow not yet implemented!! */
+
#else /* !GRAN */
extern I_ required_thread_count;
@@ -1958,6 +2051,7 @@ extern I_ required_thread_count;
r = 1; /* Should not be necessary */ \
}
+#endif /* GRAN */
\end{code}
The following seq# code should only be used in unoptimized code.
@@ -1979,8 +2073,8 @@ ED_RO_(vtbl_seq);
#define seqZh(r,liveness,node) \
({ \
__label__ cont; \
- STK_CHK(liveness,0,2,0,0,0,0); \
- SpB -= BREL(2); \
+ /* STK_CHK(liveness,0,2,0,0,0,0); */ \
+ /* SpB -= BREL(2); */ \
SpB[BREL(0)] = (W_) RetReg; \
SpB[BREL(1)] = (W_) &&cont; \
RetReg = (StgRetAddr) vtbl_seq; \
@@ -1992,23 +2086,27 @@ ED_RO_(vtbl_seq);
r = 1; /* Should be unnecessary */ \
})
-#endif /* GRAN */
#endif /* CONCURRENT */
\end{code}
%************************************************************************
%* *
-\subsubsection[StgMacros-malloc-ptrs]{Malloc Pointers}
+\subsubsection[StgMacros-foreign-objects]{Foreign Objects}
%* *
%************************************************************************
-This macro is used to construct a MallocPtr on the heap after a ccall.
-Since MallocPtr's are like arrays in many ways, this is heavily based
-on the stuff for arrays above.
+[Based on previous MallocPtr comments -- SOF]
+
+This macro is used to construct a ForeignObj on the heap.
What this does is plug the pointer (which will be in a local
-variable), into a fresh heap object and then sets a result (which will
-be a register) to point to the fresh heap object.
+variable) together with its finalising/free routine, into a fresh heap
+object and then sets a result (which will be a register) to point
+to the fresh heap object.
+
+To accommodate per-object finalisation, augment the macro with a
+finalisation routine argument. Nothing spectacular, just plug the
+pointer to the routine into the ForeignObj -- SOF 4/96
Question: what's this "SET_ACTIVITY" stuff - should I be doing this
too? (It's if you want to use the SPAT profiling tools to
@@ -2016,42 +2114,45 @@ characterize program behavior by ``activity'' -- tail-calling,
heap-checking, etc. -- see Ticky.lh. It is quite specialized.
WDP 95/1)
+(Swapped first two arguments to make it come into line with what appears
+to be `standard' format, return register then liveness mask. -- SOF 4/96)
+
\begin{code}
#ifndef PAR
-StgInt eqMallocPtr PROTO((StgMallocPtr p1, StgMallocPtr p2));
-void FreeMallocPtr PROTO((StgMallocPtr mp));
+StgInt eqForeignObj PROTO((StgForeignObj p1, StgForeignObj p2));
-#define constructMallocPtr(liveness, r, mptr) \
-do { \
- P_ result; \
- \
- HEAP_CHK(liveness, _FHS + MallocPtr_SIZE,0); \
- CC_ALLOC(CCC,_FHS + MallocPtr_SIZE,MallocPtr_K); /* cc prof */ \
+#define makeForeignObjZh(r, liveness, mptr, finalise) \
+do { \
+ P_ result; \
+ \
+ HEAP_CHK((W_)liveness, _FHS + ForeignObj_SIZE,0); \
+ CC_ALLOC(CCC,_FHS + ForeignObj_SIZE,ForeignObj_K); /* cc prof */ \
\
- result = Hp + 1 - (_FHS + MallocPtr_SIZE); \
- SET_MallocPtr_HDR(result,MallocPtr_info,CCC,_FHS + MallocPtr_SIZE,0); \
- MallocPtr_CLOSURE_DATA(result) = mptr; \
- MallocPtr_CLOSURE_LINK(result) = StorageMgrInfo.MallocPtrList; \
- StorageMgrInfo.MallocPtrList = result; \
+ result = Hp + 1 - (_FHS + ForeignObj_SIZE); \
+ SET_ForeignObj_HDR(result,ForeignObj_info,CCC,_FHS + ForeignObj_SIZE,0); \
+ ForeignObj_CLOSURE_DATA(result) = (P_)mptr; \
+ ForeignObj_CLOSURE_FINALISER(result) = (P_)finalise; \
+ ForeignObj_CLOSURE_LINK(result) = StorageMgrInfo.ForeignObjList; \
+ StorageMgrInfo.ForeignObjList = result; \
\
/* \
- printf("DEBUG: MallocPtr(0x%x) = <0x%x, 0x%x, 0x%x, 0x%x>\n", \
+ printf("DEBUG: ForeignObj(0x%x) = <0x%x, 0x%x, 0x%x, 0x%x>\n", \
result, \
result[0],result[1], \
result[2],result[3]); \
*/ \
- CHECK_MallocPtr_CLOSURE( result ); \
- VALIDATE_MallocPtrList( StorageMgrInfo.MallocPtrList ); \
+ CHECK_ForeignObj_CLOSURE( result ); \
+ VALIDATE_ForeignObjList( StorageMgrInfo.ForeignObjList ); \
\
(r) = (P_) result; \
} while (0)
#else
-#define constructMallocPtr(liveness, r, mptr) \
+#define makeForeignObjZh(r, liveness, mptr, finalise) \
do { \
fflush(stdout); \
- fprintf(stderr, "constructMallocPtr: no malloc pointer support.\n");\
+ fprintf(stderr, "makeForeignObj#: no foreign object support.\n");\
EXIT(EXIT_FAILURE); \
} while(0)