/* -----------------------------------------------------------------------------
- * $Id: StgMacros.h,v 1.19 1999/11/22 16:44:30 sewardj Exp $
+ * $Id: StgMacros.h,v 1.27 2000/07/08 19:35:42 panne Exp $
*
* (c) The GHC Team, 1998-1999
*
#define ED_ extern
#define EDD_ extern DLLIMPORT
#define ED_RO_ extern const
-#define ID_ extern
-#define ID_RO_ extern const
+#define ID_ static
+#define ID_RO_ static const
#define EI_ extern INFO_TBL_CONST StgInfoTable
#define EDI_ extern DLLIMPORT INFO_TBL_CONST StgInfoTable
-#define II_ extern INFO_TBL_CONST StgInfoTable
+#define II_ static INFO_TBL_CONST StgInfoTable
#define EC_ extern StgClosure
#define EDC_ extern DLLIMPORT StgClosure
-#define IC_ extern StgClosure
+#define IC_ static StgClosure
#define ECP_(x) extern const StgClosure *(x)[]
#define EDCP_(x) extern DLLIMPORT StgClosure *(x)[]
-#define ICP_(x) extern const StgClosure *(x)[]
+#define ICP_(x) static const StgClosure *(x)[]
/* -----------------------------------------------------------------------------
Stack Tagging.
}
#define HP_CHK(headroom,ret,r,layout,tag_assts) \
+ DO_GRAN_ALLOCATE(headroom) \
if ((Hp += headroom) > HpLim) { \
EXTFUN_RTS(stg_chk_##layout); \
tag_assts \
}
#define HP_STK_CHK(stk_headroom,hp_headroom,ret,r,layout,tag_assts) \
+ DO_GRAN_ALLOCATE(hp_headroom) \
if (Sp - stk_headroom < SpLim || (Hp += hp_headroom) > HpLim) { \
EXTFUN_RTS(stg_chk_##layout); \
tag_assts \
functions. In all these cases, node points to a closure that we
can just enter to restart the heap check (the NP stands for 'node points').
+ In the NP case GranSim absolutely has to check whether the current node
+ resides on the current processor. Otherwise a FETCH event has to be
+ scheduled. All that is done in GranSimFetch. -- HWL
+
HpLim points to the LAST WORD of valid allocation space.
-------------------------------------------------------------------------- */
}
#define HP_CHK_NP(headroom,ptrs,tag_assts) \
+ DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_enter_##ptrs); \
tag_assts \
}
#define HP_CHK_SEQ_NP(headroom,ptrs,tag_assts) \
+ DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_seq_##ptrs); \
tag_assts \
}
#define HP_STK_CHK_NP(stk_headroom, hp_headroom, ptrs, tag_assts) \
+ DO_GRAN_ALLOCATE(hp_headroom) \
if ((Sp - (stk_headroom)) < SpLim || (Hp += (hp_headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_enter_##ptrs); \
tag_assts \
/* Heap checks for branches of a primitive case / unboxed tuple return */
#define GEN_HP_CHK_ALT(headroom,lbl,tag_assts) \
+ DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(lbl); \
tag_assts \
JMP_(stg_block_##ptrs); \
}
+#if defined(PAR)
+/*
+ Similar to BLOCK_NP but separates the saving of the thread state from the
+ actual jump via an StgReturn
+*/
+
+#define SAVE_THREAD_STATE(ptrs) \
+ ASSERT(ptrs==1); \
+ Sp -= 1; \
+ Sp[0] = R1.w; \
+ SaveThreadState();
+
+#define THREAD_RETURN(ptrs) \
+ ASSERT(ptrs==1); \
+ CurrentTSO->what_next = ThreadEnterGHC; \
+ R1.i = ThreadBlocked; \
+ JMP_(StgReturn);
+#endif
+
/* -----------------------------------------------------------------------------
CCall_GC needs to push a dummy stack frame containing the contents
of volatile registers and variables.
# define UPD_BH_SINGLE_ENTRY(thunk) /* nothing */
#endif /* EAGER_BLACKHOLING */
-#define UPD_FRAME_UPDATEE(p) (((StgUpdateFrame *)(p))->updatee)
+#define UPD_FRAME_UPDATEE(p) ((P_)(((StgUpdateFrame *)(p))->updatee))
#define UPDATE_SU_FROM_UPD_FRAME(p) (Su=((StgUpdateFrame *)(p))->link)
/* -----------------------------------------------------------------------------
-------------------------------------------------------------------------- */
#if defined(USE_SPLIT_MARKERS)
-#define __STG_SPLIT_MARKER(n) FN_(__stg_split_marker##n) { }
+#define __STG_SPLIT_MARKER __asm__("\n__stg_split_marker:");
#else
-#define __STG_SPLIT_MARKER(n) /* nothing */
+#define __STG_SPLIT_MARKER /* nothing */
#endif
/* -----------------------------------------------------------------------------
static __inline__ void
SaveThreadState(void)
{
+ StgTSO *tso;
+
/* Don't need to save REG_Base, it won't have changed. */
- CurrentTSO->sp = Sp;
- CurrentTSO->su = Su;
- CurrentTSO->splim = SpLim;
+ tso = CurrentTSO;
+ tso->sp = Sp;
+ tso->su = Su;
+ tso->splim = SpLim;
CloseNursery(Hp);
#ifdef REG_CurrentTSO
- SAVE_CurrentTSO = CurrentTSO;
+ SAVE_CurrentTSO = tso;
#endif
#ifdef REG_CurrentNursery
SAVE_CurrentNursery = CurrentNursery;
static __inline__ void
LoadThreadState (void)
{
- Sp = CurrentTSO->sp;
- Su = CurrentTSO->su;
- SpLim = CurrentTSO->splim;
- OpenNursery(Hp,HpLim);
+ StgTSO *tso;
#ifdef REG_CurrentTSO
CurrentTSO = SAVE_CurrentTSO;
#endif
+
+ tso = CurrentTSO;
+ Sp = tso->sp;
+ Su = tso->su;
+ SpLim = tso->splim;
+ OpenNursery(Hp,HpLim);
+
#ifdef REG_CurrentNursery
CurrentNursery = SAVE_CurrentNursery;
#endif
#endif
/* -----------------------------------------------------------------------------
+ Module initialisation
+ -------------------------------------------------------------------------- */
+
+#define PUSH_INIT_STACK(reg_function) \
+ *(Sp++) = (W_)reg_function
+
+#define POP_INIT_STACK() \
+ *(--Sp)
+
+#define START_MOD_INIT(reg_mod_name) \
+ static int _module_registered = 0; \
+ FN_(reg_mod_name) { \
+ FB_; \
+ if (! _module_registered) { \
+ _module_registered = 1; \
+ {
+ /* extern decls go here, followed by init code */
+
+#define REGISTER_FOREIGN_EXPORT(reg_fe_binder) \
+ STGCALL1(getStablePtr,reg_fe_binder)
+
+#define REGISTER_IMPORT(reg_mod_name) \
+ do { EF_(reg_mod_name); \
+ PUSH_INIT_STACK(reg_mod_name) ; \
+ } while (0)
+
+#define END_MOD_INIT() \
+ }}; \
+ JMP_(POP_INIT_STACK()); \
+ FE_ }
+
+/* -----------------------------------------------------------------------------
Support for _ccall_GC_ and _casm_GC.
-------------------------------------------------------------------------- */