diff options
Diffstat (limited to 'includes')
-rw-r--r-- | includes/ClosureMacros.h | 185 | ||||
-rw-r--r-- | includes/Cmm.h | 31 | ||||
-rw-r--r-- | includes/GranSim.h | 331 | ||||
-rw-r--r-- | includes/HsFFI.h | 6 | ||||
-rw-r--r-- | includes/MachDeps.h | 3 | ||||
-rw-r--r-- | includes/Parallel.h | 360 | ||||
-rw-r--r-- | includes/README | 9 | ||||
-rw-r--r-- | includes/Rts.h | 130 | ||||
-rw-r--r-- | includes/RtsAPI.h | 2 | ||||
-rw-r--r-- | includes/RtsConfig.h | 64 | ||||
-rw-r--r-- | includes/RtsExternal.h | 129 | ||||
-rw-r--r-- | includes/RtsFlags.h | 241 | ||||
-rw-r--r-- | includes/STM.h | 245 | ||||
-rw-r--r-- | includes/Stable.h | 63 | ||||
-rw-r--r-- | includes/Stg.h | 57 | ||||
-rw-r--r-- | includes/Storage.h | 583 | ||||
-rw-r--r-- | includes/config.h | 7 | ||||
-rw-r--r-- | includes/ghc.mk | 6 | ||||
-rw-r--r-- | includes/ieee-flpt.h | 35 | ||||
-rw-r--r-- | includes/mkDerivedConstants.c | 4 | ||||
-rw-r--r-- | includes/rts/Adjustor.h | 20 | ||||
-rw-r--r-- | includes/rts/Bytecodes.h (renamed from includes/Bytecodes.h) | 0 | ||||
-rw-r--r-- | includes/rts/Config.h | 36 | ||||
-rw-r--r-- | includes/rts/Constants.h (renamed from includes/Constants.h) | 6 | ||||
-rw-r--r-- | includes/rts/EventLogFormat.h (renamed from includes/EventLogFormat.h) | 6 | ||||
-rw-r--r-- | includes/rts/FileLock.h (renamed from includes/FileLock.h) | 7 | ||||
-rw-r--r-- | includes/rts/Flags.h | 239 | ||||
-rw-r--r-- | includes/rts/Globals.h (renamed from includes/RtsGlobals.h) | 9 | ||||
-rw-r--r-- | includes/rts/Hooks.h (renamed from includes/Hooks.h) | 5 | ||||
-rw-r--r-- | includes/rts/Hpc.h | 32 | ||||
-rw-r--r-- | includes/rts/IOManager.h | 39 | ||||
-rw-r--r-- | includes/rts/Linker.h (renamed from includes/Linker.h) | 8 | ||||
-rw-r--r-- | includes/rts/Messages.h (renamed from includes/RtsMessages.h) | 27 | ||||
-rw-r--r-- | includes/rts/OSThreads.h (renamed from includes/OSThreads.h) | 16 | ||||
-rw-r--r-- | includes/rts/Parallel.h | 14 | ||||
-rw-r--r-- | includes/rts/Signals.h (renamed from includes/Signals.h) | 11 | ||||
-rw-r--r-- | includes/rts/SpinLock.h (renamed from includes/SpinLock.h) | 6 | ||||
-rw-r--r-- | includes/rts/Stable.h | 35 | ||||
-rw-r--r-- | includes/rts/Threads.h (renamed from includes/SchedAPI.h) | 32 | ||||
-rw-r--r-- | includes/rts/Timer.h | 15 | ||||
-rw-r--r-- | includes/rts/Types.h (renamed from includes/RtsTypes.h) | 8 | ||||
-rw-r--r-- | includes/rts/prof/CCS.h (renamed from includes/StgProf.h) | 6 | ||||
-rw-r--r-- | includes/rts/prof/LDV.h (renamed from includes/StgLdvProf.h) | 5 | ||||
-rw-r--r-- | includes/rts/storage/Block.h (renamed from includes/Block.h) | 6 | ||||
-rw-r--r-- | includes/rts/storage/ClosureMacros.h | 395 | ||||
-rw-r--r-- | includes/rts/storage/ClosureTypes.h (renamed from includes/ClosureTypes.h) | 6 | ||||
-rw-r--r-- | includes/rts/storage/Closures.h (renamed from includes/Closures.h) | 20 | ||||
-rw-r--r-- | includes/rts/storage/FunTypes.h (renamed from includes/StgFun.h) | 8 | ||||
-rw-r--r-- | includes/rts/storage/GC.h | 204 | ||||
-rw-r--r-- | includes/rts/storage/InfoTables.h (renamed from includes/InfoTables.h) | 23 | ||||
-rw-r--r-- | includes/rts/storage/Liveness.h (renamed from includes/Liveness.h) | 6 | ||||
-rw-r--r-- | includes/rts/storage/MBlock.h | 206 | ||||
-rw-r--r-- | includes/rts/storage/SMPClosureOps.h (renamed from includes/SMPClosureOps.h) | 6 | ||||
-rw-r--r-- | includes/rts/storage/TSO.h (renamed from includes/TSO.h) | 39 | ||||
-rw-r--r-- | includes/stg/DLL.h (renamed from includes/StgDLL.h) | 0 | ||||
-rw-r--r-- | includes/stg/MachRegs.h (renamed from includes/MachRegs.h) | 0 | ||||
-rw-r--r-- | includes/stg/MiscClosures.h (renamed from includes/StgMiscClosures.h) | 4 | ||||
-rw-r--r-- | includes/stg/Regs.h (renamed from includes/Regs.h) | 5 | ||||
-rw-r--r-- | includes/stg/SMP.h (renamed from includes/SMP.h) | 29 | ||||
-rw-r--r-- | includes/stg/TailCalls.h (renamed from includes/TailCalls.h) | 0 | ||||
-rw-r--r-- | includes/stg/Ticky.h (renamed from includes/TickyCounters.h) | 4 | ||||
-rw-r--r-- | includes/stg/Types.h (renamed from includes/StgTypes.h) | 48 |
62 files changed, 1501 insertions, 2581 deletions
diff --git a/includes/ClosureMacros.h b/includes/ClosureMacros.h deleted file mode 100644 index 1c371b25e8..0000000000 --- a/includes/ClosureMacros.h +++ /dev/null @@ -1,185 +0,0 @@ -/* ---------------------------------------------------------------------------- - * - * (c) The GHC Team, 1998-2004 - * - * Macros for building and manipulating closures - * - * -------------------------------------------------------------------------- */ - -#ifndef CLOSUREMACROS_H -#define CLOSUREMACROS_H - -/* Say whether the code comes before the heap; on mingwin this may not be the - case, not because of another random MS pathology, but because the static - program may reside in a DLL -*/ - -/* ----------------------------------------------------------------------------- - Info tables are slammed up against the entry code, and the label - for the info table is at the *end* of the table itself. This - inline function adjusts an info pointer to point to the beginning - of the table, so we can use standard C structure indexing on it. - - Note: this works for SRT info tables as long as you don't want to - access the SRT, since they are laid out the same with the SRT - pointer as the first word in the table. - - NOTES ABOUT MANGLED C VS. MINI-INTERPRETER: - - A couple of definitions: - - "info pointer" The first word of the closure. Might point - to either the end or the beginning of the - info table, depending on whether we're using - the mini interpretter or not. GET_INFO(c) - retrieves the info pointer of a closure. - - "info table" The info table structure associated with a - closure. This is always a pointer to the - beginning of the structure, so we can - use standard C structure indexing to pull out - the fields. get_itbl(c) returns a pointer to - the info table for closure c. - - An address of the form xxxx_info points to the end of the info - table or the beginning of the info table depending on whether we're - mangling or not respectively. So, - - c->header.info = xxx_info - - makes absolute sense, whether mangling or not. - - -------------------------------------------------------------------------- */ - -#define SET_INFO(c,i) ((c)->header.info = (i)) -#define GET_INFO(c) ((c)->header.info) -#define GET_ENTRY(c) (ENTRY_CODE(GET_INFO(c))) - -#define get_itbl(c) (INFO_PTR_TO_STRUCT((c)->header.info)) -#define get_ret_itbl(c) (RET_INFO_PTR_TO_STRUCT((c)->header.info)) -#define get_fun_itbl(c) (FUN_INFO_PTR_TO_STRUCT((c)->header.info)) -#define get_thunk_itbl(c) (THUNK_INFO_PTR_TO_STRUCT((c)->header.info)) -#define get_con_itbl(c) (CON_INFO_PTR_TO_STRUCT((c)->header.info)) - -#define GET_TAG(con) (get_itbl(con)->srt_bitmap) - -#ifdef TABLES_NEXT_TO_CODE -#define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)(info) - 1) -#define RET_INFO_PTR_TO_STRUCT(info) ((StgRetInfoTable *)(info) - 1) -#define FUN_INFO_PTR_TO_STRUCT(info) ((StgFunInfoTable *)(info) - 1) -#define THUNK_INFO_PTR_TO_STRUCT(info) ((StgThunkInfoTable *)(info) - 1) -#define CON_INFO_PTR_TO_STRUCT(info) ((StgConInfoTable *)(info) - 1) -#define itbl_to_fun_itbl(i) ((StgFunInfoTable *)(((StgInfoTable *)(i) + 1)) - 1) -#define itbl_to_ret_itbl(i) ((StgRetInfoTable *)(((StgInfoTable *)(i) + 1)) - 1) -#define itbl_to_thunk_itbl(i) ((StgThunkInfoTable *)(((StgInfoTable *)(i) + 1)) - 1) -#define itbl_to_con_itbl(i) ((StgConInfoTable *)(((StgInfoTable *)(i) + 1)) - 1) -#else -#define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)info) -#define RET_INFO_PTR_TO_STRUCT(info) ((StgRetInfoTable *)info) -#define FUN_INFO_PTR_TO_STRUCT(info) ((StgFunInfoTable *)info) -#define THUNK_INFO_PTR_TO_STRUCT(info) ((StgThunkInfoTable *)info) -#define CON_INFO_PTR_TO_STRUCT(info) ((StgConInfoTable *)info) -#define itbl_to_fun_itbl(i) ((StgFunInfoTable *)(i)) -#define itbl_to_ret_itbl(i) ((StgRetInfoTable *)(i)) -#define itbl_to_thunk_itbl(i) ((StgThunkInfoTable *)(i)) -#define itbl_to_con_itbl(i) ((StgConInfoTable *)(i)) -#endif - -/* ----------------------------------------------------------------------------- - Macros for building closures - -------------------------------------------------------------------------- */ - -#ifdef PROFILING -#ifdef DEBUG_RETAINER -/* - For the sake of debugging, we take the safest way for the moment. Actually, this - is useful to check the sanity of heap before beginning retainer profiling. - flip is defined in RetainerProfile.c, and declared as extern in RetainerProfile.h. - Note: change those functions building Haskell objects from C datatypes, i.e., - all rts_mk???() functions in RtsAPI.c, as well. - */ -#define SET_PROF_HDR(c,ccs_) \ - ((c)->header.prof.ccs = ccs_, (c)->header.prof.hp.rs = (retainerSet *)((StgWord)NULL | flip)) -#else -/* - For retainer profiling only: we do not have to set (c)->header.prof.hp.rs to - NULL | flip (flip is defined in RetainerProfile.c) because even when flip - is 1, rs is invalid and will be initialized to NULL | flip later when - the closure *c is visited. - */ -/* -#define SET_PROF_HDR(c,ccs_) \ - ((c)->header.prof.ccs = ccs_, (c)->header.prof.hp.rs = NULL) - */ -/* - The following macro works for both retainer profiling and LDV profiling: - for retainer profiling, ldvTime remains 0, so rs fields are initialized to 0. - See the invariants on ldvTime. - */ -#define SET_PROF_HDR(c,ccs_) \ - ((c)->header.prof.ccs = ccs_, \ - LDV_RECORD_CREATE((c))) -#endif /* DEBUG_RETAINER */ -#define SET_STATIC_PROF_HDR(ccs_) \ - prof : { ccs : (CostCentreStack *)ccs_, hp : { rs : NULL } }, -#else -#define SET_PROF_HDR(c,ccs) -#define SET_STATIC_PROF_HDR(ccs) -#endif - -#ifdef TICKY_TICKY -#define SET_TICKY_HDR(c,stuff) /* old: (c)->header.ticky.updated = stuff */ -#define SET_STATIC_TICKY_HDR(stuff) /* old: ticky : { updated : stuff } */ -#else -#define SET_TICKY_HDR(c,stuff) -#define SET_STATIC_TICKY_HDR(stuff) -#endif - -#define SET_HDR(c,_info,ccs) \ - { \ - (c)->header.info = _info; \ - SET_PROF_HDR((StgClosure *)(c),ccs); \ - SET_TICKY_HDR((StgClosure *)(c),0); \ - } - -#define SET_ARR_HDR(c,info,costCentreStack,n_words) \ - SET_HDR(c,info,costCentreStack); \ - (c)->words = n_words; - -/* ----------------------------------------------------------------------------- - How to get hold of the static link field for a static closure. - -------------------------------------------------------------------------- */ - -/* These are hard-coded. */ -#define FUN_STATIC_LINK(p) (&(p)->payload[0]) -#define THUNK_STATIC_LINK(p) (&(p)->payload[1]) -#define IND_STATIC_LINK(p) (&(p)->payload[1]) - -INLINE_HEADER StgClosure ** -STATIC_LINK(const StgInfoTable *info, StgClosure *p) -{ - switch (info->type) { - case THUNK_STATIC: - return THUNK_STATIC_LINK(p); - case FUN_STATIC: - return FUN_STATIC_LINK(p); - case IND_STATIC: - return IND_STATIC_LINK(p); - default: - return &(p)->payload[info->layout.payload.ptrs + - info->layout.payload.nptrs]; - } -} - -#define STATIC_LINK2(info,p) \ - (*(StgClosure**)(&((p)->payload[info->layout.payload.ptrs + \ - info->layout.payload.nptrs + 1]))) - -/* ----------------------------------------------------------------------------- - INTLIKE and CHARLIKE closures. - -------------------------------------------------------------------------- */ - -#define CHARLIKE_CLOSURE(n) ((P_)&stg_CHARLIKE_closure[(n)-MIN_CHARLIKE]) -#define INTLIKE_CLOSURE(n) ((P_)&stg_INTLIKE_closure[(n)-MIN_INTLIKE]) - -#endif /* CLOSUREMACROS_H */ diff --git a/includes/Cmm.h b/includes/Cmm.h index 4577672f44..aba5c2e36b 100644 --- a/includes/Cmm.h +++ b/includes/Cmm.h @@ -66,7 +66,6 @@ #define CMINUSMINUS 1 #include "ghcconfig.h" -#include "RtsConfig.h" /* ----------------------------------------------------------------------------- Types @@ -144,6 +143,18 @@ name : bits8[] str; \ } \ +#ifdef TABLES_NEXT_TO_CODE +#define RET_LBL(f) f##_info +#else +#define RET_LBL(f) f##_ret +#endif + +#ifdef TABLES_NEXT_TO_CODE +#define ENTRY_LBL(f) f##_info +#else +#define ENTRY_LBL(f) f##_entry +#endif + /* ----------------------------------------------------------------------------- Byte/word macros @@ -320,26 +331,26 @@ Constants. -------------------------------------------------------------------------- */ -#include "Constants.h" +#include "rts/Constants.h" #include "DerivedConstants.h" -#include "ClosureTypes.h" -#include "StgFun.h" -#include "OSThreads.h" -#include "SMPClosureOps.h" +#include "rts/storage/ClosureTypes.h" +#include "rts/storage/FunTypes.h" +#include "rts/storage/SMPClosureOps.h" +#include "rts/OSThreads.h" /* * Need MachRegs, because some of the RTS code is conditionally * compiled based on REG_R1, REG_R2, etc. */ #define STOLEN_X86_REGS 4 -#include "MachRegs.h" +#include "stg/MachRegs.h" -#include "Liveness.h" -#include "StgLdvProf.h" +#include "rts/storage/Liveness.h" +#include "rts/prof/LDV.h" #undef BLOCK_SIZE #undef MBLOCK_SIZE -#include "Block.h" /* For Bdescr() */ +#include "rts/storage/Block.h" /* For Bdescr() */ #define MyCapability() (BaseReg - OFFSET_Capability_r) diff --git a/includes/GranSim.h b/includes/GranSim.h deleted file mode 100644 index be5aa83a52..0000000000 --- a/includes/GranSim.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - Headers for GranSim specific objects. - - Note that in GranSim we have one run-queue and blocking-queue for each - processor. Therefore, this header file redefines variables like - run_queue_hd to be relative to CurrentProc. The main arrays of runnable - and blocking queues are defined in Schedule.c. The important STG-called - GranSim macros (e.g. for fetching nodes) are at the end of this - file. Usually they are just wrappers to proper C functions in GranSim.c. -*/ - -#ifndef GRANSIM_H -#define GRANSIM_H - -#if !defined(GRAN) - -/* Dummy definitions for basic GranSim macros called from STG land */ -#define DO_GRAN_ALLOCATE(n) /* nothing */ -#define DO_GRAN_UNALLOCATE(n) /* nothing */ -#define DO_GRAN_FETCH(node) /* nothing */ -#define DO_GRAN_EXEC(arith,branch,load,store,floats) /* nothing */ -#define GRAN_FETCH_AND_RESCHEDULE(liveness_mask,reenter) /* nothing */ -#define GRAN_RESCHEDULE(liveness_mask,reenter) /* nothing */ - -#endif - -#if defined(GRAN) /* whole file */ - -extern StgTSO *CurrentTSO; - -/* - * @node Headers for GranSim specific objects, , , - * @section Headers for GranSim specific objects - * - * @menu - * * Externs and prototypes:: - * * Run and blocking queues:: - * * Spark queues:: - * * Processor related stuff:: - * * GranSim costs:: - * * STG called GranSim functions:: - * * STG-called routines:: - * @end menu - * - * @node Externs and prototypes, Run and blocking queues, Includes, Headers for GranSim specific objects - * @subsection Externs and prototypes - */ - -/* Global constants */ -extern char *gran_event_names[]; -extern char *proc_status_names[]; -extern char *event_names[]; - -/* Vars checked from within STG land */ -extern rtsBool NeedToReSchedule, IgnoreEvents, IgnoreYields; -; -extern rtsTime TimeOfNextEvent, TimeOfLastEvent, EndOfTimeSlice; - -/* costs for basic operations (copied from RTS flags) */ -extern nat gran_arith_cost, gran_branch_cost, gran_load_cost, gran_store_cost, gran_float_cost; - -extern nat SparksAvail; /* How many sparks are available */ -extern nat SurplusThreads; /* How many excess threads are there */ -extern nat sparksIgnored, sparksCreated; - -/* - * @node Run and blocking queues, Spark queues, Externs and prototypes, Headers for GranSim specific objects - * @subsection Run and blocking queues - */ - -/* declared in Schedule.c */ -extern StgTSO *run_queue_hds[], *run_queue_tls[]; -extern StgTSO *blocked_queue_hds[], *blocked_queue_tls[]; -extern StgTSO *ccalling_threadss[]; - -#define run_queue_hd run_queue_hds[CurrentProc] -#define run_queue_tl run_queue_tls[CurrentProc] -#define blocked_queue_hd blocked_queue_hds[CurrentProc] -#define blocked_queue_tl blocked_queue_tls[CurrentProc] -#define pending_sparks_hd pending_sparks_hds[CurrentProc] -#define pending_sparks_tl pending_sparks_tls[CurrentProc] -#define ccalling_threads ccalling_threadss[CurrentProc] - -/* - * @node Spark queues, Processor related stuff, Run and blocking queues, Headers for GranSim specific objects - * @subsection Spark queues - */ - -/* - In GranSim we use a double linked list to represent spark queues. - - This is more flexible, but slower, than the array of pointers - representation used in GUM. We use the flexibility to define new fields in - the rtsSpark structure, representing e.g. granularity info (see HWL's PhD - thesis), or info about the parent of a spark. -*/ - -/* Sparks and spark queues */ -typedef struct rtsSpark_ -{ - StgClosure *node; - nat name, global; - nat gran_info; /* for granularity improvement mechanisms */ - PEs creator; /* PE that created this spark (unused) */ - struct rtsSpark_ *prev, *next; -} rtsSpark; -typedef rtsSpark *rtsSparkQ; - -/* The spark queues, proper */ -/* In GranSim this is a globally visible array of spark queues */ -extern rtsSparkQ pending_sparks_hds[]; -extern rtsSparkQ pending_sparks_tls[]; - -/* Prototypes of those spark routines visible to compiler generated .hc */ -/* Routines only used inside the RTS are defined in rts/parallel GranSimRts.h */ -rtsSpark *newSpark(StgClosure *node, - nat name, nat gran_info, nat size_info, - nat par_info, nat local); -/* void add_to_spark_queue(rtsSpark *spark); */ - -/* - * @node Processor related stuff, GranSim costs, Spark queues, Headers for GranSim specific objects - * @subsection Processor related stuff - */ - -extern PEs CurrentProc; -extern rtsTime CurrentTime[]; - -/* Maximum number of PEs that can be simulated */ -#define MAX_PROC 32 /* (BITS_IN(StgWord)) */ /* ToDo: fix this!! */ -/* -#if MAX_PROC==16 -#else -#error MAX_PROC should be 32 on this architecture -#endif -*/ - -/* #define CurrentTSO CurrentTSOs[CurrentProc] */ - -/* Processor numbers to bitmasks and vice-versa */ -#define MainProc 0 /* Id of main processor */ -#define NO_PRI 0 /* dummy priority */ -#define MAX_PRI 10000 /* max possible priority */ -#define MAIN_PRI MAX_PRI /* priority of main thread */ - -/* GrAnSim uses IdleProcs as bitmask to indicate which procs are idle */ -#define PE_NUMBER(n) (1l << (long)n) -#define ThisPE PE_NUMBER(CurrentProc) -#define MainPE PE_NUMBER(MainProc) -#define Everywhere (~0l) -#define Nowhere (0l) -#define Now CurrentTime[CurrentProc] - -#define IS_LOCAL_TO(ga,proc) ((1l << (PEs) proc) & ga) - -#define GRAN_TIME_SLICE 1000 /* max time between 2 ReSchedules */ - -/* - * @node GranSim costs, STG called GranSim functions, Processor related stuff, Headers for GranSim specific objects - * @subsection GranSim costs - */ - -/* Default constants for communication (see RtsFlags on how to change them) */ - -#define LATENCY 1000 /* Latency for single packet */ -#define ADDITIONAL_LATENCY 100 /* Latency for additional packets */ -#define BASICBLOCKTIME 10 -#define FETCHTIME (LATENCY*2+MSGUNPACKTIME) -#define LOCALUNBLOCKTIME 10 -#define GLOBALUNBLOCKTIME (LATENCY+MSGUNPACKTIME) - -#define MSGPACKTIME 0 /* Cost of creating a packet */ -#define MSGUNPACKTIME 0 /* Cost of receiving a packet */ -#define MSGTIDYTIME 0 /* Cost of cleaning up after send */ - -/* How much to increase GrAnSims internal packet size if an overflow - occurs. - NB: This is a GrAnSim internal variable and is independent of the - simulated packet buffer size. -*/ - -#define GRANSIM_DEFAULT_PACK_BUFFER_SIZE 400 -#define REALLOC_SZ 200 - -/* extern W_ gran_mpacktime, gran_mtidytime, gran_munpacktime; */ - -/* Thread cost model */ -#define THREADCREATETIME (25+THREADSCHEDULETIME) -#define THREADQUEUETIME 12 /* Cost of adding a thread to the running/runnable queue */ -#define THREADDESCHEDULETIME 75 /* Cost of descheduling a thread */ -#define THREADSCHEDULETIME 75 /* Cost of scheduling a thread */ -#define THREADCONTEXTSWITCHTIME (THREADDESCHEDULETIME+THREADSCHEDULETIME) - -/* Instruction Cost model (SPARC, including cache misses) */ -#define ARITH_COST 1 -#define BRANCH_COST 2 -#define LOAD_COST 4 -#define STORE_COST 4 -#define FLOAT_COST 1 /* ? */ - -#define HEAPALLOC_COST 11 - -#define PRI_SPARK_OVERHEAD 5 -#define PRI_SCHED_OVERHEAD 5 - -/* - * @node STG called GranSim functions, STG-called routines, GranSim costs, Headers for GranSim specific objects - * @subsection STG called GranSim functions - */ - -/* STG called GranSim functions */ -void GranSimAllocate(StgInt n); -void GranSimUnallocate(StgInt n); -void GranSimExec(StgWord ariths, StgWord branches, StgWord loads, StgWord stores, StgWord floats); -StgInt GranSimFetch(StgClosure *node); -void GranSimSpark(StgInt local, StgClosure *node); -void GranSimSparkAt(rtsSpark *spark, StgClosure *where,StgInt identifier); -void GranSimSparkAtAbs(rtsSpark *spark, PEs proc, StgInt identifier); -void GranSimBlock(StgTSO *tso, PEs proc, StgClosure *node); - - -/* - * @node STG-called routines, , STG called GranSim functions, Headers for GranSim specific objects - * @subsection STG-called routines - */ - -/* Wrapped version of calls to GranSim-specific STG routines */ - -/* -#define DO_PERFORM_RESCHEDULE(liveness, always_reenter_node) PerformReschedule_wrapper(liveness, always_reenter_node) -*/ -#define DO_GRAN_ALLOCATE(n) STGCALL1(GranSimAllocate, n) -#define DO_GRAN_UNALLOCATE(n) STGCALL1(GranSimUnallocate, n) -#define DO_GRAN_FETCH(node) STGCALL1(GranSimFetch, node) -#define DO_GRAN_EXEC(arith,branch,load,store,floats) GranSimExec(arith,branch,load,store,floats) - -/* - ToDo: Clean up this mess of GRAN macros!!! -- HWL -*/ -/* DO_GRAN_FETCH((StgClosure*)R1.p); */ -#define GRAN_FETCH() /* nothing */ - -#define GRAN_FETCH_AND_RESCHEDULE(liveness,reenter) \ - DO_GRAN_FETCH((StgClosure*)R1.p); \ - DO_GRAN_YIELD(liveness,ENTRY_CODE((D_)(*R1.p))); -/* RESTORE_EVERYTHING is done implicitly before entering threaded world again */ - -/* - This is the only macro currently enabled; - It should check whether it is time for the current thread to yield - (e.g. if there is a more recent event in the queue) and it should check - whether node is local, via a call to GranSimFetch. - ToDo: split this in 2 routines: - - GRAN_YIELD (as it is below) - - GRAN_FETCH (the rest of this macro) - emit only these 2 macros based on node's liveness - node alive: emit both macros - node not alive: do only a GRAN_YIELD - - replace gran_yield_? with gran_block_? (they really block the current - thread) -*/ -#define GRAN_RESCHEDULE(liveness,ptrs) \ - if (RET_STGCALL1(StgInt, GranSimFetch, (StgClosure*)R1.p)) {\ - EXTFUN_RTS(gran_block_##ptrs); \ - JMP_(gran_block_##ptrs); \ - } else { \ - if (TimeOfLastEvent < CurrentTime[CurrentProc] && \ - HEAP_ALLOCED((StgClosure *)R1.p) && \ - LOOKS_LIKE_GHC_INFO(get_itbl((StgClosure *)R1.p))) { \ - EXTFUN_RTS(gran_yield_##ptrs); \ - JMP_(gran_yield_##ptrs); \ - } \ - /* GRAN_YIELD(ptrs) */ \ - } - - -/* YIELD(liveness,reenter) */ - -/* GRAN_YIELD(liveness_mask); */ - -/* GRAN_FETCH_AND_RESCHEDULE(liveness_mask,reenter) */ - -#define THREAD_CONTEXT_SWITCH(liveness_mask,reenter) \ - do { \ - if (context_switch /* OR_INTERVAL_EXPIRED */) { \ - GRAN_RESCHEDULE(liveness_mask,reenter); \ - } }while(0) - -#define GRAN_EXEC(arith,branch,load,store,floats) \ - { \ - W_ cost = gran_arith_cost*arith + \ - gran_branch_cost*branch + \ - gran_load_cost*load + \ - gran_store_cost*store + \ - gran_float_cost*floats; \ - CurrentTSO->gran.exectime += cost; \ - CurrentTime[CurrentProc] += cost; \ - } - -/* In GranSim we first check whether there is an event to handle; only if - this is the case (or the time slice is over in case of fair scheduling) - we do a yield, which is very similar to that in the concurrent world - ToDo: check whether gran_yield_? can be merged with other yielding codes -*/ - -#define DO_GRAN_YIELD(ptrs) if (!IgnoreYields && \ - TimeOfLastEvent < CurrentTime[CurrentProc] && \ - HEAP_ALLOCED((StgClosure *)R1.p) && \ - LOOKS_LIKE_GHC_INFO(get_itbl((StgClosure *)R1.p))) { \ - EXTFUN_RTS(gran_yield_##ptrs); \ - JMP_(gran_yield_##ptrs); \ - } - -#define GRAN_YIELD(ptrs) \ - { \ - extern int context_switch; \ - if ( (CurrentTime[CurrentProc]>=EndOfTimeSlice) || \ - ((CurrentTime[CurrentProc]>=TimeOfNextEvent) && \ - (TimeOfNextEvent!=0) && !IgnoreEvents )) { \ - /* context_switch = 1; */ \ - DO_GRAN_YIELD(ptrs); \ - } \ - } - -#define ADD_TO_SPARK_QUEUE(spark) \ - STGCALL1(add_to_spark_queue,spark) \ - -#endif /* GRAN */ - -#endif /* GRANSIM_H */ diff --git a/includes/HsFFI.h b/includes/HsFFI.h index cd9f7ede80..f489be5623 100644 --- a/includes/HsFFI.h +++ b/includes/HsFFI.h @@ -18,8 +18,7 @@ extern "C" { /* get types from GHC's runtime system */ #include "ghcconfig.h" -#include "RtsConfig.h" -#include "StgTypes.h" +#include "stg/Types.h" /* get limits for integral types */ #ifdef HAVE_STDINT_H @@ -84,10 +83,7 @@ typedef StgDouble HsDouble; typedef StgInt HsBool; typedef void* HsPtr; /* this should better match StgAddr */ typedef void (*HsFunPtr)(void); /* this should better match StgAddr */ -typedef void* HsForeignPtr; /* ... and this StgForeignPtr */ typedef void* HsStablePtr; -typedef void* HsAddr; /* DEPRECATED */ -typedef void* HsForeignObj; /* DEPRECATED */ /* this should correspond to the type of StgChar in StgTypes.h */ #define HS_CHAR_MIN 0 diff --git a/includes/MachDeps.h b/includes/MachDeps.h index 7b71f7c378..8e6db3ec0e 100644 --- a/includes/MachDeps.h +++ b/includes/MachDeps.h @@ -58,9 +58,6 @@ #define SIZEOF_HSFUNPTR SIZEOF_VOID_P #define ALIGNMENT_HSFUNPTR ALIGNMENT_VOID_P -#define SIZEOF_HSFOREIGNPTR SIZEOF_VOID_P -#define ALIGNMENT_HSFOREIGNPTR ALIGNMENT_VOID_P - #define SIZEOF_HSSTABLEPTR SIZEOF_VOID_P #define ALIGNMENT_HSSTABLEPTR ALIGNMENT_VOID_P diff --git a/includes/Parallel.h b/includes/Parallel.h deleted file mode 100644 index e18fbe9b2c..0000000000 --- a/includes/Parallel.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - Definitions for GUM i.e. running on a parallel machine. - - This section contains definitions applicable only to programs compiled - to run on a parallel machine, i.e. on GUM. Some of these definitions - are also used when simulating parallel execution, i.e. on GranSim. -*/ - -#ifndef PARALLEL_H -#define PARALLEL_H - -#if defined(PAR) || defined(GRAN) /* whole file */ - -/* - * @node Parallel definitions, End of File - * @section Parallel definitions - * - * @menu - * * Basic definitions:: - * * GUM:: - * * GranSim:: - * @end menu - * - * @node Basic definitions, GUM, Parallel definitions, Parallel definitions - * @subsection Basic definitions - */ - -/* This clashes with TICKY, but currently TICKY and PAR hate each other anyway */ -#define _HS sizeofW(StgHeader) - -/* SET_PAR_HDR and SET_STATIC_PAR_HDR now live in ClosureMacros.h */ - -/* Needed for dumping routines */ -#if defined(PAR) -# define NODE_STR_LEN 20 -# define TIME_STR_LEN 120 -# define TIME rtsTime -# define CURRENT_TIME (msTime() - startTime) -# define TIME_ON_PROC(p) (msTime() - startTime) -# define CURRENT_PROC thisPE -# define BINARY_STATS RtsFlags.ParFlags.ParStats.Binary -#elif defined(GRAN) -# define NODE_STR_LEN 20 -# define TIME_STR_LEN 120 -# define TIME rtsTime -# define CURRENT_TIME CurrentTime[CurrentProc] -# define TIME_ON_PROC(p) CurrentTime[p] -# define CURRENT_PROC CurrentProc -# define BINARY_STATS RtsFlags.GranFlags.GranSimStats.Binary -#endif - -#if defined(PAR) -# define MAX_PES 256 /* Maximum number of processors */ - /* MAX_PES is enforced by SysMan, which does not - allow more than this many "processors". - This is important because PackGA [GlobAddr.lc] - **assumes** that a PE# can fit in 8+ bits. - */ - -# define SPARK_POOLS 2 /* no. of spark pools */ -# define REQUIRED_POOL 0 /* idx of pool of mandatory sparks (concurrency) */ -# define ADVISORY_POOL 1 /* idx of pool of advisory sparks (parallelism) */ -#endif - -/* - * @menu - * * GUM:: - * * GranSim:: - * @end menu - * - * @node GUM, GranSim, Basic definitions, Parallel definitions - * @subsection GUM - */ - -#if defined(PAR) -/* - Symbolic constants for the packing code. - - This constant defines how many words of data we can pack into a single - packet in the parallel (GUM) system. -*/ - -/* - * @menu - * * Types:: - * * Externs:: - * * Prototypes:: - * * Macros:: - * @end menu - * - * @node Types, Externs, GUM, GUM - * @subsubsection Types - */ - -/* Sparks and spark queues */ -typedef StgClosure *rtsSpark; -typedef rtsSpark *rtsSparkQ; - -typedef struct rtsPackBuffer_ { - StgInt /* nat */ id; - StgInt /* nat */ size; - StgInt /* nat */ unpacked_size; - StgTSO *tso; - StgWord *buffer[0]; -} rtsPackBuffer; - -#define PACK_BUFFER_HDR_SIZE 4 - -/* - * @node Externs, Prototypes, Types, GUM - * @subsubsection Externs - */ - -/* extern rtsBool do_sp_profile; */ - -extern globalAddr theGlobalFromGA, theGlobalToGA; -extern StgBlockedFetch *PendingFetches; -extern GlobalTaskId *allPEs; - -extern rtsBool IAmMainThread, GlobalStopPending; -/*extern rtsBool fishing; */ -extern rtsTime last_fish_arrived_at; -extern nat outstandingFishes; -extern GlobalTaskId SysManTask; -extern int seed; /* pseudo-random-number generator seed: */ - /* Initialised in ParInit */ -extern StgInt threadId; /* Number of Threads that have existed on a PE */ -extern GlobalTaskId mytid; - -extern GlobalTaskId *allPEs; -extern nat nPEs; -extern nat sparksIgnored, sparksCreated, threadsIgnored, threadsCreated; -extern nat advisory_thread_count; - -extern rtsBool InGlobalGC; /* Are we in the midst of performing global GC */ - -extern ullong startTime; /* start of comp; in RtsStartup.c */ - -/* the spark pools proper */ -extern rtsSpark *pending_sparks_hd[]; /* ptr to start of a spark pool */ -extern rtsSpark *pending_sparks_tl[]; /* ptr to end of a spark pool */ -extern rtsSpark *pending_sparks_lim[]; -extern rtsSpark *pending_sparks_base[]; -extern nat spark_limit[]; - -extern rtsPackBuffer *PackBuffer; /* size: can be set via option */ -extern rtsPackBuffer *buffer; -extern rtsPackBuffer *freeBuffer; -extern rtsPackBuffer *packBuffer; -extern rtsPackBuffer *gumPackBuffer; - -extern nat thisPE; - -/* From Global.c -extern GALA *freeGALAList; -extern GALA *freeIndirections; -extern GALA *liveIndirections; -extern GALA *liveRemoteGAs; -*/ - -/* - * @node Prototypes, Macros, Externs, GUM - * @subsubsection Prototypes - */ - -/* From ParInit.c */ -void initParallelSystem(void); -void SynchroniseSystem(void); -void par_exit(StgInt n); - -PEs taskIDtoPE (GlobalTaskId gtid); -void registerTask (GlobalTaskId gtid); -globalAddr *LAGAlookup (StgClosure *addr); -StgClosure *GALAlookup (globalAddr *ga); -/*static GALA *allocIndirection (StgPtr addr); */ -globalAddr *makeGlobal (StgClosure *addr, rtsBool preferred); -globalAddr *setRemoteGA (StgClosure *addr, globalAddr *ga, rtsBool preferred); -void splitWeight (globalAddr *to, globalAddr *from); -globalAddr *addWeight (globalAddr *ga); -void initGAtables (void); -void RebuildLAGAtable (void); -StgWord PackGA (StgWord pe, int slot); - -# if defined(DEBUG) -/* from Global.c */ -/* highest_slot breaks the abstraction of the slot counter for GAs; it is - only used for sanity checking and should used nowhere else */ -StgInt highest_slot (void); -# endif - -/* - * @node Macros, , Prototypes, GUM - * @subsubsection Macros - */ - -/* delay (in us) between dying fish returning and sending out a new fish */ -#define FISH_DELAY 1000 -/* max no. of outstanding spark steals */ -#define MAX_FISHES 1 - -/* ToDo: check which of these is actually needed! */ - -# define PACK_HEAP_REQUIRED ((RtsFlags.ParFlags.packBufferSize - PACK_HDR_SIZE) / (PACK_GA_SIZE + _HS) * (MIN_UPD_SIZE + 2)) - -# define MAX_GAS (RtsFlags.ParFlags.packBufferSize / PACK_GA_SIZE) - - -# define PACK_GA_SIZE 3 /* Size of a packed GA in words */ - /* Size of a packed fetch-me in words */ -# define PACK_FETCHME_SIZE (PACK_GA_SIZE + _HS) - -# define PACK_HDR_SIZE 1 /* Words of header in a packet */ - -# define PACK_PLC_SIZE 2 /* Size of a packed PLC in words */ - -/* - Definitions relating to the entire parallel-only fixed-header field. - - On GUM, the global addresses for each local closure are stored in a - separate hash table, rather then with the closure in the heap. We call - @getGA@ to look up the global address associated with a local closure (0 - is returned for local closures that have no global address), and @setGA@ - to store a new global address for a local closure which did not - previously have one. */ - -# define GA_HDR_SIZE 0 - -# define GA(closure) getGA(closure) - -# define SET_GA(closure, ga) setGA(closure,ga) -# define SET_STATIC_GA(closure) -# define SET_GRAN_HDR(closure,pe) -# define SET_STATIC_PROCS(closure) - -# define MAX_GA_WEIGHT 0 /* Treat as 2^n */ - -/* At the moment, there is no activity profiling for GUM. This may change. */ -# define SET_TASK_ACTIVITY(act) /* nothing */ - -/* - The following macros are only needed for sanity checking (see Sanity.c). -*/ - -/* NB: this is PVM specific and should be updated for MPI etc - in PVM a task id (tid) is split into 2 parts: the id for the - physical processor it is running on and an index of tasks running - on a processor; PVM_PE_MASK indicates which part of a tid holds the - id of the physical processor (the other part of the word holds the - index on that processor) - MAX_PVM_PES and MAX_PVM_TIDS are maximal values for these 2 components - in GUM we have an upper bound for the total number of PVM PEs allowed: - it's MAX_PE defined in Parallel.h - to check the slot field of a GA we call a fct highest_slot which just - returns the internal counter -*/ -#define PVM_PE_MASK 0xfffc0000 -#define MAX_PVM_PES MAX_PES -#define MAX_PVM_TIDS MAX_PES - -#if 0 -#define LOOKS_LIKE_TID(tid) (((tid & PVM_PE_MASK) != 0) && \ - (((tid & PVM_PE_MASK) + (tid & ~PVM_PE_MASK)) < MAX_PVM_TIDS)) -#define LOOKS_LIKE_SLOT(slot) (slot<=highest_slot()) - -#define LOOKS_LIKE_GA(ga) (LOOKS_LIKE_TID((ga)->payload.gc.gtid) && \ - LOOKS_LIKE_SLOT((ga)->payload.gc.slot)) -#else -rtsBool looks_like_tid(StgInt tid); -rtsBool looks_like_slot(StgInt slot); -rtsBool looks_like_ga(globalAddr *ga); -#define LOOKS_LIKE_TID(tid) looks_like_tid(tid) -#define LOOKS_LIKE_GA(ga) looks_like_ga(ga) -#endif /* 0 */ - -#endif /* PAR */ - -/* - * @node GranSim, , GUM, Parallel definitions - * @subsection GranSim - */ - -#if defined(GRAN) -/* ToDo: Check which of the PAR routines are needed in GranSim -- HWL */ - -/* - * @menu - * * Types:: - * * Prototypes:: - * * Macros:: - * @end menu - * - * @node Types, Prototypes, GranSim, GranSim - * @subsubsection Types - */ - -typedef StgWord *StgBuffer; -typedef struct rtsPackBuffer_ { - StgInt /* nat */ id; - StgInt /* nat */ size; - StgInt /* nat */ unpacked_size; - StgTSO *tso; - StgWord *buffer; -} rtsPackBuffer; - -/* - * @node Macros, , Prototypes, GranSim - * @subsubsection Macros - */ - -/* max no. of outstanding spark steals */ -#define MAX_FISHES 1 - -/* These are needed in the packing code to get the size of the packet - right. The closures itself are never built in GrAnSim. */ -# define FETCHME_VHS IND_VHS -# define FETCHME_HS IND_HS - -# define FETCHME_GA_LOCN FETCHME_HS - -# define FETCHME_CLOSURE_SIZE(closure) IND_CLOSURE_SIZE(closure) -# define FETCHME_CLOSURE_NoPTRS(closure) 0L -# define FETCHME_CLOSURE_NoNONPTRS(closure) (IND_CLOSURE_SIZE(closure)-IND_VHS) - -# define MAX_GAS (RtsFlags.GranFlags.packBufferSize / PACK_GA_SIZE) -# define PACK_GA_SIZE 3 /* Size of a packed GA in words */ - /* Size of a packed fetch-me in words */ -# define PACK_FETCHME_SIZE (PACK_GA_SIZE + _HS) -# define PACK_HDR_SIZE 4 /* Words of header in a packet */ - -# define PACK_HEAP_REQUIRED \ - (RtsFlags.GranFlags.packBufferSize * sizeofW(StgClosure*) + \ - 2 * sizeofW(StgInt) + sizeofW(StgTSO*)) - -# define PACK_FLAG_LOCN 0 -# define PACK_TSO_LOCN 1 -# define PACK_UNPACKED_SIZE_LOCN 2 -# define PACK_SIZE_LOCN 3 -# define MAGIC_PACK_FLAG 0xfabc - -# define GA_HDR_SIZE 1 - -# define PROCS_HDR_POSN PAR_HDR_POSN -# define PROCS_HDR_SIZE 1 - -/* Accessing components of the field */ -# define PROCS(closure) ((closure)->header.gran.procs) -/* SET_PROCS is now SET_GRAN_HEADER in ClosureMacros.h. */ - -#endif /* GRAN */ - -/* - * @node End of File, , Parallel definitions - * @section End of File - */ - -#endif /* defined(PAR) || defined(GRAN) whole file */ - -#endif /* Parallel_H */ - - diff --git a/includes/README b/includes/README index 90695a6e7c..dbde6579f4 100644 --- a/includes/README +++ b/includes/README @@ -83,17 +83,14 @@ Rts.h SpinLock.h TSO.h Updates.h /* macros for performing updates */ - GranSim.h Parallel.h Block.h Stable.h Hooks.h Signals.h - DNInvoke.h - Dotnet.h - RtsExternal.h /* decls for RTS things required by .hc code */ - (RtsAPI.h) - (HsFFI.h) + Adjustor.h /* foreign import "wrapper", aka adjustors */ + StgPrimFloat.h /* primitive floating-point operations */ + Hpc.h Cmm.h /* included into .cmm source only */ DerivedConstants.h /* generated by mkDerivedConstants.c from other */ diff --git a/includes/Rts.h b/includes/Rts.h index a32bf34309..7358c368c1 100644 --- a/includes/Rts.h +++ b/includes/Rts.h @@ -1,8 +1,9 @@ /* ----------------------------------------------------------------------------- * - * (c) The GHC Team, 1998-2004 + * (c) The GHC Team, 1998-2009 * - * Top-level include file for the RTS itself + * RTS external APIs. This file declares everything that the GHC RTS + * exposes externally. * * ---------------------------------------------------------------------------*/ @@ -18,8 +19,8 @@ extern "C" { #endif #include "Stg.h" -// ToDo: move RtsExternal stuff elsewhere -#include "RtsExternal.h" +#include "HsFFI.h" +#include "RtsAPI.h" // Turn off inlining when debugging - it obfuscates things #ifdef DEBUG @@ -27,7 +28,7 @@ extern "C" { # define STATIC_INLINE static #endif -#include "RtsTypes.h" +#include "rts/Types.h" #if __GNUC__ >= 3 /* Assume that a flexible array member at the end of a struct @@ -63,11 +64,6 @@ extern "C" { #define sizeofW(t) ROUNDUP_BYTES_TO_WDS(sizeof(t)) -/* - * It's nice to be able to grep for casts - */ -#define stgCast(ty,e) ((ty)(e)) - /* ----------------------------------------------------------------------------- Assertions and Debuggery @@ -75,7 +71,8 @@ extern "C" { ASSERT(p) like CHECK(p) if DEBUG is on, otherwise a no-op -------------------------------------------------------------------------- */ -extern void _assertFail (const char *, unsigned int); +void _assertFail(const char *filename, unsigned int linenum) + GNUC3_ATTRIBUTE(__noreturn__); #define CHECK(predicate) \ if (predicate) \ @@ -124,29 +121,6 @@ extern void _assertFail (const char *, unsigned int); #define FMT_Int64 "lld" #endif -/* - * Macros for untagging and retagging closure pointers - * For more information look at the comments in Cmm.h - */ - -static inline StgWord -GET_CLOSURE_TAG(StgClosure * p) -{ - return (StgWord)p & TAG_MASK; -} - -static inline StgClosure * -UNTAG_CLOSURE(StgClosure * p) -{ - return (StgClosure*)((StgWord)p & ~TAG_MASK); -} - -static inline StgClosure * -TAG_CLOSURE(StgWord tag,StgClosure * p) -{ - return (StgClosure*)((StgWord)p | tag); -} - /* ----------------------------------------------------------------------------- Include everything STG-ish -------------------------------------------------------------------------- */ @@ -158,59 +132,62 @@ TAG_CLOSURE(StgWord tag,StgClosure * p) */ #include <stdlib.h> +#include "rts/Config.h" + /* Global constaints */ -#include "Constants.h" +#include "rts/Constants.h" /* Profiling information */ -#include "StgProf.h" -#include "StgLdvProf.h" - -/* Storage format definitions */ -#include "StgFun.h" -#include "Closures.h" -#include "Liveness.h" -#include "ClosureTypes.h" -#include "InfoTables.h" -#include "TSO.h" - -/* Info tables, closures & code fragments defined in the RTS */ -#include "StgMiscClosures.h" +#include "rts/prof/CCS.h" +#include "rts/prof/LDV.h" /* Parallel information */ -#include "OSThreads.h" -#include "SMPClosureOps.h" -#include "SpinLock.h" - -/* Macros for STG/C code */ -#include "Block.h" -#include "ClosureMacros.h" - -/* Runtime-system hooks */ -#include "Hooks.h" -#include "RtsMessages.h" +#include "rts/OSThreads.h" +#include "rts/SpinLock.h" -/* for StablePtr/getStablePtr/deRefStablePtr */ -#include "Storage.h" -#include "Stable.h" +#include "rts/Messages.h" -#include "ieee-flpt.h" - -#include "Signals.h" +/* Storage format definitions */ +#include "rts/storage/FunTypes.h" +#include "rts/storage/InfoTables.h" +#include "rts/storage/Closures.h" +#include "rts/storage/Liveness.h" +#include "rts/storage/ClosureTypes.h" +#include "rts/storage/TSO.h" +#include "stg/MiscClosures.h" /* InfoTables, closures etc. defined in the RTS */ +#include "rts/storage/SMPClosureOps.h" +#include "rts/storage/Block.h" +#include "rts/storage/ClosureMacros.h" +#include "rts/storage/MBlock.h" +#include "rts/storage/GC.h" + +/* Other RTS external APIs */ +#include "rts/Parallel.h" +#include "rts/Hooks.h" +#include "rts/Signals.h" +#include "rts/Hpc.h" +#include "rts/Flags.h" +#include "rts/Adjustor.h" +#include "rts/FileLock.h" +#include "rts/Globals.h" +#include "rts/IOManager.h" +#include "rts/Linker.h" +#include "rts/Threads.h" +#include "rts/Timer.h" +#include "rts/Stable.h" /* Misc stuff without a home */ DLL_IMPORT_RTS extern char **prog_argv; /* so we can get at these from Haskell */ DLL_IMPORT_RTS extern int prog_argc; DLL_IMPORT_RTS extern char *prog_name; -extern void stackOverflow(void); - -extern void __decodeDouble_2Int (I_ *man_sign, W_ *man_high, W_ *man_low, I_ *exp, StgDouble dbl); -extern void __decodeFloat_Int (I_ *man, I_ *exp, StgFloat flt); +void stackOverflow(void); -/* Initialising the whole adjustor thunk machinery. */ -extern void initAdjustor(void); +void stg_exit(int n) GNU_ATTRIBUTE(__noreturn__); -extern void stg_exit(int n) GNU_ATTRIBUTE(__noreturn__); +#ifndef mingw32_HOST_OS +int stg_sig_install (int, int, void *); +#endif /* ----------------------------------------------------------------------------- RTS Exit codes @@ -236,11 +213,6 @@ extern void stg_exit(int n) GNU_ATTRIBUTE(__noreturn__); extern StgInt RIGHT_ARITY_##arity; \ extern StgInt TAGGED_PTR_##arity; -#define TICK_VAR_INI(arity) \ - StgInt SLOW_CALLS_##arity = 1; \ - StgInt RIGHT_ARITY_##arity = 1; \ - StgInt TAGGED_PTR_##arity = 0; - extern StgInt TOTAL_CALLS; TICK_VAR(1) @@ -253,10 +225,6 @@ TICK_VAR(2) #define IF_RTSFLAGS(c,s) if (RtsFlags.c) { s; } -/* ----------------------------------------------------------------------------- - Assertions and Debuggery - -------------------------------------------------------------------------- */ - #ifdef DEBUG #if IN_STG_CODE #define IF_DEBUG(c,s) if (RtsFlags[0].DebugFlags.c) { s; } diff --git a/includes/RtsAPI.h b/includes/RtsAPI.h index 5160046da8..2d2c35ca97 100644 --- a/includes/RtsAPI.h +++ b/includes/RtsAPI.h @@ -26,7 +26,7 @@ typedef enum { HeapExhausted /* out of memory */ } SchedulerStatus; -typedef StgClosure *HaskellObj; +typedef struct StgClosure_ *HaskellObj; /* * An abstract type representing the token returned by rts_lock() and diff --git a/includes/RtsConfig.h b/includes/RtsConfig.h deleted file mode 100644 index 3b088b7417..0000000000 --- a/includes/RtsConfig.h +++ /dev/null @@ -1,64 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) The GHC Team, 1998-2004 - * - * Rts settings. - * - * NOTE: assumes #include "ghcconfig.h" - * - * NB: THIS FILE IS INCLUDED IN NON-C CODE AND DATA! #defines only please. - * ---------------------------------------------------------------------------*/ - -#ifndef RTSCONFIG_H -#define RTSCONFIG_H - -/* - * SUPPORT_LONG_LONGS controls whether we need to support long longs on a - * particular platform. On 64-bit platforms, we don't need to support - * long longs since regular machine words will do just fine. - */ -#if HAVE_LONG_LONG && SIZEOF_VOID_P < 8 -#define SUPPORT_LONG_LONGS 1 -#endif - -/* - * Whether the runtime system will use libbfd for debugging purposes. - */ -#if defined(DEBUG) && defined(HAVE_BFD_H) && defined(HAVE_LIBBFD) && !defined(_WIN32) -#define USING_LIBBFD 1 -#endif - -/* ----------------------------------------------------------------------------- - Labels - entry labels & info labels point to the same place in - TABLES_NEXT_TO_CODE, so we only generate the _info label. Jumps - must therefore be directed to foo_info rather than foo_entry when - TABLES_NEXT_TO_CODE is on. - - This isn't a good place for these macros, but they need to be - available to .cmm sources as well as C and we don't have a better - place. - -------------------------------------------------------------------------- */ - -#ifdef TABLES_NEXT_TO_CODE -#define ENTRY_LBL(f) f##_info -#else -#define ENTRY_LBL(f) f##_entry -#endif - -#ifdef TABLES_NEXT_TO_CODE -#define RET_LBL(f) f##_info -#else -#define RET_LBL(f) f##_ret -#endif - -/* ----------------------------------------------------------------------------- - Signals - supported on non-PAR versions of the runtime. See RtsSignals.h. - -------------------------------------------------------------------------- */ - -#define RTS_USER_SIGNALS 1 - -/* Profile spin locks */ - -#define PROF_SPIN - -#endif /* RTSCONFIG_H */ diff --git a/includes/RtsExternal.h b/includes/RtsExternal.h deleted file mode 100644 index 2272b2a429..0000000000 --- a/includes/RtsExternal.h +++ /dev/null @@ -1,129 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) The GHC Team, 1998-2004 - * - * Things visible externally to the RTS - * - * -------------------------------------------------------------------------- */ - -#ifndef RTSEXTERNAL_H -#define RTSEXTERNAL_H - -/* The RTS public interface. */ -#include "RtsAPI.h" - -/* The standard FFI interface */ -#include "HsFFI.h" - -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -/* ----------------------------------------------------------------------------- - Functions exported by the RTS for use in Stg code - -------------------------------------------------------------------------- */ - -#if IN_STG_CODE -extern void newCAF(void*); -#else -extern void newCAF(StgClosure*); -#endif - -/* ToDo: remove? */ -extern HsInt genSymZh(void); -extern HsInt resetGenSymZh(void); - -/* Alternate to raise(3) for threaded rts, for OpenBSD */ -extern int genericRaise(int sig); - -/* Concurrency/Exception PrimOps. */ -extern int cmp_thread(StgPtr tso1, StgPtr tso2); -extern int rts_getThreadId(StgPtr tso); -extern int forkOS_createThread ( HsStablePtr entry ); -extern pid_t forkProcess(HsStablePtr *entry); -extern HsBool rtsSupportsBoundThreads(void); -extern StgInt newSpark (StgRegTable *reg, StgClosure *p); -extern void stopTimer(void); -extern unsigned int n_capabilities; - -/* grimy low-level support functions defined in StgPrimFloat.c */ -extern StgDouble __encodeDouble (I_ size, StgByteArray arr, I_ e); -extern StgDouble __2Int_encodeDouble (I_ j_high, I_ j_low, I_ e); -extern StgDouble __int_encodeDouble (I_ j, I_ e); -extern StgDouble __word_encodeDouble (W_ j, I_ e); -extern StgFloat __encodeFloat (I_ size, StgByteArray arr, I_ e); -extern StgFloat __int_encodeFloat (I_ j, I_ e); -extern StgFloat __word_encodeFloat (W_ j, I_ e); -extern StgInt isDoubleNaN(StgDouble d); -extern StgInt isDoubleInfinite(StgDouble d); -extern StgInt isDoubleDenormalized(StgDouble d); -extern StgInt isDoubleNegativeZero(StgDouble d); -extern StgInt isFloatNaN(StgFloat f); -extern StgInt isFloatInfinite(StgFloat f); -extern StgInt isFloatDenormalized(StgFloat f); -extern StgInt isFloatNegativeZero(StgFloat f); - -/* Suspending/resuming threads around foreign calls */ -extern void * suspendThread ( StgRegTable * ); -extern StgRegTable * resumeThread ( void * ); - -/* scheduler stuff */ -extern void stg_scheduleThread (StgRegTable *reg, struct StgTSO_ *tso); - -/* Creating and destroying an adjustor thunk */ -extern void* createAdjustor(int cconv, StgStablePtr hptr, StgFunPtr wptr, - char *typeString); -extern void freeHaskellFunctionPtr(void* ptr); - -/* Hpc stuff */ -extern int hs_hpc_module(char *modName, StgWord32 modCount, StgWord32 modHashNo,StgWord64 *tixArr); -// Simple linked list of modules -typedef struct _HpcModuleInfo { - char *modName; // name of module - StgWord32 tickCount; // number of ticks - StgWord32 tickOffset; // offset into a single large .tix Array - StgWord32 hashNo; // Hash number for this module's mix info - StgWord64 *tixArr; // tix Array; local for this module - struct _HpcModuleInfo *next; -} HpcModuleInfo; - -extern HpcModuleInfo *hs_hpc_rootModule(void); - - -#if defined(mingw32_HOST_OS) -extern int rts_InstallConsoleEvent ( int action, StgStablePtr *handler ); -extern void rts_ConsoleHandlerDone ( int ev ); -#else -extern int stg_sig_install (int, int, void *); -#endif - -#if defined(mingw32_HOST_OS) -extern StgInt console_handler; -#else -extern StgInt *signal_handlers; -#endif - -#if defined(mingw32_HOST_OS) -void *getIOManagerEvent (void); -HsWord32 readIOManagerEvent (void); -void sendIOManagerEvent (HsWord32 event); -#else -extern void setIOManagerPipe (int fd); -#endif - -extern void* allocateExec(unsigned int len, void **exec_addr); - -// Breakpoint stuff - -/* ----------------------------------------------------------------------------- - Storage manager stuff exported - -------------------------------------------------------------------------- */ - -extern void performGC(void); -extern void performMajorGC(void); -extern HsInt64 getAllocations( void ); -extern void revertCAFs( void ); -extern void dirty_MUT_VAR(StgRegTable *reg, StgClosure *p); -extern void dirty_MVAR(StgRegTable *reg, StgClosure *p); - -#endif /* RTSEXTERNAL_H */ diff --git a/includes/RtsFlags.h b/includes/RtsFlags.h index ab6f2982cd..778fccf40a 100644 --- a/includes/RtsFlags.h +++ b/includes/RtsFlags.h @@ -1,239 +1,2 @@ -/* ----------------------------------------------------------------------------- - * - * (c) The GHC Team, 1998-1999 - * - * Datatypes that holds the command-line flag settings. - * - * ---------------------------------------------------------------------------*/ - -#ifndef RTSFLAGS_H -#define RTSFLAGS_H - -#include <stdio.h> - -/* For defaults, see the @initRtsFlagsDefaults@ routine. */ - -struct GC_FLAGS { - FILE *statsFile; - nat giveStats; -#define NO_GC_STATS 0 -#define COLLECT_GC_STATS 1 -#define ONELINE_GC_STATS 2 -#define SUMMARY_GC_STATS 3 -#define VERBOSE_GC_STATS 4 - - nat maxStkSize; /* in *words* */ - nat initialStkSize; /* in *words* */ - - nat maxHeapSize; /* in *blocks* */ - nat minAllocAreaSize; /* in *blocks* */ - nat minOldGenSize; /* in *blocks* */ - nat heapSizeSuggestion; /* in *blocks* */ - double oldGenFactor; - double pcFreeHeap; - - nat generations; - nat steps; - rtsBool squeezeUpdFrames; - - rtsBool compact; /* True <=> "compact all the time" */ - double compactThreshold; - - rtsBool sweep; /* use "mostly mark-sweep" instead of copying - * for the oldest generation */ - rtsBool ringBell; - rtsBool frontpanel; - - int idleGCDelayTime; /* in milliseconds */ - - StgWord heapBase; /* address to ask the OS for memory */ -}; - -struct DEBUG_FLAGS { - /* flags to control debugging output & extra checking in various subsystems */ - rtsBool scheduler; /* 's' */ - rtsBool interpreter; /* 'i' */ - rtsBool weak; /* 'w' */ - rtsBool gccafs; /* 'G' */ - rtsBool gc; /* 'g' */ - rtsBool block_alloc; /* 'b' */ - rtsBool sanity; /* 'S' warning: might be expensive! */ - rtsBool stable; /* 't' */ - rtsBool prof; /* 'p' */ - rtsBool eventlog; /* 'e' */ - rtsBool linker; /* 'l' the object linker */ - rtsBool apply; /* 'a' */ - rtsBool stm; /* 'm' */ - rtsBool squeeze; /* 'z' stack squeezing & lazy blackholing */ - rtsBool hpc; /* 'c' coverage */ - rtsBool timestamp; /* add timestamps to traces */ -}; - -struct COST_CENTRE_FLAGS { - unsigned int doCostCentres; -# define COST_CENTRES_SUMMARY 1 -# define COST_CENTRES_VERBOSE 2 /* incl. serial time profile */ -# define COST_CENTRES_ALL 3 -# define COST_CENTRES_XML 4 - - int profilerTicks; /* derived */ - int msecsPerTick; /* derived */ -}; - -struct PROFILING_FLAGS { - unsigned int doHeapProfile; -# define NO_HEAP_PROFILING 0 /* N.B. Used as indexes into arrays */ -# define HEAP_BY_CCS 1 -# define HEAP_BY_MOD 2 -# define HEAP_BY_DESCR 4 -# define HEAP_BY_TYPE 5 -# define HEAP_BY_RETAINER 6 -# define HEAP_BY_LDV 7 - -# define HEAP_BY_CLOSURE_TYPE 8 - - nat profileInterval; /* delta between samples (in ms) */ - nat profileIntervalTicks; /* delta between samples (in 'ticks') */ - rtsBool includeTSOs; - - - rtsBool showCCSOnException; - - nat maxRetainerSetSize; - - nat ccsLength; - - char* modSelector; - char* descrSelector; - char* typeSelector; - char* ccSelector; - char* ccsSelector; - char* retainerSelector; - char* bioSelector; - -}; - -#ifdef EVENTLOG -struct EVENTLOG_FLAGS { - rtsBool doEventLogging; -}; -#endif - -struct CONCURRENT_FLAGS { - int ctxtSwitchTime; /* in milliseconds */ - int ctxtSwitchTicks; /* derived */ -}; - -struct MISC_FLAGS { - int tickInterval; /* in milliseconds */ - rtsBool install_signal_handlers; - rtsBool machineReadable; - StgWord linkerMemBase; /* address to ask the OS for memory - * for the linker, NULL ==> off */ -}; - -#ifdef THREADED_RTS -struct PAR_FLAGS { - nat nNodes; /* number of threads to run simultaneously */ - rtsBool migrate; /* migrate threads between capabilities */ - rtsBool wakeupMigrate; /* migrate a thread on wakeup */ - unsigned int maxLocalSparks; - rtsBool parGcEnabled; /* enable parallel GC */ - rtsBool parGcGen; /* do parallel GC in this generation - * and higher only */ - rtsBool parGcLoadBalancing; /* do load-balancing in parallel GC */ - rtsBool setAffinity; /* force thread affinity with CPUs */ -}; -#endif /* THREADED_RTS */ - -struct TICKY_FLAGS { - rtsBool showTickyStats; - FILE *tickyFile; -}; - -#ifdef USE_PAPI -#define MAX_PAPI_USER_EVENTS 8 - -struct PAPI_FLAGS { - nat eventType; /* The type of events to count */ - nat numUserEvents; - char * userEvents[MAX_PAPI_USER_EVENTS]; -}; - -#define PAPI_FLAG_CACHE_L1 1 -#define PAPI_FLAG_CACHE_L2 2 -#define PAPI_FLAG_BRANCH 3 -#define PAPI_FLAG_STALLS 4 -#define PAPI_FLAG_CB_EVENTS 5 -#define PAPI_USER_EVENTS 6 - -#endif - -/* Put them together: */ - -typedef struct _RTS_FLAGS { - /* The first portion of RTS_FLAGS is invariant. */ - struct GC_FLAGS GcFlags; - struct CONCURRENT_FLAGS ConcFlags; - struct MISC_FLAGS MiscFlags; - struct DEBUG_FLAGS DebugFlags; - struct COST_CENTRE_FLAGS CcFlags; - struct PROFILING_FLAGS ProfFlags; -#ifdef EVENTLOG - struct EVENTLOG_FLAGS EventLogFlags; -#endif - struct TICKY_FLAGS TickyFlags; - -#if defined(THREADED_RTS) - struct PAR_FLAGS ParFlags; -#endif -#ifdef USE_PAPI - struct PAPI_FLAGS PapiFlags; -#endif -} RTS_FLAGS; - -#ifdef COMPILING_RTS_MAIN -extern DLLIMPORT RTS_FLAGS RtsFlags; -#elif IN_STG_CODE -/* Hack because the C code generator can't generate '&label'. */ -extern RTS_FLAGS RtsFlags[]; -#else -extern RTS_FLAGS RtsFlags; -#endif - -/* Routines that operate-on/to-do-with RTS flags: */ - -extern void initRtsFlagsDefaults(void); -extern void setupRtsFlags(int *argc, char *argv[], int *rts_argc, char *rts_argv[]); -extern void setProgName(char *argv[]); - - -/* - * The printf formats are here, so we are less likely to make - * overly-long filenames (with disastrous results). No more than 128 - * chars, please! - */ - -#define STATS_FILENAME_MAXLEN 128 - -#define GR_FILENAME_FMT "%0.124s.gr" -#define GR_FILENAME_FMT_GUM "%0.120s.%03d.%s" -#define HP_FILENAME_FMT "%0.124s.hp" -#define LIFE_FILENAME_FMT "%0.122s.life" -#define PROF_FILENAME_FMT "%0.122s.prof" -#define PROF_FILENAME_FMT_GUM "%0.118s.%03d.prof" -#define QP_FILENAME_FMT "%0.124s.qp" -#define STAT_FILENAME_FMT "%0.122s.stat" -#define TICKY_FILENAME_FMT "%0.121s.ticky" -#define TIME_FILENAME_FMT "%0.122s.time" -#define TIME_FILENAME_FMT_GUM "%0.118s.%03d.time" - -/* an "int" so as to match normal "argc" */ -/* Now defined in Stg.h (lib/std/cbits need these too.) -extern int prog_argc; -extern char **prog_argv; -*/ -extern int rts_argc; /* ditto */ -extern char *rts_argv[]; - -#endif /* RTSFLAGS_H */ +#warning RtsFlags.h is DEPRECATED; please just #include "Rts.h" +#include "Rts.h" diff --git a/includes/STM.h b/includes/STM.h deleted file mode 100644 index 3bf976551d..0000000000 --- a/includes/STM.h +++ /dev/null @@ -1,245 +0,0 @@ -/*---------------------------------------------------------------------- - * - * (c) The GHC Team, 1998-2004 - * - * STM interface definition - * - *---------------------------------------------------------------------- - - STM.h defines the C-level interface to the STM. - - The design follows that of the PPoPP 2005 paper "Composable memory - transactions" extended to include fine-grained locking of TVars. - - Three different implementations can be built. In overview: - - STM_UNIPROC -- no locking at all: not safe for concurrent invocations - - STM_CG_LOCK -- coarse-grained locking : a single mutex protects all - TVars - - STM_FG_LOCKS -- per-TVar exclusion : each TVar can be owned by at - most one TRec at any time. This allows dynamically - non-conflicting transactions to commit in parallel. - The implementation treats reads optimisitcally -- - extra versioning information is retained in the - saw_update_by field of the TVars so that they do not - need to be locked for reading. - - STM.C contains more details about the locking schemes used. - -*/ - -#ifndef STM_H -#define STM_H - -#ifdef THREADED_RTS -//#define STM_CG_LOCK -#define STM_FG_LOCKS -#else -#define STM_UNIPROC -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/*---------------------------------------------------------------------- - - GC interaction - -------------- -*/ - -extern void stmPreGCHook(void); - -/*---------------------------------------------------------------------- - - Transaction context management - ------------------------------ - -*/ - -/* Create and enter a new transaction context */ - -extern StgTRecHeader *stmStartTransaction(Capability *cap, StgTRecHeader *outer); -extern StgTRecHeader *stmStartNestedTransaction(Capability *cap, StgTRecHeader *outer -); - -/* - * Roll back the current transatcion context. NB: if this is a nested tx - * then we merge its read set into its parents. This is because a change - * to that read set could change whether or not the tx should abort. - */ - -extern void stmAbortTransaction(Capability *cap, StgTRecHeader *trec); -extern void stmFreeAbortedTRec(Capability *cap, StgTRecHeader *trec); - -/* - * Ensure that a subsequent commit / validation will fail. We use this - * in our current handling of transactions that may have become invalid - * and started looping. We strip their stack back to the ATOMICALLY_FRAME, - * and, when the thread is next scheduled, discover it to be invalid and - * re-execute it. However, we need to force the transaction to stay invalid - * in case other threads' updates make it valid in the mean time. - */ - -extern void stmCondemnTransaction(Capability *cap, StgTRecHeader *trec); - -/* - * Return the trec within which the specified trec was created (not - * valid if trec==NO_TREC). - */ - -extern StgTRecHeader *stmGetEnclosingTRec(StgTRecHeader *trec); - -/*---------------------------------------------------------------------- - - Validation - ---------- - - Test whether the specified transaction record, and all those within which - it is nested, are still valid. - - Note: the caller can assume that once stmValidateTransaction has - returned FALSE for a given trec then that transaction will never - again be valid -- we rely on this in Schedule.c when kicking invalid - threads at GC (in case they are stuck looping) -*/ - -extern StgBool stmValidateNestOfTransactions(StgTRecHeader *trec); - -/*---------------------------------------------------------------------- - - Commit/wait/rewait operations - ----------------------------- - - These four operations return boolean results which should be interpreted - as follows: - - true => The transaction record was definitely valid - - false => The transaction record may not have been valid - - Note that, for nested operations, validity here is solely in terms - of the specified trec: it does not say whether those that it may be - nested are themselves valid. Callers can check this with - stmValidateNestOfTransactions. - - The user of the STM should ensure that it is always safe to assume that a - transaction context is not valid when in fact it is (i.e. to return false in - place of true, with side-effects as defined below). This may cause - needless retries of transactions (in the case of validate and commit), or it - may cause needless spinning instead of blocking (in the case of wait and - rewait). - - In defining the behaviour of wait and rewait we distinguish between two - different aspects of a thread's runnability: - - - We say that a thread is "blocked" when it is not running or - runnable as far as the scheduler is concerned. - - - We say that a thread is "waiting" when its StgTRecHeader is linked on an - tvar's wait queue. - - Considering only STM operations, (blocked) => (waiting). The user of the STM - should ensure that they are prepared for threads to be unblocked spuriously - and for wait/reWait to return false even when the previous transaction context - is actually still valid. -*/ - -/* - * Fill in the trec's list of invariants that might be violated by the current - * transaction. - */ - -extern StgInvariantCheckQueue *stmGetInvariantsToCheck(Capability *cap, - StgTRecHeader *trec); - -extern void stmAddInvariantToCheck(Capability *cap, - StgTRecHeader *trec, - StgClosure *code); - -/* - * Test whether the current transaction context is valid and, if so, - * commit its memory accesses to the heap. stmCommitTransaction must - * unblock any threads which are waiting on tvars that updates have - * been committed to. - */ - -extern StgBool stmCommitTransaction(Capability *cap, StgTRecHeader *trec); -extern StgBool stmCommitNestedTransaction(Capability *cap, StgTRecHeader *trec); - -/* - * Test whether the current transaction context is valid and, if so, - * start the thread waiting for updates to any of the tvars it has - * ready from and mark it as blocked. It is an error to call stmWait - * if the thread is already waiting. - */ - -extern StgBool stmWait(Capability *cap, - StgTSO *tso, - StgTRecHeader *trec); - -extern void stmWaitUnlock(Capability *cap, StgTRecHeader *trec); - -/* - * Test whether the current transaction context is valid and, if so, - * leave the thread waiting and mark it as blocked again. If the - * transaction context is no longer valid then stop the thread waiting - * and leave it as unblocked. It is an error to call stmReWait if the - * thread is not waiting. - */ - -extern StgBool stmReWait(Capability *cap, StgTSO *tso); - -/*---------------------------------------------------------------------- - - TVar management operations - -------------------------- -*/ - -extern StgTVar *stmNewTVar(Capability *cap, - StgClosure *new_value); - -/*---------------------------------------------------------------------- - - Data access operations - ---------------------- -*/ - -/* - * Return the logical contents of 'tvar' within the context of the - * thread's current transaction. - */ - -extern StgClosure *stmReadTVar(Capability *cap, - StgTRecHeader *trec, - StgTVar *tvar); - -/* Update the logical contents of 'tvar' within the context of the - * thread's current transaction. - */ - -extern void stmWriteTVar(Capability *cap, - StgTRecHeader *trec, - StgTVar *tvar, - StgClosure *new_value); - -/*----------------------------------------------------------------------*/ - -/* NULLs */ - -#define END_STM_WATCH_QUEUE ((StgTVarWatchQueue *)(void *)&stg_END_STM_WATCH_QUEUE_closure) -#define END_INVARIANT_CHECK_QUEUE ((StgInvariantCheckQueue *)(void *)&stg_END_INVARIANT_CHECK_QUEUE_closure) -#define END_STM_CHUNK_LIST ((StgTRecChunk *)(void *)&stg_END_STM_CHUNK_LIST_closure) - -#define NO_TREC ((StgTRecHeader *)(void *)&stg_NO_TREC_closure) - -/*----------------------------------------------------------------------*/ - -#ifdef __cplusplus -} -#endif - -#endif /* STM_H */ - diff --git a/includes/Stable.h b/includes/Stable.h deleted file mode 100644 index 9752a534bb..0000000000 --- a/includes/Stable.h +++ /dev/null @@ -1,63 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) The GHC Team, 1998-2004 - * - * Stable Pointers: A stable pointer is represented as an index into - * the stable pointer table in the low BITS_PER_WORD-8 bits with a - * weight in the upper 8 bits. - * - * SUP: StgStablePtr used to be a synonym for StgWord, but stable pointers - * are guaranteed to be void* on the C-side, so we have to do some occasional - * casting. Size is not a matter, because StgWord is always the same size as - * a void*. - * - * ---------------------------------------------------------------------------*/ - -#ifndef STABLE_H -#define STABLE_H - -/* ----------------------------------------------------------------------------- - External C Interface - -------------------------------------------------------------------------- */ - -EXTERN_INLINE StgPtr deRefStablePtr(StgStablePtr stable_ptr); -extern void freeStablePtr(StgStablePtr sp); -extern StgStablePtr splitStablePtr(StgStablePtr sp); -extern StgStablePtr getStablePtr(StgPtr p); - -/* ----------------------------------------------------------------------------- - PRIVATE from here. - -------------------------------------------------------------------------- */ - -typedef struct { - StgPtr addr; /* Haskell object, free list, or NULL */ - StgPtr old; /* old Haskell object, used during GC */ - StgWord ref; /* used for reference counting */ - StgClosure *sn_obj; /* the StableName object (or NULL) */ -} snEntry; - -extern DLL_IMPORT_RTS snEntry *stable_ptr_table; - -extern void freeStablePtr(StgStablePtr sp); - -EXTERN_INLINE -StgPtr deRefStablePtr(StgStablePtr sp) -{ - ASSERT(stable_ptr_table[(StgWord)sp].ref > 0); - return stable_ptr_table[(StgWord)sp].addr; -} - -extern void initStablePtrTable ( void ); -extern void exitStablePtrTable ( void ); -extern void enlargeStablePtrTable ( void ); -extern StgWord lookupStableName ( StgPtr p ); - -extern void markStablePtrTable ( evac_fn evac, void *user ); -extern void threadStablePtrTable ( evac_fn evac, void *user ); -extern void gcStablePtrTable ( void ); -extern void updateStablePtrTable ( rtsBool full ); - -extern void stablePtrPreGC ( void ); -extern void stablePtrPostGC ( void ); - -#endif diff --git a/includes/Stg.h b/includes/Stg.h index 06a866256e..0344b70fd2 100644 --- a/includes/Stg.h +++ b/includes/Stg.h @@ -23,11 +23,16 @@ #ifndef STG_H #define STG_H - -/* If we include "Stg.h" directly, we're in STG code, and we therefore - * get all the global register variables, macros etc. that go along - * with that. If "Stg.h" is included via "Rts.h", we're assumed to - * be in vanilla C. +/* + * If we are compiling a .hc file, then we want all the register + * variables. This is the what happens if you #include "Stg.h" first: + * we assume this is a .hc file, and set IN_STG_CODE==1, which later + * causes the register variables to be enabled in stg/Regs.h. + * + * If instead "Rts.h" is included first, then we are compiling a + * vanilla C file. Everything from Stg.h is provided, except that + * IN_STG_CODE is not defined, and the register variables will not be + * active. */ #ifndef IN_STG_CODE # define IN_STG_CODE 1 @@ -47,7 +52,6 @@ /* Configuration */ #include "ghcconfig.h" -#include "RtsConfig.h" /* The code generator calls the math functions directly in .hc code. NB. after configuration stuff above, because this sets #defines @@ -59,7 +63,7 @@ -------------------------------------------------------------------------- */ /* - * The C backend like to refer to labels by just mentioning their + * The C backend likes to refer to labels by just mentioning their * names. Howevver, when a symbol is declared as a variable in C, the * C compiler will implicitly dereference it when it occurs in source. * So we must subvert this behaviour for .hc files by declaring @@ -165,7 +169,7 @@ -------------------------------------------------------------------------- */ #include "MachDeps.h" -#include "StgTypes.h" +#include "stg/Types.h" /* ----------------------------------------------------------------------------- Shorthand forms @@ -174,24 +178,14 @@ typedef StgChar C_; typedef StgWord W_; typedef StgWord* P_; -typedef P_* PP_; typedef StgInt I_; -typedef StgAddr A_; -typedef const StgWord* D_; -typedef StgFunPtr F_; -typedef StgByteArray B_; -typedef StgClosurePtr L_; - -typedef StgInt64 LI_; -typedef StgWord64 LW_; - -#define IF_(f) static F_ GNUC3_ATTRIBUTE(used) f(void) -#define FN_(f) F_ f(void) -#define EF_(f) extern F_ f(void) - typedef StgWord StgWordArray[]; + #define EI_(X) extern StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) #define II_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) +#define IF_(f) static StgFunPtr GNUC3_ATTRIBUTE(used) f(void) +#define FN_(f) StgFunPtr f(void) +#define EF_(f) extern StgFunPtr f(void) /* ----------------------------------------------------------------------------- Tail calls @@ -200,27 +194,26 @@ typedef StgWord StgWordArray[]; to be before all procedures (inline & out-of-line). -------------------------------------------------------------------------- */ -#include "TailCalls.h" +#include "stg/TailCalls.h" /* ----------------------------------------------------------------------------- Other Stg stuff... -------------------------------------------------------------------------- */ -#include "StgDLL.h" -#include "MachRegs.h" -#include "Regs.h" - -#include "TickyCounters.h" +#include "stg/DLL.h" +#include "stg/MachRegs.h" +#include "stg/Regs.h" +#include "stg/Ticky.h" #if IN_STG_CODE /* * This is included later for RTS sources, after definitions of * StgInfoTable, StgClosure and so on. */ -#include "StgMiscClosures.h" +#include "stg/MiscClosures.h" #endif -#include "SMP.h" // write_barrier() inline is required +#include "stg/SMP.h" // write_barrier() inline is required /* ----------------------------------------------------------------------------- Moving Floats and Doubles @@ -342,7 +335,7 @@ INLINE_HEADER StgDouble PK_DBL(W_ p_src[]) In both cases the memory location might not be 64-bit aligned. -------------------------------------------------------------------------- */ -#ifdef SUPPORT_LONG_LONGS +#if SIZEOF_HSWORD == 4 typedef struct { StgWord dhi; @@ -413,7 +406,7 @@ INLINE_HEADER StgInt64 PK_Int64(W_ p_src[]) return p_src[0]; } -#endif +#endif /* SIZEOF_HSWORD == 4 */ /* ----------------------------------------------------------------------------- Split markers diff --git a/includes/Storage.h b/includes/Storage.h deleted file mode 100644 index 5d3e7733cf..0000000000 --- a/includes/Storage.h +++ /dev/null @@ -1,583 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) The GHC Team, 1998-2004 - * - * External Storage Manger Interface - * - * ---------------------------------------------------------------------------*/ - -#ifndef STORAGE_H -#define STORAGE_H - -#include <stddef.h> -#include "OSThreads.h" -#include "SMP.h" - -/* ----------------------------------------------------------------------------- - * Generational GC - * - * We support an arbitrary number of generations, with an arbitrary number - * of steps per generation. Notes (in no particular order): - * - * - all generations except the oldest should have two steps. This gives - * objects a decent chance to age before being promoted, and in - * particular will ensure that we don't end up with too many - * thunks being updated in older generations. - * - * - the oldest generation has one step. There's no point in aging - * objects in the oldest generation. - * - * - generation 0, step 0 (G0S0) is the allocation area. It is given - * a fixed set of blocks during initialisation, and these blocks - * are never freed. - * - * - during garbage collection, each step which is an evacuation - * destination (i.e. all steps except G0S0) is allocated a to-space. - * evacuated objects are allocated into the step's to-space until - * GC is finished, when the original step's contents may be freed - * and replaced by the to-space. - * - * - the mutable-list is per-generation (not per-step). G0 doesn't - * have one (since every garbage collection collects at least G0). - * - * - block descriptors contain pointers to both the step and the - * generation that the block belongs to, for convenience. - * - * - static objects are stored in per-generation lists. See GC.c for - * details of how we collect CAFs in the generational scheme. - * - * - large objects are per-step, and are promoted in the same way - * as small objects, except that we may allocate large objects into - * generation 1 initially. - * - * ------------------------------------------------------------------------- */ - -typedef struct step_ { - unsigned int no; // step number in this generation - unsigned int abs_no; // absolute step number - - struct generation_ * gen; // generation this step belongs to - unsigned int gen_no; // generation number (cached) - - bdescr * blocks; // blocks in this step - unsigned int n_blocks; // number of blocks - unsigned int n_words; // number of words - - struct step_ * to; // destination step for live objects - - bdescr * large_objects; // large objects (doubly linked) - unsigned int n_large_blocks; // no. of blocks used by large objs - - StgTSO * threads; // threads in this step - // linked via global_link - - // ------------------------------------ - // Fields below are used during GC only - - // During GC, if we are collecting this step, blocks and n_blocks - // are copied into the following two fields. After GC, these blocks - // are freed. - -#if defined(THREADED_RTS) - char pad[128]; // make sure the following is - // on a separate cache line. - SpinLock sync_large_objects; // lock for large_objects - // and scavenged_large_objects -#endif - - int mark; // mark (not copy)? (old gen only) - int compact; // compact (not sweep)? (old gen only) - - bdescr * old_blocks; // bdescr of first from-space block - unsigned int n_old_blocks; // number of blocks in from-space - unsigned int live_estimate; // for sweeping: estimate of live data - - bdescr * part_blocks; // partially-full scanned blocks - unsigned int n_part_blocks; // count of above - - bdescr * scavenged_large_objects; // live large objs after GC (d-link) - unsigned int n_scavenged_large_blocks; // size (not count) of above - - bdescr * bitmap; // bitmap for compacting collection - - StgTSO * old_threads; - -} step; - - -typedef struct generation_ { - unsigned int no; // generation number - step * steps; // steps - unsigned int n_steps; // number of steps - unsigned int max_blocks; // max blocks in step 0 - bdescr *mut_list; // mut objects in this gen (not G0) - - // stats information - unsigned int collections; - unsigned int par_collections; - unsigned int failed_promotions; - - // temporary use during GC: - bdescr *saved_mut_list; -} generation; - -extern generation * RTS_VAR(generations); - -extern generation * RTS_VAR(g0); -extern step * RTS_VAR(g0s0); -extern generation * RTS_VAR(oldest_gen); -extern step * RTS_VAR(all_steps); -extern nat RTS_VAR(total_steps); - -/* ----------------------------------------------------------------------------- - Initialisation / De-initialisation - -------------------------------------------------------------------------- */ - -extern void initStorage(void); -extern void exitStorage(void); -extern void freeStorage(void); - -/* ----------------------------------------------------------------------------- - Generic allocation - - StgPtr allocateInGen(generation *g, nat n) - Allocates a chunk of contiguous store - n words long in generation g, - returning a pointer to the first word. - Always succeeds. - - StgPtr allocate(nat n) Equaivalent to allocateInGen(g0) - - StgPtr allocateLocal(Capability *cap, nat n) - Allocates memory from the nursery in - the current Capability. This can be - done without taking a global lock, - unlike allocate(). - - StgPtr allocatePinned(nat n) Allocates a chunk of contiguous store - n words long, which is at a fixed - address (won't be moved by GC). - Returns a pointer to the first word. - Always succeeds. - - NOTE: the GC can't in general handle - pinned objects, so allocatePinned() - can only be used for ByteArrays at the - moment. - - Don't forget to TICK_ALLOC_XXX(...) - after calling allocate or - allocatePinned, for the - benefit of the ticky-ticky profiler. - - rtsBool doYouWantToGC(void) Returns True if the storage manager is - ready to perform a GC, False otherwise. - - lnat allocatedBytes(void) Returns the number of bytes allocated - via allocate() since the last GC. - Used in the reporting of statistics. - - -------------------------------------------------------------------------- */ - -extern StgPtr allocate ( lnat n ); -extern StgPtr allocateInGen ( generation *g, lnat n ); -extern StgPtr allocateLocal ( Capability *cap, lnat n ); -extern StgPtr allocatePinned ( lnat n ); -extern lnat allocatedBytes ( void ); - -extern bdescr * RTS_VAR(small_alloc_list); -extern bdescr * RTS_VAR(large_alloc_list); -extern bdescr * RTS_VAR(pinned_object_block); - -extern nat RTS_VAR(alloc_blocks); -extern nat RTS_VAR(alloc_blocks_lim); - -INLINE_HEADER rtsBool -doYouWantToGC( void ) -{ - return (alloc_blocks >= alloc_blocks_lim); -} - -/* memory allocator for executable memory */ -extern void* allocateExec(unsigned int len, void **exec_addr); -extern void freeExec (void *p); - -/* for splitting blocks groups in two */ -extern bdescr * splitLargeBlock (bdescr *bd, nat blocks); - -/* ----------------------------------------------------------------------------- - Performing Garbage Collection - - GarbageCollect(get_roots) Performs a garbage collection. - 'get_roots' is called to find all the - roots that the system knows about. - - - -------------------------------------------------------------------------- */ - -extern void GarbageCollect(rtsBool force_major_gc, nat gc_type, Capability *cap); - -/* ----------------------------------------------------------------------------- - Generational garbage collection support - - recordMutable(StgPtr p) Informs the garbage collector that a - previously immutable object has - become (permanently) mutable. Used - by thawArray and similar. - - updateWithIndirection(p1,p2) Updates the object at p1 with an - indirection pointing to p2. This is - normally called for objects in an old - generation (>0) when they are updated. - - updateWithPermIndirection(p1,p2) As above but uses a permanent indir. - - -------------------------------------------------------------------------- */ - -/* - * Storage manager mutex - */ -#if defined(THREADED_RTS) -extern Mutex sm_mutex; -#endif - -#if defined(THREADED_RTS) -#define ACQUIRE_SM_LOCK ACQUIRE_LOCK(&sm_mutex); -#define RELEASE_SM_LOCK RELEASE_LOCK(&sm_mutex); -#define ASSERT_SM_LOCK() ASSERT_LOCK_HELD(&sm_mutex); -#else -#define ACQUIRE_SM_LOCK -#define RELEASE_SM_LOCK -#define ASSERT_SM_LOCK() -#endif - -#if !IN_STG_CODE - -INLINE_HEADER void -recordMutableGen(StgClosure *p, nat gen_no) -{ - bdescr *bd; - - bd = generations[gen_no].mut_list; - if (bd->free >= bd->start + BLOCK_SIZE_W) { - bdescr *new_bd; - new_bd = allocBlock(); - new_bd->link = bd; - bd = new_bd; - generations[gen_no].mut_list = bd; - } - *bd->free++ = (StgWord)p; - -} - -INLINE_HEADER void -recordMutableGenLock(StgClosure *p, nat gen_no) -{ - ACQUIRE_SM_LOCK; - recordMutableGen(p,gen_no); - RELEASE_SM_LOCK; -} - -INLINE_HEADER void -recordMutable(StgClosure *p) -{ - bdescr *bd; - ASSERT(closure_MUTABLE(p)); - bd = Bdescr((P_)p); - if (bd->gen_no > 0) recordMutableGen(p, bd->gen_no); -} - -INLINE_HEADER void -recordMutableLock(StgClosure *p) -{ - ACQUIRE_SM_LOCK; - recordMutable(p); - RELEASE_SM_LOCK; -} - -#endif // !IN_STG_CODE - -/* ----------------------------------------------------------------------------- - The CAF table - used to let us revert CAFs in GHCi - -------------------------------------------------------------------------- */ - -/* set to disable CAF garbage collection in GHCi. */ -/* (needed when dynamic libraries are used). */ -extern rtsBool keepCAFs; - -/* ----------------------------------------------------------------------------- - This is the write barrier for MUT_VARs, a.k.a. IORefs. A - MUT_VAR_CLEAN object is not on the mutable list; a MUT_VAR_DIRTY - is. When written to, a MUT_VAR_CLEAN turns into a MUT_VAR_DIRTY - and is put on the mutable list. - -------------------------------------------------------------------------- */ - -void dirty_MUT_VAR(StgRegTable *reg, StgClosure *p); - -/* ----------------------------------------------------------------------------- - DEBUGGING predicates for pointers - - LOOKS_LIKE_INFO_PTR(p) returns False if p is definitely not an info ptr - LOOKS_LIKE_CLOSURE_PTR(p) returns False if p is definitely not a closure ptr - - These macros are complete but not sound. That is, they might - return false positives. Do not rely on them to distinguish info - pointers from closure pointers, for example. - - We don't use address-space predicates these days, for portability - reasons, and the fact that code/data can be scattered about the - address space in a dynamically-linked environment. Our best option - is to look at the alleged info table and see whether it seems to - make sense... - -------------------------------------------------------------------------- */ - -INLINE_HEADER rtsBool LOOKS_LIKE_INFO_PTR (StgWord p); -INLINE_HEADER rtsBool LOOKS_LIKE_CLOSURE_PTR (void *p); // XXX StgClosure* - -/* ----------------------------------------------------------------------------- - Macros for calculating how big a closure will be (used during allocation) - -------------------------------------------------------------------------- */ - -INLINE_HEADER StgOffset PAP_sizeW ( nat n_args ) -{ return sizeofW(StgPAP) + n_args; } - -INLINE_HEADER StgOffset AP_sizeW ( nat n_args ) -{ return sizeofW(StgAP) + n_args; } - -INLINE_HEADER StgOffset AP_STACK_sizeW ( nat size ) -{ return sizeofW(StgAP_STACK) + size; } - -INLINE_HEADER StgOffset CONSTR_sizeW( nat p, nat np ) -{ return sizeofW(StgHeader) + p + np; } - -INLINE_HEADER StgOffset THUNK_SELECTOR_sizeW ( void ) -{ return sizeofW(StgSelector); } - -INLINE_HEADER StgOffset BLACKHOLE_sizeW ( void ) -{ return sizeofW(StgHeader)+MIN_PAYLOAD_SIZE; } - -/* -------------------------------------------------------------------------- - Sizes of closures - ------------------------------------------------------------------------*/ - -INLINE_HEADER StgOffset sizeW_fromITBL( const StgInfoTable* itbl ) -{ return sizeofW(StgClosure) - + sizeofW(StgPtr) * itbl->layout.payload.ptrs - + sizeofW(StgWord) * itbl->layout.payload.nptrs; } - -INLINE_HEADER StgOffset thunk_sizeW_fromITBL( const StgInfoTable* itbl ) -{ return sizeofW(StgThunk) - + sizeofW(StgPtr) * itbl->layout.payload.ptrs - + sizeofW(StgWord) * itbl->layout.payload.nptrs; } - -INLINE_HEADER StgOffset ap_stack_sizeW( StgAP_STACK* x ) -{ return AP_STACK_sizeW(x->size); } - -INLINE_HEADER StgOffset ap_sizeW( StgAP* x ) -{ return AP_sizeW(x->n_args); } - -INLINE_HEADER StgOffset pap_sizeW( StgPAP* x ) -{ return PAP_sizeW(x->n_args); } - -INLINE_HEADER StgOffset arr_words_sizeW( StgArrWords* x ) -{ return sizeofW(StgArrWords) + x->words; } - -INLINE_HEADER StgOffset mut_arr_ptrs_sizeW( StgMutArrPtrs* x ) -{ return sizeofW(StgMutArrPtrs) + x->ptrs; } - -INLINE_HEADER StgWord tso_sizeW ( StgTSO *tso ) -{ return TSO_STRUCT_SIZEW + tso->stack_size; } - -INLINE_HEADER StgWord bco_sizeW ( StgBCO *bco ) -{ return bco->size; } - -INLINE_HEADER nat -closure_sizeW_ (StgClosure *p, StgInfoTable *info) -{ - switch (info->type) { - case THUNK_0_1: - case THUNK_1_0: - return sizeofW(StgThunk) + 1; - case FUN_0_1: - case CONSTR_0_1: - case FUN_1_0: - case CONSTR_1_0: - return sizeofW(StgHeader) + 1; - case THUNK_0_2: - case THUNK_1_1: - case THUNK_2_0: - return sizeofW(StgThunk) + 2; - case FUN_0_2: - case CONSTR_0_2: - case FUN_1_1: - case CONSTR_1_1: - case FUN_2_0: - case CONSTR_2_0: - return sizeofW(StgHeader) + 2; - case THUNK: - return thunk_sizeW_fromITBL(info); - case THUNK_SELECTOR: - return THUNK_SELECTOR_sizeW(); - case AP_STACK: - return ap_stack_sizeW((StgAP_STACK *)p); - case AP: - return ap_sizeW((StgAP *)p); - case PAP: - return pap_sizeW((StgPAP *)p); - case IND: - case IND_PERM: - case IND_OLDGEN: - case IND_OLDGEN_PERM: - return sizeofW(StgInd); - case ARR_WORDS: - return arr_words_sizeW((StgArrWords *)p); - case MUT_ARR_PTRS_CLEAN: - case MUT_ARR_PTRS_DIRTY: - case MUT_ARR_PTRS_FROZEN: - case MUT_ARR_PTRS_FROZEN0: - return mut_arr_ptrs_sizeW((StgMutArrPtrs*)p); - case TSO: - return tso_sizeW((StgTSO *)p); - case BCO: - return bco_sizeW((StgBCO *)p); - case TVAR_WATCH_QUEUE: - return sizeofW(StgTVarWatchQueue); - case TVAR: - return sizeofW(StgTVar); - case TREC_CHUNK: - return sizeofW(StgTRecChunk); - case TREC_HEADER: - return sizeofW(StgTRecHeader); - case ATOMIC_INVARIANT: - return sizeofW(StgAtomicInvariant); - case INVARIANT_CHECK_QUEUE: - return sizeofW(StgInvariantCheckQueue); - default: - return sizeW_fromITBL(info); - } -} - -// The definitive way to find the size, in words, of a heap-allocated closure -INLINE_HEADER nat -closure_sizeW (StgClosure *p) -{ - return closure_sizeW_(p, get_itbl(p)); -} - -/* ----------------------------------------------------------------------------- - Sizes of stack frames - -------------------------------------------------------------------------- */ - -INLINE_HEADER StgWord stack_frame_sizeW( StgClosure *frame ) -{ - StgRetInfoTable *info; - - info = get_ret_itbl(frame); - switch (info->i.type) { - - case RET_DYN: - { - StgRetDyn *dyn = (StgRetDyn *)frame; - return sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE + - RET_DYN_NONPTR_REGS_SIZE + - RET_DYN_PTRS(dyn->liveness) + RET_DYN_NONPTRS(dyn->liveness); - } - - case RET_FUN: - return sizeofW(StgRetFun) + ((StgRetFun *)frame)->size; - - case RET_BIG: - return 1 + GET_LARGE_BITMAP(&info->i)->size; - - case RET_BCO: - return 2 + BCO_BITMAP_SIZE((StgBCO *)((P_)frame)[1]); - - default: - return 1 + BITMAP_SIZE(info->i.layout.bitmap); - } -} - -/* ----------------------------------------------------------------------------- - Nursery manipulation - -------------------------------------------------------------------------- */ - -extern void allocNurseries ( void ); -extern void resetNurseries ( void ); -extern void resizeNurseries ( nat blocks ); -extern void resizeNurseriesFixed ( nat blocks ); -extern lnat countNurseryBlocks ( void ); - - -/* ----------------------------------------------------------------------------- - Functions from GC.c - -------------------------------------------------------------------------- */ - -typedef void (*evac_fn)(void *user, StgClosure **root); - -extern void threadPaused ( Capability *cap, StgTSO * ); -extern StgClosure * isAlive ( StgClosure *p ); -extern void markCAFs ( evac_fn evac, void *user ); -extern void GetRoots ( evac_fn evac, void *user ); - -/* ----------------------------------------------------------------------------- - Stats 'n' DEBUG stuff - -------------------------------------------------------------------------- */ - -extern ullong RTS_VAR(total_allocated); - -extern lnat calcAllocated ( void ); -extern lnat calcLiveBlocks ( void ); -extern lnat calcLiveWords ( void ); -extern lnat countOccupied ( bdescr *bd ); -extern lnat calcNeeded ( void ); - -#if defined(DEBUG) -extern void memInventory(rtsBool show); -extern void checkSanity(void); -extern nat countBlocks(bdescr *); -extern void checkNurserySanity( step *stp ); -#endif - -#if defined(DEBUG) -void printMutOnceList(generation *gen); -void printMutableList(generation *gen); -#endif - -/* ---------------------------------------------------------------------------- - Storage manager internal APIs and globals - ------------------------------------------------------------------------- */ - -#define END_OF_STATIC_LIST stgCast(StgClosure*,1) - -extern void newDynCAF(StgClosure *); - -extern void move_TSO(StgTSO *src, StgTSO *dest); -extern StgTSO *relocate_stack(StgTSO *dest, ptrdiff_t diff); - -extern StgWeak * RTS_VAR(old_weak_ptr_list); -extern StgWeak * RTS_VAR(weak_ptr_list); -extern StgClosure * RTS_VAR(caf_list); -extern StgClosure * RTS_VAR(revertible_caf_list); -extern StgTSO * RTS_VAR(resurrected_threads); - -#define IS_FORWARDING_PTR(p) ((((StgWord)p) & 1) != 0) -#define MK_FORWARDING_PTR(p) (((StgWord)p) | 1) -#define UN_FORWARDING_PTR(p) (((StgWord)p) - 1) - -INLINE_HEADER rtsBool LOOKS_LIKE_INFO_PTR_NOT_NULL (StgWord p) -{ - StgInfoTable *info = INFO_PTR_TO_STRUCT(p); - return info->type != INVALID_OBJECT && info->type < N_CLOSURE_TYPES; -} - -INLINE_HEADER rtsBool LOOKS_LIKE_INFO_PTR (StgWord p) -{ - return p && (IS_FORWARDING_PTR(p) || LOOKS_LIKE_INFO_PTR_NOT_NULL(p)); -} - -INLINE_HEADER rtsBool LOOKS_LIKE_CLOSURE_PTR (void *p) -{ - return LOOKS_LIKE_INFO_PTR((StgWord)(UNTAG_CLOSURE((StgClosure *)(p)))->header.info); -} - -#endif /* STORAGE_H */ diff --git a/includes/config.h b/includes/config.h deleted file mode 100644 index 66e2ade637..0000000000 --- a/includes/config.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __CONFIG_H__ -#define __CONFIG_H__ - -#warning config.h is deprecated; please use ghcconfig.h instead -#include "ghcconfig.h" - -#endif diff --git a/includes/ghc.mk b/includes/ghc.mk index a266bf4c6a..50107eda37 100644 --- a/includes/ghc.mk +++ b/includes/ghc.mk @@ -33,7 +33,7 @@ ifeq "$(GhcEnableTablesNextToCode) $(GhcUnregisterised)" "YES NO" includes_CC_OPTS += -DTABLES_NEXT_TO_CODE endif -includes_CC_OPTS += -Iincludes -Irts -Irts/parallel +includes_CC_OPTS += -Iincludes -Irts ifneq "$(GhcWithSMP)" "YES" includes_CC_OPTS += -DNOSMP @@ -129,7 +129,7 @@ includes_dist-derivedconstants_PROG = mkDerivedConstants$(exeext) $(eval $(call build-prog,includes,dist-derivedconstants,0)) -$(includes_dist-derivedconstants_depfile) : $(includes_H_CONFIG) $(includes_H_PLATFORM) +$(includes_dist-derivedconstants_depfile) : $(includes_H_CONFIG) $(includes_H_PLATFORM) $(wildcard includes/*.h) $(wildcard rts/*.h) includes/dist-derivedconstants/build/mkDerivedConstants.o : $(includes_H_CONFIG) $(includes_H_PLATFORM) ifneq "$(BINDIST)" "YES" @@ -159,7 +159,7 @@ includes_dist-ghcconstants_CC_OPTS = -DGEN_HASKELL $(eval $(call build-prog,includes,dist-ghcconstants,0)) ifneq "$(BINDIST)" "YES" -$(includes_dist-ghcconstants_depfile) : $(includes_H_CONFIG) $(includes_H_PLATFORM) +$(includes_dist-ghcconstants_depfile) : $(includes_H_CONFIG) $(includes_H_PLATFORM) $(wildcard includes/*.h) $(wildcard rts/*.h) includes/dist-ghcconstants/build/mkDerivedConstants.o : $(includes_H_CONFIG) $(includes_H_PLATFORM) diff --git a/includes/ieee-flpt.h b/includes/ieee-flpt.h deleted file mode 100644 index a1fce3a8da..0000000000 --- a/includes/ieee-flpt.h +++ /dev/null @@ -1,35 +0,0 @@ -/* this file is #included into both C (.c and .hc) and Haskell files */ - - /* IEEE format floating-point */ -#define IEEE_FLOATING_POINT 1 - - /* Radix of exponent representation */ -#ifndef FLT_RADIX -# define FLT_RADIX 2 -#endif - - /* Number of base-FLT_RADIX digits in the significand of a float */ -#ifndef FLT_MANT_DIG -# define FLT_MANT_DIG 24 -#endif - /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */ -#ifndef FLT_MIN_EXP -# define FLT_MIN_EXP (-125) -#endif - /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */ -#ifndef FLT_MAX_EXP -# define FLT_MAX_EXP 128 -#endif - - /* Number of base-FLT_RADIX digits in the significand of a double */ -#ifndef DBL_MANT_DIG -# define DBL_MANT_DIG 53 -#endif - /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */ -#ifndef DBL_MIN_EXP -# define DBL_MIN_EXP (-1021) -#endif - /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */ -#ifndef DBL_MAX_EXP -# define DBL_MAX_EXP 1024 -#endif diff --git a/includes/mkDerivedConstants.c b/includes/mkDerivedConstants.c index f1289f61f3..b38f3abe36 100644 --- a/includes/mkDerivedConstants.c +++ b/includes/mkDerivedConstants.c @@ -21,10 +21,8 @@ #define THREADED_RTS #include "Rts.h" -#include "RtsFlags.h" -#include "Storage.h" + #include "Stable.h" -#include "OSThreads.h" #include "Capability.h" #include <stdio.h> diff --git a/includes/rts/Adjustor.h b/includes/rts/Adjustor.h new file mode 100644 index 0000000000..71e15246c1 --- /dev/null +++ b/includes/rts/Adjustor.h @@ -0,0 +1,20 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2009 + * + * Adjustor API + * + * -------------------------------------------------------------------------- */ + +#ifndef RTS_ADJUSTOR_H +#define RTS_ADJUSTOR_H + +/* Creating and destroying an adjustor thunk */ +void* createAdjustor (int cconv, + StgStablePtr hptr, + StgFunPtr wptr, + char *typeString); + +void freeHaskellFunctionPtr (void* ptr); + +#endif /* RTS_ADJUSTOR_H */ diff --git a/includes/Bytecodes.h b/includes/rts/Bytecodes.h index 4aff907cfd..4aff907cfd 100644 --- a/includes/Bytecodes.h +++ b/includes/rts/Bytecodes.h diff --git a/includes/rts/Config.h b/includes/rts/Config.h new file mode 100644 index 0000000000..ce332fa2a2 --- /dev/null +++ b/includes/rts/Config.h @@ -0,0 +1,36 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2004 + * + * Rts settings. + * + * NOTE: assumes #include "ghcconfig.h" + * + * NB: THIS FILE IS INCLUDED IN NON-C CODE AND DATA! #defines only please. + * ---------------------------------------------------------------------------*/ + +#ifndef RTS_CONFIG_H +#define RTS_CONFIG_H + +#if defined(TICKY_TICKY) && defined(THREADED_RTS) +#error TICKY_TICKY is incompatible with THREADED_RTS +#endif + +/* + * Whether the runtime system will use libbfd for debugging purposes. + */ +#if defined(DEBUG) && defined(HAVE_BFD_H) && defined(HAVE_LIBBFD) && !defined(_WIN32) +#define USING_LIBBFD 1 +#endif + +/* ----------------------------------------------------------------------------- + Signals - supported on non-PAR versions of the runtime. See RtsSignals.h. + -------------------------------------------------------------------------- */ + +#define RTS_USER_SIGNALS 1 + +/* Profile spin locks */ + +#define PROF_SPIN + +#endif /* RTS_CONFIG_H */ diff --git a/includes/Constants.h b/includes/rts/Constants.h index 967a852496..bab45a362c 100644 --- a/includes/Constants.h +++ b/includes/rts/Constants.h @@ -14,8 +14,8 @@ * * -------------------------------------------------------------------------- */ -#ifndef CONSTANTS_H -#define CONSTANTS_H +#ifndef RTS_CONSTANTS_H +#define RTS_CONSTANTS_H /* ----------------------------------------------------------------------------- Minimum closure sizes @@ -287,4 +287,4 @@ #error RESERVED_STACK_WORDS may be wrong! #endif -#endif /* CONSTANTS_H */ +#endif /* RTS_CONSTANTS_H */ diff --git a/includes/EventLogFormat.h b/includes/rts/EventLogFormat.h index b56b0b77e4..363c1ca1cf 100644 --- a/includes/EventLogFormat.h +++ b/includes/rts/EventLogFormat.h @@ -73,8 +73,8 @@ * * -------------------------------------------------------------------------- */ -#ifndef EVENTLOGFORMAT_H -#define EVENTLOGFORMAT_H +#ifndef RTS_EVENTLOGFORMAT_H +#define RTS_EVENTLOGFORMAT_H /* * Markers for begin/end of the Header. @@ -140,4 +140,4 @@ typedef StgWord16 EventCapNo; #endif -#endif /* EVENTLOGFORMAT_H */ +#endif /* RTS_EVENTLOGFORMAT_H */ diff --git a/includes/FileLock.h b/includes/rts/FileLock.h index 3fc1a81aec..9a35ecc581 100644 --- a/includes/FileLock.h +++ b/includes/rts/FileLock.h @@ -6,7 +6,10 @@ * * ---------------------------------------------------------------------------*/ -void initFileLocking(void); -void freeFileLocking(void); +#ifndef RTS_FILELOCK_H +#define RTS_FILELOCK_H + int lockFile(int fd, dev_t dev, ino_t ino, int for_writing); int unlockFile(int fd); + +#endif /* RTS_FILELOCK_H */ diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h new file mode 100644 index 0000000000..3f3a0a952f --- /dev/null +++ b/includes/rts/Flags.h @@ -0,0 +1,239 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-1999 + * + * Datatypes that holds the command-line flag settings. + * + * ---------------------------------------------------------------------------*/ + +#ifndef RTS_FLAGS_H +#define RTS_FLAGS_H + +#include <stdio.h> + +/* For defaults, see the @initRtsFlagsDefaults@ routine. */ + +struct GC_FLAGS { + FILE *statsFile; + nat giveStats; +#define NO_GC_STATS 0 +#define COLLECT_GC_STATS 1 +#define ONELINE_GC_STATS 2 +#define SUMMARY_GC_STATS 3 +#define VERBOSE_GC_STATS 4 + + nat maxStkSize; /* in *words* */ + nat initialStkSize; /* in *words* */ + + nat maxHeapSize; /* in *blocks* */ + nat minAllocAreaSize; /* in *blocks* */ + nat minOldGenSize; /* in *blocks* */ + nat heapSizeSuggestion; /* in *blocks* */ + double oldGenFactor; + double pcFreeHeap; + + nat generations; + nat steps; + rtsBool squeezeUpdFrames; + + rtsBool compact; /* True <=> "compact all the time" */ + double compactThreshold; + + rtsBool sweep; /* use "mostly mark-sweep" instead of copying + * for the oldest generation */ + rtsBool ringBell; + rtsBool frontpanel; + + int idleGCDelayTime; /* in milliseconds */ + + StgWord heapBase; /* address to ask the OS for memory */ +}; + +struct DEBUG_FLAGS { + /* flags to control debugging output & extra checking in various subsystems */ + rtsBool scheduler; /* 's' */ + rtsBool interpreter; /* 'i' */ + rtsBool weak; /* 'w' */ + rtsBool gccafs; /* 'G' */ + rtsBool gc; /* 'g' */ + rtsBool block_alloc; /* 'b' */ + rtsBool sanity; /* 'S' warning: might be expensive! */ + rtsBool stable; /* 't' */ + rtsBool prof; /* 'p' */ + rtsBool eventlog; /* 'e' */ + rtsBool linker; /* 'l' the object linker */ + rtsBool apply; /* 'a' */ + rtsBool stm; /* 'm' */ + rtsBool squeeze; /* 'z' stack squeezing & lazy blackholing */ + rtsBool hpc; /* 'c' coverage */ + rtsBool timestamp; /* add timestamps to traces */ +}; + +struct COST_CENTRE_FLAGS { + unsigned int doCostCentres; +# define COST_CENTRES_SUMMARY 1 +# define COST_CENTRES_VERBOSE 2 /* incl. serial time profile */ +# define COST_CENTRES_ALL 3 +# define COST_CENTRES_XML 4 + + int profilerTicks; /* derived */ + int msecsPerTick; /* derived */ +}; + +struct PROFILING_FLAGS { + unsigned int doHeapProfile; +# define NO_HEAP_PROFILING 0 /* N.B. Used as indexes into arrays */ +# define HEAP_BY_CCS 1 +# define HEAP_BY_MOD 2 +# define HEAP_BY_DESCR 4 +# define HEAP_BY_TYPE 5 +# define HEAP_BY_RETAINER 6 +# define HEAP_BY_LDV 7 + +# define HEAP_BY_CLOSURE_TYPE 8 + + nat profileInterval; /* delta between samples (in ms) */ + nat profileIntervalTicks; /* delta between samples (in 'ticks') */ + rtsBool includeTSOs; + + + rtsBool showCCSOnException; + + nat maxRetainerSetSize; + + nat ccsLength; + + char* modSelector; + char* descrSelector; + char* typeSelector; + char* ccSelector; + char* ccsSelector; + char* retainerSelector; + char* bioSelector; + +}; + +#ifdef EVENTLOG +struct EVENTLOG_FLAGS { + rtsBool doEventLogging; +}; +#endif + +struct CONCURRENT_FLAGS { + int ctxtSwitchTime; /* in milliseconds */ + int ctxtSwitchTicks; /* derived */ +}; + +struct MISC_FLAGS { + int tickInterval; /* in milliseconds */ + rtsBool install_signal_handlers; + rtsBool machineReadable; + StgWord linkerMemBase; /* address to ask the OS for memory + * for the linker, NULL ==> off */ +}; + +#ifdef THREADED_RTS +struct PAR_FLAGS { + nat nNodes; /* number of threads to run simultaneously */ + rtsBool migrate; /* migrate threads between capabilities */ + rtsBool wakeupMigrate; /* migrate a thread on wakeup */ + unsigned int maxLocalSparks; + rtsBool parGcEnabled; /* enable parallel GC */ + rtsBool parGcGen; /* do parallel GC in this generation + * and higher only */ + rtsBool parGcLoadBalancing; /* do load-balancing in parallel GC */ + rtsBool setAffinity; /* force thread affinity with CPUs */ +}; +#endif /* THREADED_RTS */ + +struct TICKY_FLAGS { + rtsBool showTickyStats; + FILE *tickyFile; +}; + +#ifdef USE_PAPI +#define MAX_PAPI_USER_EVENTS 8 + +struct PAPI_FLAGS { + nat eventType; /* The type of events to count */ + nat numUserEvents; + char * userEvents[MAX_PAPI_USER_EVENTS]; +}; + +#define PAPI_FLAG_CACHE_L1 1 +#define PAPI_FLAG_CACHE_L2 2 +#define PAPI_FLAG_BRANCH 3 +#define PAPI_FLAG_STALLS 4 +#define PAPI_FLAG_CB_EVENTS 5 +#define PAPI_USER_EVENTS 6 + +#endif + +/* Put them together: */ + +typedef struct _RTS_FLAGS { + /* The first portion of RTS_FLAGS is invariant. */ + struct GC_FLAGS GcFlags; + struct CONCURRENT_FLAGS ConcFlags; + struct MISC_FLAGS MiscFlags; + struct DEBUG_FLAGS DebugFlags; + struct COST_CENTRE_FLAGS CcFlags; + struct PROFILING_FLAGS ProfFlags; +#ifdef EVENTLOG + struct EVENTLOG_FLAGS EventLogFlags; +#endif + struct TICKY_FLAGS TickyFlags; + +#if defined(THREADED_RTS) + struct PAR_FLAGS ParFlags; +#endif +#ifdef USE_PAPI + struct PAPI_FLAGS PapiFlags; +#endif +} RTS_FLAGS; + +#ifdef COMPILING_RTS_MAIN +extern DLLIMPORT RTS_FLAGS RtsFlags; +#elif IN_STG_CODE +/* Hack because the C code generator can't generate '&label'. */ +extern RTS_FLAGS RtsFlags[]; +#else +extern RTS_FLAGS RtsFlags; +#endif + +/* Routines that operate-on/to-do-with RTS flags: */ + +extern void initRtsFlagsDefaults(void); +extern void setupRtsFlags(int *argc, char *argv[], int *rts_argc, char *rts_argv[]); +extern void setProgName(char *argv[]); + + +/* + * The printf formats are here, so we are less likely to make + * overly-long filenames (with disastrous results). No more than 128 + * chars, please! + */ + +#define STATS_FILENAME_MAXLEN 128 + +#define GR_FILENAME_FMT "%0.124s.gr" +#define GR_FILENAME_FMT_GUM "%0.120s.%03d.%s" +#define HP_FILENAME_FMT "%0.124s.hp" +#define LIFE_FILENAME_FMT "%0.122s.life" +#define PROF_FILENAME_FMT "%0.122s.prof" +#define PROF_FILENAME_FMT_GUM "%0.118s.%03d.prof" +#define QP_FILENAME_FMT "%0.124s.qp" +#define STAT_FILENAME_FMT "%0.122s.stat" +#define TICKY_FILENAME_FMT "%0.121s.ticky" +#define TIME_FILENAME_FMT "%0.122s.time" +#define TIME_FILENAME_FMT_GUM "%0.118s.%03d.time" + +/* an "int" so as to match normal "argc" */ +/* Now defined in Stg.h (lib/std/cbits need these too.) +extern int prog_argc; +extern char **prog_argv; +*/ +extern int rts_argc; /* ditto */ +extern char *rts_argv[]; + +#endif /* RTS_FLAGS_H */ diff --git a/includes/RtsGlobals.h b/includes/rts/Globals.h index 476f112e17..71846e75a1 100644 --- a/includes/RtsGlobals.h +++ b/includes/rts/Globals.h @@ -9,13 +9,10 @@ * * ---------------------------------------------------------------------------*/ -#ifndef RTSGLOBALS_H -#define RTSGLOBALS_H - -void initGlobalStore(void); -void exitGlobalStore(void); +#ifndef RTS_GLOBALS_H +#define RTS_GLOBALS_H StgStablePtr getOrSetTypeableStore(StgStablePtr value); StgStablePtr getOrSetSignalHandlerStore(StgStablePtr value); -#endif +#endif /* RTS_GLOBALS_H */ diff --git a/includes/Hooks.h b/includes/rts/Hooks.h index e281c89ab9..4fe50b4b9f 100644 --- a/includes/Hooks.h +++ b/includes/rts/Hooks.h @@ -6,6 +6,9 @@ * * ---------------------------------------------------------------------------*/ +#ifndef RTS_HOOKS_H +#define RTS_HOOKS_H + extern char *ghc_rts_opts; extern void OnExitHook (void); @@ -14,3 +17,5 @@ extern void StackOverflowHook (unsigned long stack_size); extern void OutOfHeapHook (unsigned long request_size, unsigned long heap_size); extern void MallocFailHook (unsigned long request_size /* in bytes */, char *msg); extern void defaultsHook (void); + +#endif /* RTS_HOOKS_H */ diff --git a/includes/rts/Hpc.h b/includes/rts/Hpc.h new file mode 100644 index 0000000000..c966e32cd9 --- /dev/null +++ b/includes/rts/Hpc.h @@ -0,0 +1,32 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 2008-2009 + * + * Haskell Program Coverage + * + * -------------------------------------------------------------------------- */ + +#ifndef RTS_HPC_H +#define RTS_HPC_H + +// Simple linked list of modules +typedef struct _HpcModuleInfo { + char *modName; // name of module + StgWord32 tickCount; // number of ticks + StgWord32 tickOffset; // offset into a single large .tix Array + StgWord32 hashNo; // Hash number for this module's mix info + StgWord64 *tixArr; // tix Array; local for this module + struct _HpcModuleInfo *next; +} HpcModuleInfo; + +int hs_hpc_module (char *modName, + StgWord32 modCount, + StgWord32 modHashNo, + StgWord64 *tixArr); + +HpcModuleInfo * hs_hpc_rootModule (void); + +void startupHpc(void); +void exitHpc(void); + +#endif /* RTS_HPC_H */ diff --git a/includes/rts/IOManager.h b/includes/rts/IOManager.h new file mode 100644 index 0000000000..1c269ada6d --- /dev/null +++ b/includes/rts/IOManager.h @@ -0,0 +1,39 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2009 + * + * IO Manager functionality in the RTS + * + * -------------------------------------------------------------------------- */ + +#ifndef RTS_IOMANAGER_H +#define RTS_IOMANAGER_H + +#if defined(mingw32_HOST_OS) + +int rts_InstallConsoleEvent ( int action, StgStablePtr *handler ); +void rts_ConsoleHandlerDone ( int ev ); +extern StgInt console_handler; + +void * getIOManagerEvent (void); +HsWord32 readIOManagerEvent (void); +void sendIOManagerEvent (HsWord32 event); + +#else + +void setIOManagerPipe (int fd); + +#endif + +// +// Communicating with the IO manager thread (see GHC.Conc). +// Posix implementation in posix/Signals.c +// Win32 implementation in win32/ThrIOManager.c +// +#if defined(THREADED_RTS) +void ioManagerWakeup (void); +void ioManagerDie (void); +void ioManagerStart (void); +#endif + +#endif /* RTS_IOMANAGER_H */ diff --git a/includes/Linker.h b/includes/rts/Linker.h index 053d411153..df74e7eeb8 100644 --- a/includes/Linker.h +++ b/includes/rts/Linker.h @@ -6,8 +6,8 @@ * * ---------------------------------------------------------------------------*/ -#ifndef LINKER_H -#define LINKER_H +#ifndef RTS_LINKER_H +#define RTS_LINKER_H /* initialize the object linker */ void initLinker( void ); @@ -33,6 +33,4 @@ HsInt resolveObjs( void ); /* load a dynamic library */ const char *addDLL( char* dll_name ); -extern void markRootPtrTable(void (*)(StgClosure **)); - -#endif /* LINKER_H */ +#endif /* RTS_LINKER_H */ diff --git a/includes/RtsMessages.h b/includes/rts/Messages.h index 79c48d3b98..e01eff47cf 100644 --- a/includes/RtsMessages.h +++ b/includes/rts/Messages.h @@ -9,8 +9,8 @@ * * ---------------------------------------------------------------------------*/ -#ifndef RTSMESSAGES_H -#define RTSMESSAGES_H +#ifndef RTS_MESSAGES_H +#define RTS_MESSAGES_H #include <stdarg.h> @@ -26,14 +26,15 @@ * barf() invokes (*fatalInternalErrorFn)(). This function is not * expected to return. */ -extern void barf(const char *s, ...) +void barf(const char *s, ...) GNUC3_ATTRIBUTE(__noreturn__); -extern void vbarf(const char *s, va_list ap) +void vbarf(const char *s, va_list ap) GNUC3_ATTRIBUTE(__noreturn__); -extern void _assertFail(const char *filename, unsigned int linenum) - GNUC3_ATTRIBUTE(__noreturn__); +// declared in Rts.h: +// extern void _assertFail(const char *filename, unsigned int linenum) +// GNUC3_ATTRIBUTE(__noreturn__); /* * An error condition which is caused by and/or can be corrected by @@ -41,10 +42,10 @@ extern void _assertFail(const char *filename, unsigned int linenum) * * errorBelch() invokes (*errorMsgFn)(). */ -extern void errorBelch(const char *s, ...) +void errorBelch(const char *s, ...) GNUC3_ATTRIBUTE(format (printf, 1, 2)); -extern void verrorBelch(const char *s, va_list ap); +void verrorBelch(const char *s, va_list ap); /* * An error condition which is caused by and/or can be corrected by @@ -55,10 +56,10 @@ extern void verrorBelch(const char *s, va_list ap); * * sysErrorBelch() invokes (*sysErrorMsgFn)(). */ -extern void sysErrorBelch(const char *s, ...) +void sysErrorBelch(const char *s, ...) GNUC3_ATTRIBUTE(format (printf, 1, 2)); -extern void vsysErrorBelch(const char *s, va_list ap); +void vsysErrorBelch(const char *s, va_list ap); /* * A debugging message. Debugging messages are generated either as a @@ -67,10 +68,10 @@ extern void vsysErrorBelch(const char *s, va_list ap); * * debugBelch() invokes (*debugMsgFn)(). */ -extern void debugBelch(const char *s, ...) +void debugBelch(const char *s, ...) GNUC3_ATTRIBUTE(format (printf, 1, 2)); -extern void vdebugBelch(const char *s, va_list ap); +void vdebugBelch(const char *s, va_list ap); /* Hooks for redirecting message generation: */ @@ -88,4 +89,4 @@ extern RtsMsgFunction rtsDebugMsgFn; extern RtsMsgFunction rtsErrorMsgFn; extern RtsMsgFunction rtsSysErrorMsgFn; -#endif /* RTSMESSAGES_H */ +#endif /* RTS_MESSAGES_H */ diff --git a/includes/OSThreads.h b/includes/rts/OSThreads.h index f5c434fc28..2d32136379 100644 --- a/includes/OSThreads.h +++ b/includes/rts/OSThreads.h @@ -7,8 +7,8 @@ * * --------------------------------------------------------------------------*/ -#ifndef __OSTHREADS_H__ -#define __OSTHREADS_H__ +#ifndef RTS_OSTHREADS_H +#define RTS_OSTHREADS_H #if defined(THREADED_RTS) /* to the end */ @@ -152,7 +152,7 @@ typedef HANDLE Mutex; // General thread operations // extern OSThreadId osThreadId ( void ); -extern void shutdownThread ( void ); +extern void shutdownThread ( void ) GNUC3_ATTRIBUTE(__noreturn__); extern void yieldThread ( void ); typedef void OSThreadProcAttr OSThreadProc(void *); @@ -198,4 +198,12 @@ void setThreadAffinity (nat n, nat m); #endif /* defined(THREADED_RTS) */ -#endif /* __OSTHREADS_H__ */ +// +// Support for forkOS (defined regardless of THREADED_RTS, but does +// nothing when !THREADED_RTS). +// +#ifndef CMINUSMINUS +int forkOS_createThread ( HsStablePtr entry ); +#endif + +#endif /* RTS_OSTHREADS_H */ diff --git a/includes/rts/Parallel.h b/includes/rts/Parallel.h new file mode 100644 index 0000000000..b6759819b1 --- /dev/null +++ b/includes/rts/Parallel.h @@ -0,0 +1,14 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2009 + * + * Parallelism-related functionality + * + * -------------------------------------------------------------------------- */ + +#ifndef RTS_PARALLEL_H +#define RTS_PARALLEL_H + +StgInt newSpark (StgRegTable *reg, StgClosure *p); + +#endif /* RTS_PARALLEL_H */ diff --git a/includes/Signals.h b/includes/rts/Signals.h index a5907bbee9..8d9e0fd4b7 100644 --- a/includes/Signals.h +++ b/includes/rts/Signals.h @@ -1,18 +1,21 @@ /* ----------------------------------------------------------------------------- * - * (c) The GHC Team, 1998-2005 + * (c) The GHC Team, 1998-2009 * * RTS signal handling * * ---------------------------------------------------------------------------*/ -#ifndef SIGNALS_H -#define SIGNALS_H +#ifndef RTS_SIGNALS_H +#define RTS_SIGNALS_H +/* NB. #included in Haskell code, no prototypes in here. */ + +/* arguments to stg_sig_install() */ #define STG_SIG_DFL (-1) #define STG_SIG_IGN (-2) #define STG_SIG_ERR (-3) #define STG_SIG_HAN (-4) #define STG_SIG_RST (-5) -#endif /* SIGNALS_H */ +#endif /* RTS_SIGNALS_H */ diff --git a/includes/SpinLock.h b/includes/rts/SpinLock.h index 76fcd4e00e..ea992a3457 100644 --- a/includes/SpinLock.h +++ b/includes/rts/SpinLock.h @@ -14,8 +14,8 @@ * * -------------------------------------------------------------------------- */ -#ifndef SPINLOCK_H -#define SPINLOCK_H +#ifndef RTS_SPINLOCK_H +#define RTS_SPINLOCK_H #if defined(THREADED_RTS) @@ -101,5 +101,5 @@ INLINE_HEADER void initSpinLock(void * p STG_UNUSED) #endif /* THREADED_RTS */ -#endif /* SPINLOCK_H */ +#endif /* RTS_SPINLOCK_H */ diff --git a/includes/rts/Stable.h b/includes/rts/Stable.h new file mode 100644 index 0000000000..95a3f96156 --- /dev/null +++ b/includes/rts/Stable.h @@ -0,0 +1,35 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2004 + * + * Stable Pointers + * + * ---------------------------------------------------------------------------*/ + +#ifndef RTS_STABLE_H +#define RTS_STABLE_H + +EXTERN_INLINE StgPtr deRefStablePtr (StgStablePtr stable_ptr); +StgStablePtr getStablePtr (StgPtr p); + +/* ----------------------------------------------------------------------------- + PRIVATE from here. + -------------------------------------------------------------------------- */ + +typedef struct { + StgPtr addr; /* Haskell object, free list, or NULL */ + StgPtr old; /* old Haskell object, used during GC */ + StgWord ref; /* used for reference counting */ + StgClosure *sn_obj; /* the StableName object (or NULL) */ +} snEntry; + +extern DLL_IMPORT_RTS snEntry *stable_ptr_table; + +EXTERN_INLINE +StgPtr deRefStablePtr(StgStablePtr sp) +{ + ASSERT(stable_ptr_table[(StgWord)sp].ref > 0); + return stable_ptr_table[(StgWord)sp].addr; +} + +#endif /* RTS_STABLE_H */ diff --git a/includes/SchedAPI.h b/includes/rts/Threads.h index b11437bda2..06a0ed11dc 100644 --- a/includes/SchedAPI.h +++ b/includes/rts/Threads.h @@ -1,18 +1,18 @@ /* ----------------------------------------------------------------------------- * - * (c) The GHC Team 1998-2002 + * (c) The GHC Team 1998-2009 * * External API for the scheduler. For most uses, the functions in * RtsAPI.h should be enough. * * ---------------------------------------------------------------------------*/ -#ifndef SCHEDAPI_H -#define SCHEDAPI_H +#ifndef RTS_THREADS_H +#define RTS_THREADS_H -/* - * Creating threads - */ +// +// Creating threads +// StgTSO *createThread (Capability *cap, nat stack_size); Capability *scheduleWaitThread (StgTSO *tso, /*out*/HaskellObj* ret, @@ -24,4 +24,24 @@ StgTSO *createIOThread (Capability *cap, nat stack_size, StgClosure *closure); StgTSO *createStrictIOThread (Capability *cap, nat stack_size, StgClosure *closure); + +// Suspending/resuming threads around foreign calls +void * suspendThread (StgRegTable *); +StgRegTable * resumeThread (void *); + +// +// Thread operations from Threads.c +// +int cmp_thread (StgPtr tso1, StgPtr tso2); +int rts_getThreadId (StgPtr tso); +pid_t forkProcess (HsStablePtr *entry); +HsBool rtsSupportsBoundThreads (void); + +// The number of Capabilities +extern unsigned int n_capabilities; + +#if !IN_STG_CODE +extern Capability MainCapability; #endif + +#endif /* RTS_THREADS_H */ diff --git a/includes/rts/Timer.h b/includes/rts/Timer.h new file mode 100644 index 0000000000..e3a5c2dc69 --- /dev/null +++ b/includes/rts/Timer.h @@ -0,0 +1,15 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1995-2006 + * + * Interface to the RTS timer signal (uses OS-dependent Ticker.h underneath) + * + * ---------------------------------------------------------------------------*/ + +#ifndef RTS_TIMER_H +#define RTS_TIMER_H + +void startTimer (void); +void stopTimer (void); + +#endif /* RTS_TIMER_H */ diff --git a/includes/RtsTypes.h b/includes/rts/Types.h index 79bbf1fccf..6f399e083d 100644 --- a/includes/RtsTypes.h +++ b/includes/rts/Types.h @@ -35,10 +35,8 @@ typedef enum { rtsTrue } rtsBool; -/* - Types specific to the parallel runtime system. -*/ - -typedef ullong rtsTime; +typedef struct StgClosure_ StgClosure; +typedef struct StgInfoTable_ StgInfoTable; +typedef struct StgTSO_ StgTSO; #endif /* RTS_TYPES_H */ diff --git a/includes/StgProf.h b/includes/rts/prof/CCS.h index 9b3ce69a9f..3512930b7b 100644 --- a/includes/StgProf.h +++ b/includes/rts/prof/CCS.h @@ -6,8 +6,8 @@ * * ---------------------------------------------------------------------------*/ -#ifndef STGPROF_H -#define STGPROF_H +#ifndef RTS_PROF_CCS_H +#define RTS_PROF_CCS_H /* ----------------------------------------------------------------------------- * Data Structures @@ -234,5 +234,5 @@ extern CostCentreStack * RTS_VAR(CCS_LIST); /* registered CCS list */ #endif /* PROFILING */ -#endif /* STGPROF_H */ +#endif /* RTS_PROF_CCS_H */ diff --git a/includes/StgLdvProf.h b/includes/rts/prof/LDV.h index 3c3df1c5fa..c51b10647e 100644 --- a/includes/StgLdvProf.h +++ b/includes/rts/prof/LDV.h @@ -6,8 +6,8 @@ * * ---------------------------------------------------------------------------*/ -#ifndef STGLDVPROF_H -#define STGLDVPROF_H +#ifndef RTS_PROF_LDV_H +#define RTS_PROF_LDV_H #ifdef PROFILING @@ -42,4 +42,5 @@ #define LDV_RECORD_DEAD_FILL_SLOP_DYNAMIC(c) /* nothing */ #endif /* PROFILING */ + #endif /* STGLDVPROF_H */ diff --git a/includes/Block.h b/includes/rts/storage/Block.h index ec894da02e..849f99f430 100644 --- a/includes/Block.h +++ b/includes/rts/storage/Block.h @@ -6,8 +6,8 @@ * * ---------------------------------------------------------------------------*/ -#ifndef BLOCK_H -#define BLOCK_H +#ifndef RTS_STORAGE_BLOCK_H +#define RTS_STORAGE_BLOCK_H /* The actual block and megablock-size constants are defined in * includes/Constants.h, all constants here are derived from these. @@ -268,4 +268,4 @@ round_up_to_mblocks(StgWord words) } #endif /* !CMINUSMINUS */ -#endif /* BLOCK_H */ +#endif /* RTS_STORAGE_BLOCK_H */ diff --git a/includes/rts/storage/ClosureMacros.h b/includes/rts/storage/ClosureMacros.h new file mode 100644 index 0000000000..458960f3f7 --- /dev/null +++ b/includes/rts/storage/ClosureMacros.h @@ -0,0 +1,395 @@ +/* ---------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2004 + * + * Macros for building and manipulating closures + * + * -------------------------------------------------------------------------- */ + +#ifndef RTS_STORAGE_CLOSUREMACROS_H +#define RTS_STORAGE_CLOSUREMACROS_H + +/* ----------------------------------------------------------------------------- + Info tables are slammed up against the entry code, and the label + for the info table is at the *end* of the table itself. This + inline function adjusts an info pointer to point to the beginning + of the table, so we can use standard C structure indexing on it. + + Note: this works for SRT info tables as long as you don't want to + access the SRT, since they are laid out the same with the SRT + pointer as the first word in the table. + + NOTES ABOUT MANGLED C VS. MINI-INTERPRETER: + + A couple of definitions: + + "info pointer" The first word of the closure. Might point + to either the end or the beginning of the + info table, depending on whether we're using + the mini interpretter or not. GET_INFO(c) + retrieves the info pointer of a closure. + + "info table" The info table structure associated with a + closure. This is always a pointer to the + beginning of the structure, so we can + use standard C structure indexing to pull out + the fields. get_itbl(c) returns a pointer to + the info table for closure c. + + An address of the form xxxx_info points to the end of the info + table or the beginning of the info table depending on whether we're + mangling or not respectively. So, + + c->header.info = xxx_info + + makes absolute sense, whether mangling or not. + + -------------------------------------------------------------------------- */ + +#define SET_INFO(c,i) ((c)->header.info = (i)) +#define GET_INFO(c) ((c)->header.info) +#define GET_ENTRY(c) (ENTRY_CODE(GET_INFO(c))) + +#define get_itbl(c) (INFO_PTR_TO_STRUCT((c)->header.info)) +#define get_ret_itbl(c) (RET_INFO_PTR_TO_STRUCT((c)->header.info)) +#define get_fun_itbl(c) (FUN_INFO_PTR_TO_STRUCT((c)->header.info)) +#define get_thunk_itbl(c) (THUNK_INFO_PTR_TO_STRUCT((c)->header.info)) +#define get_con_itbl(c) (CON_INFO_PTR_TO_STRUCT((c)->header.info)) + +#define GET_TAG(con) (get_itbl(con)->srt_bitmap) + +#ifdef TABLES_NEXT_TO_CODE +#define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)(info) - 1) +#define RET_INFO_PTR_TO_STRUCT(info) ((StgRetInfoTable *)(info) - 1) +#define FUN_INFO_PTR_TO_STRUCT(info) ((StgFunInfoTable *)(info) - 1) +#define THUNK_INFO_PTR_TO_STRUCT(info) ((StgThunkInfoTable *)(info) - 1) +#define CON_INFO_PTR_TO_STRUCT(info) ((StgConInfoTable *)(info) - 1) +#define itbl_to_fun_itbl(i) ((StgFunInfoTable *)(((StgInfoTable *)(i) + 1)) - 1) +#define itbl_to_ret_itbl(i) ((StgRetInfoTable *)(((StgInfoTable *)(i) + 1)) - 1) +#define itbl_to_thunk_itbl(i) ((StgThunkInfoTable *)(((StgInfoTable *)(i) + 1)) - 1) +#define itbl_to_con_itbl(i) ((StgConInfoTable *)(((StgInfoTable *)(i) + 1)) - 1) +#else +#define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)info) +#define RET_INFO_PTR_TO_STRUCT(info) ((StgRetInfoTable *)info) +#define FUN_INFO_PTR_TO_STRUCT(info) ((StgFunInfoTable *)info) +#define THUNK_INFO_PTR_TO_STRUCT(info) ((StgThunkInfoTable *)info) +#define CON_INFO_PTR_TO_STRUCT(info) ((StgConInfoTable *)info) +#define itbl_to_fun_itbl(i) ((StgFunInfoTable *)(i)) +#define itbl_to_ret_itbl(i) ((StgRetInfoTable *)(i)) +#define itbl_to_thunk_itbl(i) ((StgThunkInfoTable *)(i)) +#define itbl_to_con_itbl(i) ((StgConInfoTable *)(i)) +#endif + +/* ----------------------------------------------------------------------------- + Macros for building closures + -------------------------------------------------------------------------- */ + +#ifdef PROFILING +#ifdef DEBUG_RETAINER +/* + For the sake of debugging, we take the safest way for the moment. Actually, this + is useful to check the sanity of heap before beginning retainer profiling. + flip is defined in RetainerProfile.c, and declared as extern in RetainerProfile.h. + Note: change those functions building Haskell objects from C datatypes, i.e., + all rts_mk???() functions in RtsAPI.c, as well. + */ +#define SET_PROF_HDR(c,ccs_) \ + ((c)->header.prof.ccs = ccs_, (c)->header.prof.hp.rs = (retainerSet *)((StgWord)NULL | flip)) +#else +/* + For retainer profiling only: we do not have to set (c)->header.prof.hp.rs to + NULL | flip (flip is defined in RetainerProfile.c) because even when flip + is 1, rs is invalid and will be initialized to NULL | flip later when + the closure *c is visited. + */ +/* +#define SET_PROF_HDR(c,ccs_) \ + ((c)->header.prof.ccs = ccs_, (c)->header.prof.hp.rs = NULL) + */ +/* + The following macro works for both retainer profiling and LDV profiling: + for retainer profiling, ldvTime remains 0, so rs fields are initialized to 0. + See the invariants on ldvTime. + */ +#define SET_PROF_HDR(c,ccs_) \ + ((c)->header.prof.ccs = ccs_, \ + LDV_RECORD_CREATE((c))) +#endif /* DEBUG_RETAINER */ +#else +#define SET_PROF_HDR(c,ccs) +#endif + +#define SET_HDR(c,_info,ccs) \ + { \ + (c)->header.info = _info; \ + SET_PROF_HDR((StgClosure *)(c),ccs); \ + } + +#define SET_ARR_HDR(c,info,costCentreStack,n_words) \ + SET_HDR(c,info,costCentreStack); \ + (c)->words = n_words; + +/* ----------------------------------------------------------------------------- + How to get hold of the static link field for a static closure. + -------------------------------------------------------------------------- */ + +/* These are hard-coded. */ +#define FUN_STATIC_LINK(p) (&(p)->payload[0]) +#define THUNK_STATIC_LINK(p) (&(p)->payload[1]) +#define IND_STATIC_LINK(p) (&(p)->payload[1]) + +INLINE_HEADER StgClosure ** +STATIC_LINK(const StgInfoTable *info, StgClosure *p) +{ + switch (info->type) { + case THUNK_STATIC: + return THUNK_STATIC_LINK(p); + case FUN_STATIC: + return FUN_STATIC_LINK(p); + case IND_STATIC: + return IND_STATIC_LINK(p); + default: + return &(p)->payload[info->layout.payload.ptrs + + info->layout.payload.nptrs]; + } +} + +#define STATIC_LINK2(info,p) \ + (*(StgClosure**)(&((p)->payload[info->layout.payload.ptrs + \ + info->layout.payload.nptrs + 1]))) + +/* ----------------------------------------------------------------------------- + INTLIKE and CHARLIKE closures. + -------------------------------------------------------------------------- */ + +#define CHARLIKE_CLOSURE(n) ((P_)&stg_CHARLIKE_closure[(n)-MIN_CHARLIKE]) +#define INTLIKE_CLOSURE(n) ((P_)&stg_INTLIKE_closure[(n)-MIN_INTLIKE]) + +/* ---------------------------------------------------------------------------- + Macros for untagging and retagging closure pointers + For more information look at the comments in Cmm.h + ------------------------------------------------------------------------- */ + +static inline StgWord +GET_CLOSURE_TAG(StgClosure * p) +{ + return (StgWord)p & TAG_MASK; +} + +static inline StgClosure * +UNTAG_CLOSURE(StgClosure * p) +{ + return (StgClosure*)((StgWord)p & ~TAG_MASK); +} + +static inline StgClosure * +TAG_CLOSURE(StgWord tag,StgClosure * p) +{ + return (StgClosure*)((StgWord)p | tag); +} + +/* ----------------------------------------------------------------------------- + Forwarding pointers + -------------------------------------------------------------------------- */ + +#define IS_FORWARDING_PTR(p) ((((StgWord)p) & 1) != 0) +#define MK_FORWARDING_PTR(p) (((StgWord)p) | 1) +#define UN_FORWARDING_PTR(p) (((StgWord)p) - 1) + +/* ----------------------------------------------------------------------------- + DEBUGGING predicates for pointers + + LOOKS_LIKE_INFO_PTR(p) returns False if p is definitely not an info ptr + LOOKS_LIKE_CLOSURE_PTR(p) returns False if p is definitely not a closure ptr + + These macros are complete but not sound. That is, they might + return false positives. Do not rely on them to distinguish info + pointers from closure pointers, for example. + + We don't use address-space predicates these days, for portability + reasons, and the fact that code/data can be scattered about the + address space in a dynamically-linked environment. Our best option + is to look at the alleged info table and see whether it seems to + make sense... + -------------------------------------------------------------------------- */ + +INLINE_HEADER rtsBool LOOKS_LIKE_INFO_PTR_NOT_NULL (StgWord p) +{ + StgInfoTable *info = INFO_PTR_TO_STRUCT(p); + return info->type != INVALID_OBJECT && info->type < N_CLOSURE_TYPES; +} + +INLINE_HEADER rtsBool LOOKS_LIKE_INFO_PTR (StgWord p) +{ + return p && (IS_FORWARDING_PTR(p) || LOOKS_LIKE_INFO_PTR_NOT_NULL(p)); +} + +INLINE_HEADER rtsBool LOOKS_LIKE_CLOSURE_PTR (void *p) +{ + return LOOKS_LIKE_INFO_PTR((StgWord)(UNTAG_CLOSURE((StgClosure *)(p)))->header.info); +} + +/* ----------------------------------------------------------------------------- + Macros for calculating the size of a closure + -------------------------------------------------------------------------- */ + +INLINE_HEADER StgOffset PAP_sizeW ( nat n_args ) +{ return sizeofW(StgPAP) + n_args; } + +INLINE_HEADER StgOffset AP_sizeW ( nat n_args ) +{ return sizeofW(StgAP) + n_args; } + +INLINE_HEADER StgOffset AP_STACK_sizeW ( nat size ) +{ return sizeofW(StgAP_STACK) + size; } + +INLINE_HEADER StgOffset CONSTR_sizeW( nat p, nat np ) +{ return sizeofW(StgHeader) + p + np; } + +INLINE_HEADER StgOffset THUNK_SELECTOR_sizeW ( void ) +{ return sizeofW(StgSelector); } + +INLINE_HEADER StgOffset BLACKHOLE_sizeW ( void ) +{ return sizeofW(StgHeader)+MIN_PAYLOAD_SIZE; } + +/* -------------------------------------------------------------------------- + Sizes of closures + ------------------------------------------------------------------------*/ + +INLINE_HEADER StgOffset sizeW_fromITBL( const StgInfoTable* itbl ) +{ return sizeofW(StgClosure) + + sizeofW(StgPtr) * itbl->layout.payload.ptrs + + sizeofW(StgWord) * itbl->layout.payload.nptrs; } + +INLINE_HEADER StgOffset thunk_sizeW_fromITBL( const StgInfoTable* itbl ) +{ return sizeofW(StgThunk) + + sizeofW(StgPtr) * itbl->layout.payload.ptrs + + sizeofW(StgWord) * itbl->layout.payload.nptrs; } + +INLINE_HEADER StgOffset ap_stack_sizeW( StgAP_STACK* x ) +{ return AP_STACK_sizeW(x->size); } + +INLINE_HEADER StgOffset ap_sizeW( StgAP* x ) +{ return AP_sizeW(x->n_args); } + +INLINE_HEADER StgOffset pap_sizeW( StgPAP* x ) +{ return PAP_sizeW(x->n_args); } + +INLINE_HEADER StgOffset arr_words_sizeW( StgArrWords* x ) +{ return sizeofW(StgArrWords) + x->words; } + +INLINE_HEADER StgOffset mut_arr_ptrs_sizeW( StgMutArrPtrs* x ) +{ return sizeofW(StgMutArrPtrs) + x->ptrs; } + +INLINE_HEADER StgWord tso_sizeW ( StgTSO *tso ) +{ return TSO_STRUCT_SIZEW + tso->stack_size; } + +INLINE_HEADER StgWord bco_sizeW ( StgBCO *bco ) +{ return bco->size; } + +INLINE_HEADER nat +closure_sizeW_ (StgClosure *p, StgInfoTable *info) +{ + switch (info->type) { + case THUNK_0_1: + case THUNK_1_0: + return sizeofW(StgThunk) + 1; + case FUN_0_1: + case CONSTR_0_1: + case FUN_1_0: + case CONSTR_1_0: + return sizeofW(StgHeader) + 1; + case THUNK_0_2: + case THUNK_1_1: + case THUNK_2_0: + return sizeofW(StgThunk) + 2; + case FUN_0_2: + case CONSTR_0_2: + case FUN_1_1: + case CONSTR_1_1: + case FUN_2_0: + case CONSTR_2_0: + return sizeofW(StgHeader) + 2; + case THUNK: + return thunk_sizeW_fromITBL(info); + case THUNK_SELECTOR: + return THUNK_SELECTOR_sizeW(); + case AP_STACK: + return ap_stack_sizeW((StgAP_STACK *)p); + case AP: + return ap_sizeW((StgAP *)p); + case PAP: + return pap_sizeW((StgPAP *)p); + case IND: + case IND_PERM: + case IND_OLDGEN: + case IND_OLDGEN_PERM: + return sizeofW(StgInd); + case ARR_WORDS: + return arr_words_sizeW((StgArrWords *)p); + case MUT_ARR_PTRS_CLEAN: + case MUT_ARR_PTRS_DIRTY: + case MUT_ARR_PTRS_FROZEN: + case MUT_ARR_PTRS_FROZEN0: + return mut_arr_ptrs_sizeW((StgMutArrPtrs*)p); + case TSO: + return tso_sizeW((StgTSO *)p); + case BCO: + return bco_sizeW((StgBCO *)p); + case TVAR_WATCH_QUEUE: + return sizeofW(StgTVarWatchQueue); + case TVAR: + return sizeofW(StgTVar); + case TREC_CHUNK: + return sizeofW(StgTRecChunk); + case TREC_HEADER: + return sizeofW(StgTRecHeader); + case ATOMIC_INVARIANT: + return sizeofW(StgAtomicInvariant); + case INVARIANT_CHECK_QUEUE: + return sizeofW(StgInvariantCheckQueue); + default: + return sizeW_fromITBL(info); + } +} + +// The definitive way to find the size, in words, of a heap-allocated closure +INLINE_HEADER nat +closure_sizeW (StgClosure *p) +{ + return closure_sizeW_(p, get_itbl(p)); +} + +/* ----------------------------------------------------------------------------- + Sizes of stack frames + -------------------------------------------------------------------------- */ + +INLINE_HEADER StgWord stack_frame_sizeW( StgClosure *frame ) +{ + StgRetInfoTable *info; + + info = get_ret_itbl(frame); + switch (info->i.type) { + + case RET_DYN: + { + StgRetDyn *dyn = (StgRetDyn *)frame; + return sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE + + RET_DYN_NONPTR_REGS_SIZE + + RET_DYN_PTRS(dyn->liveness) + RET_DYN_NONPTRS(dyn->liveness); + } + + case RET_FUN: + return sizeofW(StgRetFun) + ((StgRetFun *)frame)->size; + + case RET_BIG: + return 1 + GET_LARGE_BITMAP(&info->i)->size; + + case RET_BCO: + return 2 + BCO_BITMAP_SIZE((StgBCO *)((P_)frame)[1]); + + default: + return 1 + BITMAP_SIZE(info->i.layout.bitmap); + } +} + +#endif /* RTS_STORAGE_CLOSUREMACROS_H */ diff --git a/includes/ClosureTypes.h b/includes/rts/storage/ClosureTypes.h index 99bd3060ff..3415d423a3 100644 --- a/includes/ClosureTypes.h +++ b/includes/rts/storage/ClosureTypes.h @@ -7,8 +7,8 @@ * * -------------------------------------------------------------------------- */ -#ifndef CLOSURETYPES_H -#define CLOSURETYPES_H +#ifndef RTS_STORAGE_CLOSURETYPES_H +#define RTS_STORAGE_CLOSURETYPES_H /* * WARNING WARNING WARNING @@ -93,4 +93,4 @@ #define WHITEHOLE 69 #define N_CLOSURE_TYPES 70 -#endif /* CLOSURETYPES_H */ +#endif /* RTS_STORAGE_CLOSURETYPES_H */ diff --git a/includes/Closures.h b/includes/rts/storage/Closures.h index eb5d1ed89d..6e06e57f3c 100644 --- a/includes/Closures.h +++ b/includes/rts/storage/Closures.h @@ -6,8 +6,8 @@ * * -------------------------------------------------------------------------- */ -#ifndef CLOSURES_H -#define CLOSURES_H +#ifndef RTS_STORAGE_CLOSURES_H +#define RTS_STORAGE_CLOSURES_H /* * The Layout of a closure header depends on which kind of system we're @@ -51,14 +51,14 @@ typedef struct { -------------------------------------------------------------------------- */ typedef struct { - const struct _StgInfoTable* info; + const StgInfoTable* info; #ifdef PROFILING StgProfHeader prof; #endif } StgHeader; typedef struct { - const struct _StgInfoTable* info; + const StgInfoTable* info; #ifdef PROFILING StgProfHeader prof; #endif @@ -77,10 +77,10 @@ typedef struct { /* All closures follow the generic format */ -struct StgClosure_ { +typedef struct StgClosure_ { StgHeader header; struct StgClosure_ *payload[FLEXIBLE_ARRAY]; -}; +} *StgClosurePtr; // StgClosure defined in Rts.h typedef struct { StgThunkHeader header; @@ -124,7 +124,7 @@ typedef struct { StgHeader header; StgClosure *indirectee; StgClosure *static_link; - struct _StgInfoTable *saved_info; + StgInfoTable *saved_info; } StgIndStatic; typedef struct { @@ -273,7 +273,7 @@ typedef struct { -------------------------------------------------------------------------- */ typedef struct { - const struct _StgInfoTable* info; + const StgInfoTable* info; StgWord liveness; StgWord ret_addr; StgClosure * payload[FLEXIBLE_ARRAY]; @@ -287,7 +287,7 @@ typedef struct { * The stack frame size is also cached in the frame for convenience. */ typedef struct { - const struct _StgInfoTable* info; + const StgInfoTable* info; StgWord size; StgClosure * fun; StgClosure * payload[FLEXIBLE_ARRAY]; @@ -414,4 +414,4 @@ typedef struct { StgClosure *alt_code; } StgCatchRetryFrame; -#endif /* CLOSURES_H */ +#endif /* RTS_STORAGE_CLOSURES_H */ diff --git a/includes/StgFun.h b/includes/rts/storage/FunTypes.h index e6f9b1fe0e..402c913bcd 100644 --- a/includes/StgFun.h +++ b/includes/rts/storage/FunTypes.h @@ -1,11 +1,13 @@ /* ----------------------------------------------------------------------------- + * * (c) The GHC Team, 2002 * * Things for functions. + * * ---------------------------------------------------------------------------*/ -#ifndef STGFUN_H -#define STGFUN_H +#ifndef RTS_STORAGE_FUNTYPES_H +#define RTS_STORAGE_FUNTYPES_ /* generic - function comes with a small bitmap */ #define ARG_GEN 0 @@ -49,4 +51,4 @@ #define ARG_PPPPPPP 24 #define ARG_PPPPPPPP 25 -#endif /* STGFUN_H */ +#endif /* RTS_STORAGE_FUNTYPES_H */ diff --git a/includes/rts/storage/GC.h b/includes/rts/storage/GC.h new file mode 100644 index 0000000000..df4ba9d153 --- /dev/null +++ b/includes/rts/storage/GC.h @@ -0,0 +1,204 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2004 + * + * External Storage Manger Interface + * + * ---------------------------------------------------------------------------*/ + +#ifndef RTS_STORAGE_GC_H +#define RTS_STORAGE_GC_H + +#include <stddef.h> +#include "rts/OSThreads.h" + +/* ----------------------------------------------------------------------------- + * Generational GC + * + * We support an arbitrary number of generations, with an arbitrary number + * of steps per generation. Notes (in no particular order): + * + * - all generations except the oldest should have the same + * number of steps. Multiple steps gives objects a decent + * chance to age before being promoted, and helps ensure that + * we don't end up with too many thunks being updated in older + * generations. + * + * - the oldest generation has one step. There's no point in aging + * objects in the oldest generation. + * + * - generation 0, step 0 (G0S0) is the allocation area. It is given + * a fixed set of blocks during initialisation, and these blocks + * normally stay in G0S0. In parallel execution, each + * Capability has its own nursery. + * + * - during garbage collection, each step which is an evacuation + * destination (i.e. all steps except G0S0) is allocated a to-space. + * evacuated objects are allocated into the step's to-space until + * GC is finished, when the original step's contents may be freed + * and replaced by the to-space. + * + * - the mutable-list is per-generation (not per-step). G0 doesn't + * have one (since every garbage collection collects at least G0). + * + * - block descriptors contain pointers to both the step and the + * generation that the block belongs to, for convenience. + * + * - static objects are stored in per-generation lists. See GC.c for + * details of how we collect CAFs in the generational scheme. + * + * - large objects are per-step, and are promoted in the same way + * as small objects, except that we may allocate large objects into + * generation 1 initially. + * + * ------------------------------------------------------------------------- */ + +typedef struct step_ { + unsigned int no; // step number in this generation + unsigned int abs_no; // absolute step number + + struct generation_ * gen; // generation this step belongs to + unsigned int gen_no; // generation number (cached) + + bdescr * blocks; // blocks in this step + unsigned int n_blocks; // number of blocks + unsigned int n_words; // number of words + + struct step_ * to; // destination step for live objects + + bdescr * large_objects; // large objects (doubly linked) + unsigned int n_large_blocks; // no. of blocks used by large objs + + StgTSO * threads; // threads in this step + // linked via global_link + + // ------------------------------------ + // Fields below are used during GC only + + // During GC, if we are collecting this step, blocks and n_blocks + // are copied into the following two fields. After GC, these blocks + // are freed. + +#if defined(THREADED_RTS) + char pad[128]; // make sure the following is + // on a separate cache line. + SpinLock sync_large_objects; // lock for large_objects + // and scavenged_large_objects +#endif + + int mark; // mark (not copy)? (old gen only) + int compact; // compact (not sweep)? (old gen only) + + bdescr * old_blocks; // bdescr of first from-space block + unsigned int n_old_blocks; // number of blocks in from-space + unsigned int live_estimate; // for sweeping: estimate of live data + + bdescr * part_blocks; // partially-full scanned blocks + unsigned int n_part_blocks; // count of above + + bdescr * scavenged_large_objects; // live large objs after GC (d-link) + unsigned int n_scavenged_large_blocks; // size (not count) of above + + bdescr * bitmap; // bitmap for compacting collection + + StgTSO * old_threads; + +} step; + + +typedef struct generation_ { + unsigned int no; // generation number + step * steps; // steps + unsigned int n_steps; // number of steps + unsigned int max_blocks; // max blocks in step 0 + bdescr *mut_list; // mut objects in this gen (not G0) + + // stats information + unsigned int collections; + unsigned int par_collections; + unsigned int failed_promotions; + + // temporary use during GC: + bdescr *saved_mut_list; +} generation; + +extern generation * generations; + +extern generation * g0; +extern step * g0s0; +extern generation * oldest_gen; +extern step * all_steps; +extern nat total_steps; + +/* ----------------------------------------------------------------------------- + Generic allocation + + StgPtr allocateInGen(generation *g, nat n) + Allocates a chunk of contiguous store + n words long in generation g, + returning a pointer to the first word. + Always succeeds. + + StgPtr allocate(nat n) Equaivalent to allocateInGen(g0) + + StgPtr allocateLocal(Capability *cap, nat n) + Allocates memory from the nursery in + the current Capability. This can be + done without taking a global lock, + unlike allocate(). + + StgPtr allocatePinned(nat n) Allocates a chunk of contiguous store + n words long, which is at a fixed + address (won't be moved by GC). + Returns a pointer to the first word. + Always succeeds. + + NOTE: the GC can't in general handle + pinned objects, so allocatePinned() + can only be used for ByteArrays at the + moment. + + Don't forget to TICK_ALLOC_XXX(...) + after calling allocate or + allocatePinned, for the + benefit of the ticky-ticky profiler. + + rtsBool doYouWantToGC(void) Returns True if the storage manager is + ready to perform a GC, False otherwise. + + lnat allocatedBytes(void) Returns the number of bytes allocated + via allocate() since the last GC. + Used in the reporting of statistics. + + -------------------------------------------------------------------------- */ + +StgPtr allocate ( lnat n ); +StgPtr allocateInGen ( generation *g, lnat n ); +StgPtr allocateLocal ( Capability *cap, lnat n ); +StgPtr allocatePinned ( lnat n ); +lnat allocatedBytes ( void ); + +/* memory allocator for executable memory */ +void * allocateExec(unsigned int len, void **exec_addr); +void freeExec (void *p); + +/* ----------------------------------------------------------------------------- + Performing Garbage Collection + -------------------------------------------------------------------------- */ + +void performGC(void); +void performMajorGC(void); + +/* ----------------------------------------------------------------------------- + The CAF table - used to let us revert CAFs in GHCi + -------------------------------------------------------------------------- */ + +void newCAF (StgClosure*); +void newDynCAF (StgClosure *); +void revertCAFs (void); + +/* set to disable CAF garbage collection in GHCi. */ +/* (needed when dynamic libraries are used). */ +extern rtsBool keepCAFs; + +#endif /* RTS_STORAGE_GC_H */ diff --git a/includes/InfoTables.h b/includes/rts/storage/InfoTables.h index 0c6ab52745..4596ce2d75 100644 --- a/includes/InfoTables.h +++ b/includes/rts/storage/InfoTables.h @@ -6,8 +6,8 @@ * * -------------------------------------------------------------------------- */ -#ifndef INFOTABLES_H -#define INFOTABLES_H +#ifndef RTS_STORAGE_INFOTABLES_H +#define RTS_STORAGE_INFOTABLES_H /* ---------------------------------------------------------------------------- Relative pointers @@ -212,11 +212,7 @@ typedef union { /* * The "standard" part of an info table. Every info table has this bit. */ -typedef struct _StgInfoTable { - -#ifndef TABLES_NEXT_TO_CODE - StgFunPtr entry; /* pointer to the entry code */ -#endif +typedef struct StgInfoTable_ { #ifdef PROFILING StgProfInfo prof; @@ -236,7 +232,7 @@ typedef struct _StgInfoTable { #ifdef TABLES_NEXT_TO_CODE StgCode code[FLEXIBLE_ARRAY]; #endif -} StgInfoTable; +} *StgInfoTablePtr; /* ----------------------------------------------------------------------------- @@ -254,7 +250,7 @@ typedef struct _StgInfoTable { bitmap fields have also been omitted. -------------------------------------------------------------------------- */ -typedef struct _StgFunInfoExtraRev { +typedef struct StgFunInfoExtraRev_ { OFFSET_FIELD ( slow_apply_offset ); /* apply to args on the stack */ union { StgWord bitmap; @@ -265,7 +261,7 @@ typedef struct _StgFunInfoExtraRev { StgHalfWord arity; /* function arity */ } StgFunInfoExtraRev; -typedef struct _StgFunInfoExtraFwd { +typedef struct StgFunInfoExtraFwd_ { StgHalfWord fun_type; /* function type */ StgHalfWord arity; /* function arity */ StgSRT *srt; /* pointer to the SRT table */ @@ -313,7 +309,7 @@ typedef struct { * pointer iff srt_bitmap is zero. */ -typedef struct _StgThunkInfoTable { +typedef struct StgThunkInfoTable_ { #if !defined(TABLES_NEXT_TO_CODE) StgInfoTable i; #endif @@ -331,7 +327,7 @@ typedef struct _StgThunkInfoTable { Constructor info tables -------------------------------------------------------------------------- */ -typedef struct _StgConInfoTable { +typedef struct StgConInfoTable_ { #if !defined(TABLES_NEXT_TO_CODE) StgInfoTable i; #endif @@ -410,4 +406,5 @@ typedef struct _StgConInfoTable { #else #define GET_PROF_DESC(info) ((info)->prof.closure_desc) #endif -#endif /* INFOTABLES_H */ + +#endif /* RTS_STORAGE_INFOTABLES_H */ diff --git a/includes/Liveness.h b/includes/rts/storage/Liveness.h index cc93cae34f..66c82f3134 100644 --- a/includes/Liveness.h +++ b/includes/rts/storage/Liveness.h @@ -11,8 +11,8 @@ * * -------------------------------------------------------------------------- */ -#ifndef LIVENESS_H -#define LIVENESS_H +#ifndef RTS_STORAGE_LIVENESS_H +#define RTS_STORAGE_LIVENESS_H #define NO_PTRS 0xff #define R1_PTR (NO_PTRS ^ (1<<0)) @@ -31,4 +31,4 @@ #define RET_DYN_PTRS(l) ((l)>>24 & 0xff) #define RET_DYN_LIVENESS(l) ((l) & 0xffff) -#endif /* LIVENESS_H */ +#endif /* RTS_STORAGE_LIVENESS_H */ diff --git a/includes/rts/storage/MBlock.h b/includes/rts/storage/MBlock.h new file mode 100644 index 0000000000..03396c1fd7 --- /dev/null +++ b/includes/rts/storage/MBlock.h @@ -0,0 +1,206 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2008 + * + * MegaBlock Allocator interface. + * + * See wiki commentary at + * http://hackage.haskell.org/trac/ghc/wiki/Commentary/HeapAlloced + * + * ---------------------------------------------------------------------------*/ + +#ifndef RTS_STORAGE_MBLOCK_H +#define RTS_STORAGE_MBLOCK_H + +extern lnat mblocks_allocated; + +extern void initMBlocks(void); +extern void * getMBlock(void); +extern void * getMBlocks(nat n); +extern void freeAllMBlocks(void); + +#ifdef DEBUG +extern void *getFirstMBlock(void); +extern void *getNextMBlock(void *mblock); +#endif + +/* ----------------------------------------------------------------------------- + The HEAP_ALLOCED() test. + + HEAP_ALLOCED is called FOR EVERY SINGLE CLOSURE during GC. + It needs to be FAST. + + See wiki commentary at + http://hackage.haskell.org/trac/ghc/wiki/Commentary/HeapAlloced + + Implementation of HEAP_ALLOCED + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Since heap is allocated in chunks of megablocks (MBLOCK_SIZE), we + can just use a table to record which megablocks in the address + space belong to the heap. On a 32-bit machine, with 1Mb + megablocks, using 8 bits for each entry in the table, the table + requires 4k. Lookups during GC will be fast, because the table + will be quickly cached (indeed, performance measurements showed no + measurable difference between doing the table lookup and using a + constant comparison). + + On 64-bit machines, we cache one 12-bit block map that describes + 4096 megablocks or 4GB of memory. If HEAP_ALLOCED is called for + an address that is not in the cache, it calls slowIsHeapAlloced + (see MBlock.c) which will find the block map for the 4GB block in + question. + -------------------------------------------------------------------------- */ + +#if SIZEOF_VOID_P == 4 +extern StgWord8 mblock_map[]; + +/* On a 32-bit machine a 4KB table is always sufficient */ +# define MBLOCK_MAP_SIZE 4096 +# define MBLOCK_MAP_ENTRY(p) ((StgWord)(p) >> MBLOCK_SHIFT) +# define HEAP_ALLOCED(p) mblock_map[MBLOCK_MAP_ENTRY(p)] +# define HEAP_ALLOCED_GC(p) HEAP_ALLOCED(p) + +/* ----------------------------------------------------------------------------- + HEAP_ALLOCED for 64-bit machines. + + Here are some cache layout options: + + [1] + 16KB cache of 16-bit entries, 1MB lines (capacity 8GB) + mblock size = 20 bits + entries = 8192 13 bits + line size = 0 bits (1 bit of value) + tag size = 15 bits + = 48 bits + + [2] + 32KB cache of 16-bit entries, 4MB lines (capacity 32GB) + mblock size = 20 bits + entries = 16384 14 bits + line size = 2 bits (4 bits of value) + tag size = 12 bits + = 48 bits + + [3] + 16KB cache of 16-bit entries, 2MB lines (capacity 16GB) + mblock size = 20 bits + entries = 8192 13 bits + line size = 1 bits (2 bits of value) + tag size = 14 bits + = 48 bits + + [4] + 4KB cache of 32-bit entries, 16MB lines (capacity 16GB) + mblock size = 20 bits + entries = 1024 10 bits + line size = 4 bits (16 bits of value) + tag size = 14 bits + = 48 bits + + [5] + 4KB cache of 64-bit entries, 32MB lines (capacity 16GB) + mblock size = 20 bits + entries = 512 9 bits + line size = 5 bits (32 bits of value) + tag size = 14 bits + = 48 bits + + We actually use none of the above. After much experimentation it was + found that optimising the lookup is the most important factor, + followed by reducing the number of misses. To that end, we use a + variant of [1] in which each cache entry is ((mblock << 1) + value) + where value is 0 for non-heap and 1 for heap. The cache entries can + be 32 bits, since the mblock number is 48-20 = 28 bits, and we need + 1 bit for the value. The cache can be as big as we like, but + currently we use 8k entries, giving us 8GB capacity. + + ---------------------------------------------------------------------------- */ + +#elif SIZEOF_VOID_P == 8 + +#define MBC_LINE_BITS 0 +#define MBC_TAG_BITS 15 +typedef StgWord32 MbcCacheLine; // could use 16, but 32 was faster +typedef StgWord8 MBlockMapLine; + +#define MBLOCK_MAP_LINE(p) (((StgWord)p & 0xffffffff) >> (MBLOCK_SHIFT + MBC_LINE_BITS)) + +#define MBC_LINE_SIZE (1<<MBC_LINE_BITS) +#define MBC_SHIFT (48 - MBLOCK_SHIFT - MBC_LINE_BITS - MBC_TAG_BITS) +#define MBC_ENTRIES (1<<MBC_SHIFT) + +extern MbcCacheLine mblock_cache[]; + +#define MBC_LINE(p) ((StgWord)p >> (MBLOCK_SHIFT + MBC_LINE_BITS)) + +#define MBLOCK_MAP_ENTRIES (1 << (32 - MBLOCK_SHIFT - MBC_LINE_BITS)) + +typedef struct { + StgWord32 addrHigh32; + MBlockMapLine lines[MBLOCK_MAP_ENTRIES]; +} MBlockMap; + +extern lnat mpc_misses; + +StgBool HEAP_ALLOCED_miss(StgWord mblock, void *p); + +INLINE_HEADER +StgBool HEAP_ALLOCED(void *p) +{ + StgWord mblock; + nat entry_no; + MbcCacheLine entry, value; + + mblock = (StgWord)p >> MBLOCK_SHIFT; + entry_no = mblock & (MBC_ENTRIES-1); + entry = mblock_cache[entry_no]; + value = entry ^ (mblock << 1); + // this formulation coaxes gcc into prioritising the value==1 + // case, which we expect to be the most common. + // __builtin_expect() didn't have any useful effect (gcc-4.3.0). + if (value == 1) { + return 1; + } else if (value == 0) { + return 0; + } else { + // putting the rest out of line turned out to be a slight + // performance improvement: + return HEAP_ALLOCED_miss(mblock,p); + } +} + +// In the parallel GC, the cache itself is safe to *read*, and can be +// updated atomically, but we need to place a lock around operations +// that touch the MBlock map. +INLINE_HEADER +StgBool HEAP_ALLOCED_GC(void *p) +{ + StgWord mblock; + nat entry_no; + MbcCacheLine entry, value; + StgBool b; + + mblock = (StgWord)p >> MBLOCK_SHIFT; + entry_no = mblock & (MBC_ENTRIES-1); + entry = mblock_cache[entry_no]; + value = entry ^ (mblock << 1); + if (value == 1) { + return 1; + } else if (value == 0) { + return 0; + } else { + // putting the rest out of line turned out to be a slight + // performance improvement: + ACQUIRE_SPIN_LOCK(&gc_alloc_block_sync); + b = HEAP_ALLOCED_miss(mblock,p); + RELEASE_SPIN_LOCK(&gc_alloc_block_sync); + return b; + } +} + +#else +# error HEAP_ALLOCED not defined +#endif + +#endif /* RTS_STORAGE_MBLOCK_H */ diff --git a/includes/SMPClosureOps.h b/includes/rts/storage/SMPClosureOps.h index f46dbdefe8..d5f7c3f295 100644 --- a/includes/SMPClosureOps.h +++ b/includes/rts/storage/SMPClosureOps.h @@ -6,8 +6,8 @@ * * -------------------------------------------------------------------------- */ -#ifndef SMPCLOSUREOPS_H -#define SMPCLOSUREOPS_H +#ifndef RTS_STORAGE_SMPCLOSUREOPS_H +#define RTS_STORAGE_SMPCLOSUREOPS_H #ifdef CMINUSMINUS @@ -75,4 +75,4 @@ EXTERN_INLINE void unlockTSO(StgTSO *tso) #endif /* CMINUSMINUS */ -#endif /* SMPCLOSUREOPS_H */ +#endif /* RTS_STORAGE_SMPCLOSUREOPS_H */ diff --git a/includes/TSO.h b/includes/rts/storage/TSO.h index af624f7666..7cb245909f 100644 --- a/includes/TSO.h +++ b/includes/rts/storage/TSO.h @@ -1,36 +1,13 @@ /* ----------------------------------------------------------------------------- * - * (c) The GHC Team, 1998-1999 + * (c) The GHC Team, 1998-2009 * * The definitions for Thread State Objects. * * ---------------------------------------------------------------------------*/ -#ifndef TSO_H -#define TSO_H - -#if DEBUG -#define TSO_MAGIC 4321 -#endif - -typedef struct { - StgInt pri; - StgInt magic; - StgInt sparkname; - rtsTime startedat; - rtsBool exported; - StgInt basicblocks; - StgInt allocs; - rtsTime exectime; - rtsTime fetchtime; - rtsTime fetchcount; - rtsTime blocktime; - StgInt blockcount; - rtsTime blockedat; - StgInt globalsparks; - StgInt localsparks; - rtsTime clock; -} StgTSOStatBuf; +#ifndef RTS_STORAGE_TSO_H +#define RTS_STORAGE_TSO_H /* * PROFILING info in a TSO @@ -146,14 +123,14 @@ typedef struct StgTSO_ { StgPtr sp; StgWord stack[FLEXIBLE_ARRAY]; -} StgTSO; +} *StgTSOPtr; /* ----------------------------------------------------------------------------- functions -------------------------------------------------------------------------- */ -extern void dirty_TSO (Capability *cap, StgTSO *tso); -extern void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); +void dirty_TSO (Capability *cap, StgTSO *tso); +void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); /* ----------------------------------------------------------------------------- Invariants: @@ -174,7 +151,7 @@ extern void setTSOLink (Capability *cap, StgTSO *tso, StgTSO *target); ---------------------------------------------------------------------- NotBlocked NULL runnable_queue, or running - BlockedOnBlackHole the BLACKHOLE_BQ the BLACKHOLE_BQ's queue + BlockedOnBlackHole the BLACKHOLE blackhole_queue BlockedOnMVar the MVAR the MVAR's queue @@ -226,4 +203,4 @@ extern StgTSO dummy_tso; /* this is the NIL ptr for a TSO queue (e.g. runnable queue) */ #define END_TSO_QUEUE ((StgTSO *)(void*)&stg_END_TSO_QUEUE_closure) -#endif /* TSO_H */ +#endif /* RTS_STORAGE_TSO_H */ diff --git a/includes/StgDLL.h b/includes/stg/DLL.h index 5e824271bf..5e824271bf 100644 --- a/includes/StgDLL.h +++ b/includes/stg/DLL.h diff --git a/includes/MachRegs.h b/includes/stg/MachRegs.h index d6075326db..d6075326db 100644 --- a/includes/MachRegs.h +++ b/includes/stg/MachRegs.h diff --git a/includes/StgMiscClosures.h b/includes/stg/MiscClosures.h index d5a03fcdd9..1591570780 100644 --- a/includes/StgMiscClosures.h +++ b/includes/stg/MiscClosures.h @@ -253,7 +253,6 @@ RTS_INFO(stg_sel_5_upd_info); RTS_INFO(stg_sel_6_upd_info); RTS_INFO(stg_sel_7_upd_info); RTS_INFO(stg_sel_8_upd_info); -RTS_INFO(stg_sel_8_upd_info); RTS_INFO(stg_sel_9_upd_info); RTS_INFO(stg_sel_10_upd_info); RTS_INFO(stg_sel_11_upd_info); @@ -271,7 +270,6 @@ RTS_ENTRY(stg_sel_5_upd_entry); RTS_ENTRY(stg_sel_6_upd_entry); RTS_ENTRY(stg_sel_7_upd_entry); RTS_ENTRY(stg_sel_8_upd_entry); -RTS_ENTRY(stg_sel_8_upd_entry); RTS_ENTRY(stg_sel_9_upd_entry); RTS_ENTRY(stg_sel_10_upd_entry); RTS_ENTRY(stg_sel_11_upd_entry); @@ -517,7 +515,7 @@ RTS_FUN(orIntegerzh_fast); RTS_FUN(xorIntegerzh_fast); RTS_FUN(complementIntegerzh_fast); -#ifdef SUPPORT_LONG_LONGS +#if SIZEOF_HSINT == 4 RTS_FUN(int64ToIntegerzh_fast); RTS_FUN(word64ToIntegerzh_fast); diff --git a/includes/Regs.h b/includes/stg/Regs.h index beb71c9184..fb26254d5a 100644 --- a/includes/Regs.h +++ b/includes/stg/Regs.h @@ -37,14 +37,9 @@ typedef union { StgWord w; StgAddr a; StgChar c; - StgInt8 i8; StgFloat f; StgInt i; StgPtr p; - StgClosurePtr cl; - StgStackOffset offset; /* unused? */ - StgByteArray b; - StgTSOPtr t; } StgUnion; /* diff --git a/includes/SMP.h b/includes/stg/SMP.h index b7538424b9..5d9d80169b 100644 --- a/includes/SMP.h +++ b/includes/stg/SMP.h @@ -9,28 +9,17 @@ #ifndef SMP_H #define SMP_H -/* THREADED_RTS is currently not compatible with the following options: - * - * PROFILING (but only 1 CPU supported) - * TICKY_TICKY - * Unregisterised builds are ok, but only 1 CPU supported. - */ - #if defined(THREADED_RTS) -#if defined(TICKY_TICKY) -#error Build options incompatible with THREADED_RTS. -#endif - /* ---------------------------------------------------------------------------- Atomic operations ------------------------------------------------------------------------- */ -#if !IN_STG_CODE -// We only want write_barrier() declared in .hc files. Defining the -// other inline functions here causes type mismatch errors from gcc, -// because the generated C code is assuming that there are no -// prototypes in scope. +#if !IN_STG_CODE || IN_STGCRUN +// We only want the barriers, e.g. write_barrier(), declared in .hc +// files. Defining the other inline functions here causes type +// mismatch errors from gcc, because the generated C code is assuming +// that there are no prototypes in scope. /* * The atomic exchange operation: xchg(p,w) exchanges the value @@ -94,12 +83,8 @@ EXTERN_INLINE void load_load_barrier(void); Implementations ------------------------------------------------------------------------- */ -#if !IN_STG_CODE +#if !IN_STG_CODE || IN_STGCRUN -/* - * NB: the xchg instruction is implicitly locked, so we do not need - * a lock prefix here. - */ EXTERN_INLINE StgWord xchg(StgPtr p, StgWord w) { @@ -107,6 +92,8 @@ xchg(StgPtr p, StgWord w) #if i386_HOST_ARCH || x86_64_HOST_ARCH result = w; __asm__ __volatile__ ( + // NB: the xchg instruction is implicitly locked, so we do not + // need a lock prefix here. "xchg %1,%0" :"+r" (result), "+m" (*p) : /* no input-only operands */ diff --git a/includes/TailCalls.h b/includes/stg/TailCalls.h index 854c7b4b18..854c7b4b18 100644 --- a/includes/TailCalls.h +++ b/includes/stg/TailCalls.h diff --git a/includes/TickyCounters.h b/includes/stg/Ticky.h index 38e84ef2af..fd7edf85c5 100644 --- a/includes/TickyCounters.h +++ b/includes/stg/Ticky.h @@ -3,7 +3,8 @@ * (c) The GHC Team, 2007 * * Declarations for counters used by ticky-ticky profiling. - *----------------------------------------------------------------------------- */ + * + * -------------------------------------------------------------------------- */ #ifndef TICKYCOUNTERS_H @@ -25,7 +26,6 @@ #define EXTERN extern #endif - /* Here are all the counter declarations: */ EXTERN StgInt ENT_VIA_NODE_ctr INIT(0); diff --git a/includes/StgTypes.h b/includes/stg/Types.h index 7f2c08e5e2..227356c9ea 100644 --- a/includes/StgTypes.h +++ b/includes/stg/Types.h @@ -19,9 +19,8 @@ StgInt Signed version of StgWord StgAddr Generic address type - StgBool, StgVoid, StgClosurePtr, StgPtr, StgOffset, - StgTSOPtr, StgForeignPtr, StgStackOffset, StgStackPtr, - StgCode, StgArray, StgByteArray, StgStablePtr, StgFunPtr, + StgBool, StgVoid, StgPtr, StgOffset, + StgCode, StgStablePtr, StgFunPtr, StgUnion. * WARNING: Keep this file, MachDeps.h, and HsFFI.h in synch! @@ -58,23 +57,17 @@ typedef unsigned int StgWord32; #error GHC untested on this architecture: sizeof(int) != 4 #endif -#ifdef SUPPORT_LONG_LONGS -/* assume long long is 64 bits */ -# ifndef _MSC_VER -typedef signed long long int StgInt64; -typedef unsigned long long int StgWord64; -# else -typedef __int64 StgInt64; -typedef unsigned __int64 StgWord64; -# endif -#elif SIZEOF_LONG == 8 +#if SIZEOF_LONG == 8 typedef signed long StgInt64; typedef unsigned long StgWord64; #elif defined(__MSVC__) typedef __int64 StgInt64; typedef unsigned __int64 StgWord64; +#elif SIZEOF_LONG_LONG == 8 +typedef signed long long int StgInt64; +typedef unsigned long long int StgWord64; #else -#error GHC untested on this architecture: sizeof(void *) < 8 and no long longs. +#error cannot find a way to define StgInt64 #endif /* @@ -106,40 +99,21 @@ typedef StgWord16 StgHalfWord; #define W_MASK (sizeof(W_)-1) -typedef void* StgAddr; - /* * Other commonly-used STG datatypes. */ +typedef void* StgAddr; typedef StgWord32 StgChar; typedef int StgBool; - typedef float StgFloat; typedef double StgDouble; - -typedef void StgVoid; - -typedef struct StgClosure_ StgClosure; -typedef StgClosure* StgClosurePtr; -typedef StgWord* StgPtr; /* pointer into closure */ +typedef StgWord* StgPtr; /* heap or stack pointer */ typedef StgWord volatile* StgVolatilePtr; /* pointer to volatile word */ typedef StgWord StgOffset; /* byte offset within closure */ - -typedef struct StgTSO_* StgTSOPtr; - -typedef void* StgForeignPtr; - -typedef StgInt StgStackOffset; /* offset in words! */ - -typedef StgWord* StgStackPtr; - -typedef StgWord8 StgCode; /* close enough */ - -typedef StgPtr* StgArray; /* the goods of an Array# */ -typedef char* StgByteArray; /* the goods of a ByteArray# */ - +typedef StgWord8 StgCode; /* close enough */ typedef void* StgStablePtr; +typedef StgWord8* StgByteArray; /* Types for the generated C functions |