diff options
Diffstat (limited to 'rts')
123 files changed, 1083 insertions, 1163 deletions
diff --git a/rts/Adjustor.c b/rts/Adjustor.c index e93f361aee..0f09743a02 100644 --- a/rts/Adjustor.c +++ b/rts/Adjustor.c @@ -38,9 +38,9 @@ Haskell side. #include "PosixSource.h" #include "Rts.h" -#include "RtsExternal.h" + #include "RtsUtils.h" -#include <stdlib.h> +#include "Stable.h" #if defined(USE_LIBFFI_FOR_ADJUSTORS) diff --git a/rts/Arena.c b/rts/Arena.c index fcdc6cce14..7fc49f44d7 100644 --- a/rts/Arena.c +++ b/rts/Arena.c @@ -18,12 +18,12 @@ which most allocations are small. -------------------------------------------------------------------------- */ +#include "PosixSource.h" #include "Rts.h" + #include "RtsUtils.h" #include "Arena.h" -#include <stdlib.h> - // Each arena struct is allocated using malloc(). struct _Arena { bdescr *current; diff --git a/rts/AwaitEvent.h b/rts/AwaitEvent.h index e03cb4444e..758e81a288 100644 --- a/rts/AwaitEvent.h +++ b/rts/AwaitEvent.h @@ -21,4 +21,4 @@ void awaitEvent(rtsBool wait); /* In posix/Select.c or * win32/AwaitEvent.c */ #endif -#endif /* SELECT_H */ +#endif /* AWAITEVENT_H */ diff --git a/rts/Capability.c b/rts/Capability.c index 02308d4c20..ddaba699a3 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -18,28 +18,27 @@ #include "PosixSource.h" #include "Rts.h" -#include "RtsUtils.h" -#include "RtsFlags.h" -#include "STM.h" -#include "OSThreads.h" + #include "Capability.h" #include "Schedule.h" #include "Sparks.h" #include "Trace.h" -#include "GC.h" +#include "sm/GC.h" // for gcWorkerThread() +#include "STM.h" +#include "RtsUtils.h" // one global capability, this is the Capability for non-threaded // builds, and for +RTS -N1 Capability MainCapability; -nat n_capabilities; +nat n_capabilities = 0; Capability *capabilities = NULL; // Holds the Capability which last became free. This is used so that // an in-call has a chance of quickly finding a free Capability. // Maintaining a global free list of Capabilities would require global // locking, so we don't do that. -Capability *last_free_capability; +Capability *last_free_capability = NULL; /* GC indicator, in scope for the scheduler, init'ed to false */ volatile StgWord waiting_for_gc = 0; @@ -235,8 +234,8 @@ initCapability( Capability *cap, nat i ) #endif cap->f.stgEagerBlackholeInfo = (W_)&__stg_EAGER_BLACKHOLE_info; - cap->f.stgGCEnter1 = (F_)__stg_gc_enter_1; - cap->f.stgGCFun = (F_)__stg_gc_fun; + cap->f.stgGCEnter1 = (StgFunPtr)__stg_gc_enter_1; + cap->f.stgGCFun = (StgFunPtr)__stg_gc_fun; cap->mut_lists = stgMallocBytes(sizeof(bdescr *) * RtsFlags.GcFlags.generations, diff --git a/rts/Capability.h b/rts/Capability.h index d2fcc5ed7b..fb199e2a3e 100644 --- a/rts/Capability.h +++ b/rts/Capability.h @@ -4,26 +4,21 @@ * * Capabilities * - * The notion of a capability is used when operating in multi-threaded - * environments (which the THREADED_RTS build of the RTS does), to - * hold all the state an OS thread/task needs to run Haskell code: - * its STG registers, a pointer to its TSO, a nursery etc. During - * STG execution, a pointer to the capabilitity is kept in a - * register (BaseReg). + * A Capability holds all the state an OS thread/task needs to run + * Haskell code: its STG registers, a pointer to its TSO, a nursery + * etc. During STG execution, a pointer to the Capabilitity is kept in + * a register (BaseReg). * - * Only in an THREADED_RTS build will there be multiple capabilities, - * in the non-threaded builds there is one global capability, namely + * Only in a THREADED_RTS build will there be multiple capabilities, + * in the non-threaded RTS there is one global capability, called * MainCapability. * - * This header file contains the functions for working with capabilities. - * (the main, and only, consumer of this interface is the scheduler). - * * --------------------------------------------------------------------------*/ #ifndef CAPABILITY_H #define CAPABILITY_H -#include "RtsFlags.h" +#include "sm/GC.h" // for evac_fn #include "Task.h" #include "Sparks.h" @@ -174,14 +169,14 @@ INLINE_HEADER void releaseCapability_ (Capability* cap STG_UNUSED, rtsBool always_wakeup STG_UNUSED) {}; #endif -#if !IN_STG_CODE -// one global capability -extern Capability MainCapability; -#endif +// declared in includes/rts/Threads.h: +// extern Capability MainCapability; + +// declared in includes/rts/Threads.h: +// extern nat n_capabilities; // Array of all the capabilities // -extern nat n_capabilities; extern Capability *capabilities; // The Capability that was last free. Used as a good guess for where @@ -281,7 +276,7 @@ INLINE_HEADER void contextSwitchCapability(Capability *cap); // Free all capabilities void freeCapabilities (void); -// FOr the GC: +// For the GC: void markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta, rtsBool prune_sparks); void markCapabilities (evac_fn evac, void *user); diff --git a/rts/Disassembler.c b/rts/Disassembler.c index 19c121f2f1..fff3fe9d76 100644 --- a/rts/Disassembler.c +++ b/rts/Disassembler.c @@ -13,12 +13,10 @@ #include "PosixSource.h" #include "Rts.h" #include "RtsAPI.h" +#include "rts/Bytecodes.h" + #include "RtsUtils.h" -#include "Closures.h" -#include "TSO.h" #include "Schedule.h" - -#include "Bytecodes.h" #include "Printer.h" #include "Disassembler.h" #include "Interpreter.h" diff --git a/rts/FrontPanel.c b/rts/FrontPanel.c index 2ce91e2c65..163a7c08ca 100644 --- a/rts/FrontPanel.c +++ b/rts/FrontPanel.c @@ -12,11 +12,10 @@ /* #include "PosixSource.h" */ #include "Rts.h" + #include "RtsUtils.h" -#include "MBlock.h" #include "FrontPanel.h" #include "Stats.h" -#include "RtsFlags.h" #include "Schedule.h" #include <gtk/gtk.h> diff --git a/rts/Globals.c b/rts/Globals.c index a0d0788335..15b10130a8 100644 --- a/rts/Globals.c +++ b/rts/Globals.c @@ -9,8 +9,11 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "RtsGlobals.h" + +#include "Globals.h" +#include "Stable.h" static StgStablePtr typeableStore = 0; static StgStablePtr signalHandlerStore = 0; diff --git a/rts/Globals.h b/rts/Globals.h new file mode 100644 index 0000000000..bc68904f78 --- /dev/null +++ b/rts/Globals.h @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 2006-2009 + * + * The RTS stores some "global" values on behalf of libraries, so that + * some libraries can ensure that certain top-level things are shared + * even when multiple versions of the library are loaded. e.g. see + * Data.Typeable and GHC.Conc. + * + * ---------------------------------------------------------------------------*/ + +#ifndef GLOBALS_H +#define GLOBALS_H + +void initGlobalStore(void); +void exitGlobalStore(void); + +#endif + diff --git a/rts/Hash.c b/rts/Hash.c index 033ccb3e73..09d0a06808 100644 --- a/rts/Hash.c +++ b/rts/Hash.c @@ -10,10 +10,10 @@ #include "PosixSource.h" #include "Rts.h" + #include "Hash.h" #include "RtsUtils.h" -#include <stdlib.h> #include <string.h> #define HSEGSIZE 1024 /* Size of a single hash table segment */ @@ -2,16 +2,16 @@ * (c)2006 Galois Connections, Inc. */ +#include "PosixSource.h" +#include "Rts.h" + +#include "Trace.h" + #include <stdio.h> #include <ctype.h> -#include <stdlib.h> #include <string.h> #include <assert.h> -#include "Rts.h" -#include "Hpc.h" -#include "Trace.h" - #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -49,7 +49,8 @@ int totalTixes = 0; // total number of tix boxes. static char *tixFilename; -static void failure(char *msg) { +static void GNU_ATTRIBUTE(__noreturn__) +failure(char *msg) { debugTrace(DEBUG_hpc,"hpc failure: %s\n",msg); fprintf(stderr,"Hpc failure: %s\n",msg); if (tixFilename) { diff --git a/rts/Hpc.h b/rts/Hpc.h deleted file mode 100644 index a0ff40b06c..0000000000 --- a/rts/Hpc.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef HPC_H -#define HPC_H - -extern void startupHpc(void); -extern void exitHpc(void); - -#endif /* HPC_H */ - - - diff --git a/rts/HsFFI.c b/rts/HsFFI.c index 350bcfbdec..57f91b198e 100644 --- a/rts/HsFFI.c +++ b/rts/HsFFI.c @@ -6,9 +6,12 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "HsFFI.h" #include "Rts.h" +#include "Stable.h" + // hs_init and hs_exit are defined in RtsStartup.c void diff --git a/rts/Inlines.c b/rts/Inlines.c index 5d2be70c63..88cbdd2f44 100644 --- a/rts/Inlines.c +++ b/rts/Inlines.c @@ -2,4 +2,5 @@ // compiled for real here, just in case the definition was not inlined // at some call site: #define KEEP_INLINES +#include "PosixSource.h" #include "Rts.h" diff --git a/rts/Interpreter.c b/rts/Interpreter.c index 91e500b8ee..d047876d21 100644 --- a/rts/Interpreter.c +++ b/rts/Interpreter.c @@ -7,21 +7,20 @@ #include "PosixSource.h" #include "Rts.h" #include "RtsAPI.h" +#include "rts/Bytecodes.h" + +// internal headers +#include "sm/Storage.h" #include "RtsUtils.h" -#include "Closures.h" -#include "TSO.h" #include "Schedule.h" -#include "RtsFlags.h" -#include "LdvProfile.h" #include "Updates.h" #include "Sanity.h" -#include "Liveness.h" #include "Prelude.h" - -#include "Bytecodes.h" +#include "Stable.h" #include "Printer.h" #include "Disassembler.h" #include "Interpreter.h" +#include "ThreadPaused.h" #include <string.h> /* for memcpy */ #ifdef HAVE_ERRNO_H diff --git a/rts/LdvProfile.c b/rts/LdvProfile.c index eab3ec3e4b..c97187a9a9 100644 --- a/rts/LdvProfile.c +++ b/rts/LdvProfile.c @@ -9,9 +9,9 @@ #ifdef PROFILING +#include "PosixSource.h" #include "Rts.h" -#include "LdvProfile.h" -#include "RtsFlags.h" + #include "Profiling.h" #include "Stats.h" #include "RtsUtils.h" diff --git a/rts/Linker.c b/rts/Linker.c index 162ada872c..7db88cb625 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -18,17 +18,19 @@ #endif #include "Rts.h" -#include "RtsFlags.h" #include "HsFFI.h" + +#include "sm/Storage.h" #include "Hash.h" -#include "Linker.h" #include "LinkerInternals.h" #include "RtsUtils.h" -#include "Schedule.h" -#include "Sparks.h" -#include "RtsGlobals.h" -#include "Timer.h" #include "Trace.h" +#include "StgPrimFloat.h" // for __int_encodeFloat etc. +#include "Stable.h" + +#if !defined(mingw32_HOST_OS) +#include "posix/Signals.h" +#endif #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> @@ -230,8 +232,8 @@ typedef struct _RtsSymbolVal { #if !defined (mingw32_HOST_OS) #define RTS_POSIX_ONLY_SYMBOLS \ SymI_HasProto(shutdownHaskellAndSignal) \ - SymI_NeedsProto(lockFile) \ - SymI_NeedsProto(unlockFile) \ + SymI_HasProto(lockFile) \ + SymI_HasProto(unlockFile) \ SymI_HasProto(signal_handlers) \ SymI_HasProto(stg_sig_install) \ SymI_NeedsProto(nocldstop) @@ -613,7 +615,6 @@ typedef struct _RtsSymbolVal { SymI_HasProto(forkProcess) \ SymI_HasProto(forkOS_createThread) \ SymI_HasProto(freeHaskellFunctionPtr) \ - SymI_HasProto(freeStablePtr) \ SymI_HasProto(getOrSetTypeableStore) \ SymI_HasProto(getOrSetSignalHandlerStore) \ SymI_HasProto(genSymZh) \ @@ -635,15 +636,7 @@ typedef struct _RtsSymbolVal { SymI_HasProto(getApStackValzh_fast) \ SymI_HasProto(getSparkzh_fast) \ SymI_HasProto(isCurrentThreadBoundzh_fast) \ - SymI_HasProto(isDoubleDenormalized) \ - SymI_HasProto(isDoubleInfinite) \ - SymI_HasProto(isDoubleNaN) \ - SymI_HasProto(isDoubleNegativeZero) \ SymI_HasProto(isEmptyMVarzh_fast) \ - SymI_HasProto(isFloatDenormalized) \ - SymI_HasProto(isFloatInfinite) \ - SymI_HasProto(isFloatNaN) \ - SymI_HasProto(isFloatNegativeZero) \ SymI_HasProto(killThreadzh_fast) \ SymI_HasProto(loadObj) \ SymI_HasProto(insertStableSymbol) \ @@ -674,7 +667,6 @@ typedef struct _RtsSymbolVal { SymI_HasProto(raiseIOzh_fast) \ SymI_HasProto(readTVarzh_fast) \ SymI_HasProto(readTVarIOzh_fast) \ - SymI_HasProto(resetNonBlockingFd) \ SymI_HasProto(resumeThread) \ SymI_HasProto(resolveObjs) \ SymI_HasProto(retryzh_fast) \ @@ -735,7 +727,6 @@ typedef struct _RtsSymbolVal { SymI_HasProto(stackOverflow) \ SymI_HasProto(stg_CAF_BLACKHOLE_info) \ SymI_HasProto(__stg_EAGER_BLACKHOLE_info) \ - SymI_HasProto(awakenBlockedQueue) \ SymI_HasProto(startTimer) \ SymI_HasProto(stg_CHARLIKE_closure) \ SymI_HasProto(stg_MVAR_CLEAN_info) \ diff --git a/rts/Main.c b/rts/Main.c index 58d3f37919..c1b028ff1b 100644 --- a/rts/Main.c +++ b/rts/Main.c @@ -11,6 +11,7 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" #include "RtsMain.h" diff --git a/rts/Papi.c b/rts/Papi.c index d95e26c8e7..e62fc9595c 100644 --- a/rts/Papi.c +++ b/rts/Papi.c @@ -16,12 +16,12 @@ #include <papi.h> -#include "Papi.h" +#include "PosixSource.h" #include "Rts.h" + #include "RtsUtils.h" #include "Stats.h" -#include "RtsFlags.h" -#include "OSThreads.h" +#include "Papi.h" // used to protect the aggregated counters #ifdef THREADED_RTS diff --git a/rts/Papi.h b/rts/Papi.h index fc92a913d5..8f58f6dfc9 100644 --- a/rts/Papi.h +++ b/rts/Papi.h @@ -5,6 +5,9 @@ * * ---------------------------------------------------------------------------*/ +#ifndef PAPI_H +#define PAPI_H + /* Check the error value of a PAPI call, reporting an error, if needed */ extern int papi_error; @@ -25,3 +28,5 @@ void papi_stop_gc1_count(void); // events and aggregate them into the main GC counters. void papi_thread_start_gc1_count(int event_set); void papi_thread_stop_gc1_count(int event_set); + +#endif /* PAPI_H */ diff --git a/rts/PosixSource.h b/rts/PosixSource.h index a938f9bc0f..cd1aeea34c 100644 --- a/rts/PosixSource.h +++ b/rts/PosixSource.h @@ -11,8 +11,9 @@ #define _POSIX_SOURCE 1 #define _POSIX_C_SOURCE 199506L -#define _ISOC9X_SOURCE +#define _XOPEN_SOURCE 500 +#define _ISOC99_SOURCE -/* Let's be ISO C9X too... */ +/* Let's be ISO C99 too... */ #endif /* POSIXSOURCE_H */ diff --git a/rts/Printer.c b/rts/Printer.c index a0040a5d46..ee91777854 100644 --- a/rts/Printer.c +++ b/rts/Printer.c @@ -8,18 +8,16 @@ #include "PosixSource.h" #include "Rts.h" +#include "rts/Bytecodes.h" /* for InstrPtr */ + #include "Printer.h" #include "RtsUtils.h" #ifdef DEBUG -#include "RtsFlags.h" -#include "MBlock.h" -#include "Bytecodes.h" /* for InstrPtr */ #include "Disassembler.h" #include "Apply.h" -#include <stdlib.h> #include <string.h> /* -------------------------------------------------------------------------- @@ -37,7 +35,6 @@ static rtsBool lookup_name ( char *name, StgWord *result ); static void enZcode ( char *in, char *out ); #endif static char unZcode ( char ch ); -const char * lookupGHCName ( void *addr ); static void printZcoded ( const char *raw ); /* -------------------------------------------------------------------------- @@ -186,7 +183,7 @@ printClosure( StgClosure *obj ) case AP: { - StgAP* ap = stgCast(StgAP*,obj); + StgAP* ap = (StgAP*)obj; StgWord i; debugBelch("AP("); printPtr((StgPtr)ap->fun); for (i = 0; i < ap->n_args; ++i) { @@ -199,7 +196,7 @@ printClosure( StgClosure *obj ) case PAP: { - StgPAP* pap = stgCast(StgPAP*,obj); + StgPAP* pap = (StgPAP*)obj; StgWord i; debugBelch("PAP/%d(",pap->arity); printPtr((StgPtr)pap->fun); @@ -213,7 +210,7 @@ printClosure( StgClosure *obj ) case AP_STACK: { - StgAP_STACK* ap = stgCast(StgAP_STACK*,obj); + StgAP_STACK* ap = (StgAP_STACK*)obj; StgWord i; debugBelch("AP_STACK("); printPtr((StgPtr)ap->fun); for (i = 0; i < ap->size; ++i) { @@ -226,31 +223,31 @@ printClosure( StgClosure *obj ) case IND: debugBelch("IND("); - printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + printPtr((StgPtr)((StgInd*)obj)->indirectee); debugBelch(")\n"); break; case IND_OLDGEN: debugBelch("IND_OLDGEN("); - printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + printPtr((StgPtr)((StgInd*)obj)->indirectee); debugBelch(")\n"); break; case IND_PERM: debugBelch("IND("); - printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + printPtr((StgPtr)((StgInd*)obj)->indirectee); debugBelch(")\n"); break; case IND_OLDGEN_PERM: debugBelch("IND_OLDGEN_PERM("); - printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + printPtr((StgPtr)((StgInd*)obj)->indirectee); debugBelch(")\n"); break; case IND_STATIC: debugBelch("IND_STATIC("); - printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee); + printPtr((StgPtr)((StgInd*)obj)->indirectee); debugBelch(")\n"); break; @@ -264,7 +261,7 @@ printClosure( StgClosure *obj ) case UPDATE_FRAME: { - StgUpdateFrame* u = stgCast(StgUpdateFrame*,obj); + StgUpdateFrame* u = (StgUpdateFrame*)obj; debugBelch("UPDATE_FRAME("); printPtr((StgPtr)GET_INFO(u)); debugBelch(","); @@ -275,7 +272,7 @@ printClosure( StgClosure *obj ) case CATCH_FRAME: { - StgCatchFrame* u = stgCast(StgCatchFrame*,obj); + StgCatchFrame* u = (StgCatchFrame*)obj; debugBelch("CATCH_FRAME("); printPtr((StgPtr)GET_INFO(u)); debugBelch(","); @@ -286,7 +283,7 @@ printClosure( StgClosure *obj ) case STOP_FRAME: { - StgStopFrame* u = stgCast(StgStopFrame*,obj); + StgStopFrame* u = (StgStopFrame*)obj; debugBelch("STOP_FRAME("); printPtr((StgPtr)GET_INFO(u)); debugBelch(")\n"); diff --git a/rts/Printer.h b/rts/Printer.h index 689c2f8d4a..52c1c3eb21 100644 --- a/rts/Printer.h +++ b/rts/Printer.h @@ -15,8 +15,8 @@ extern void printObj ( StgClosure *obj ); #ifdef DEBUG extern void prettyPrintClosure (StgClosure *obj); extern void printClosure ( StgClosure *obj ); -extern StgStackPtr printStackObj ( StgStackPtr sp ); -extern void printStackChunk ( StgStackPtr sp, StgStackPtr spLim ); +extern StgPtr printStackObj ( StgPtr sp ); +extern void printStackChunk ( StgPtr sp, StgPtr spLim ); extern void printTSO ( StgTSO *tso ); void info_hdr_type ( StgClosure *closure, char *res ); diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c index 36d4eb5f6f..8d9843893b 100644 --- a/rts/ProfHeap.c +++ b/rts/ProfHeap.c @@ -8,20 +8,17 @@ #include "PosixSource.h" #include "Rts.h" + #include "RtsUtils.h" -#include "RtsFlags.h" #include "Profiling.h" #include "ProfHeap.h" #include "Stats.h" #include "Hash.h" #include "RetainerProfile.h" -#include "LdvProfile.h" #include "Arena.h" #include "Printer.h" #include <string.h> -#include <stdlib.h> -#include <math.h> /* ----------------------------------------------------------------------------- * era stores the current time period. It is the same as the @@ -95,6 +92,8 @@ static void aggregateCensusInfo( void ); static void dumpCensus( Census *census ); +static rtsBool closureSatisfiesConstraints( StgClosure* p ); + /* ---------------------------------------------------------------------------- Closure Type Profiling; ------------------------------------------------------------------------- */ @@ -615,7 +614,6 @@ fprint_ccs(FILE *fp, CostCentreStack *ccs, nat max_length) } fprintf(fp, "%s", buf); } -#endif /* PROFILING */ rtsBool strMatchesSelector( char* str, char* sel ) @@ -641,11 +639,13 @@ strMatchesSelector( char* str, char* sel ) } } +#endif /* PROFILING */ + /* ----------------------------------------------------------------------------- * Figure out whether a closure should be counted in this census, by * testing against all the specified constraints. * -------------------------------------------------------------------------- */ -rtsBool +static rtsBool closureSatisfiesConstraints( StgClosure* p ) { #if !defined(PROFILING) @@ -1012,7 +1012,7 @@ heapCensusChain( Census *census, bdescr *bd ) case ARR_WORDS: prim = rtsTrue; - size = arr_words_sizeW(stgCast(StgArrWords*,p)); + size = arr_words_sizeW((StgArrWords*)p); break; case MUT_ARR_PTRS_CLEAN: diff --git a/rts/ProfHeap.h b/rts/ProfHeap.h index 0251416762..a3da424d24 100644 --- a/rts/ProfHeap.h +++ b/rts/ProfHeap.h @@ -12,7 +12,6 @@ extern void heapCensus( void ); extern nat initHeapProfiling( void ); extern void endHeapProfiling( void ); -extern rtsBool closureSatisfiesConstraints( StgClosure* p ); extern void LDV_recordDead( StgClosure *c, nat size ); extern rtsBool strMatchesSelector( char* str, char* sel ); diff --git a/rts/Profiling.c b/rts/Profiling.c index d729c8a09e..0769b529c0 100644 --- a/rts/Profiling.c +++ b/rts/Profiling.c @@ -10,15 +10,13 @@ #include "PosixSource.h" #include "Rts.h" + #include "RtsUtils.h" -#include "RtsFlags.h" #include "Profiling.h" #include "Proftimer.h" -#include "Timer.h" #include "ProfHeap.h" #include "Arena.h" #include "RetainerProfile.h" -#include "LdvProfile.h" #include <string.h> diff --git a/rts/Proftimer.c b/rts/Proftimer.c index 32e5c56073..dfcc709625 100644 --- a/rts/Proftimer.c +++ b/rts/Proftimer.c @@ -7,14 +7,15 @@ * ---------------------------------------------------------------------------*/ #include "PosixSource.h" - #include "Rts.h" + #include "Profiling.h" -#include "Timer.h" #include "Proftimer.h" -#include "RtsFlags.h" +#ifdef PROFILING static rtsBool do_prof_ticks = rtsFalse; // enable profiling ticks +#endif + static rtsBool do_heap_prof_ticks = rtsFalse; // enable heap profiling ticks // Number of ticks until next heap census @@ -23,6 +24,8 @@ static int ticks_to_heap_profile; // Time for a heap profile on the next context switch rtsBool performHeapProfile; +#ifdef PROFILING + void stopProfTimer( void ) { @@ -35,6 +38,8 @@ startProfTimer( void ) do_prof_ticks = rtsTrue; } +#endif + void stopHeapProfTimer( void ) { diff --git a/rts/Proftimer.h b/rts/Proftimer.h index c837b855f9..1379792d66 100644 --- a/rts/Proftimer.h +++ b/rts/Proftimer.h @@ -12,8 +12,11 @@ extern void initProfTimer ( void ); extern void handleProfTick ( void ); +#ifdef PROFILING extern void stopProfTimer ( void ); extern void startProfTimer ( void ); +#endif + extern void stopHeapProfTimer ( void ); extern void startHeapProfTimer ( void ); diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c index 2ff916a70a..39c973bd1d 100644 --- a/rts/RaiseAsync.c +++ b/rts/RaiseAsync.c @@ -8,17 +8,17 @@ #include "PosixSource.h" #include "Rts.h" + +#include "sm/Storage.h" #include "Threads.h" #include "Trace.h" #include "RaiseAsync.h" -#include "SMP.h" #include "Schedule.h" -#include "LdvProfile.h" #include "Updates.h" #include "STM.h" #include "Sanity.h" #include "Profiling.h" -#include "EventLog.h" +#include "eventlog/EventLog.h" #if defined(mingw32_HOST_OS) #include "win32/IOManager.h" #endif diff --git a/rts/RetainerProfile.c b/rts/RetainerProfile.c index 2bd213ad3d..fa12637ef6 100644 --- a/rts/RetainerProfile.c +++ b/rts/RetainerProfile.c @@ -16,13 +16,14 @@ #define INLINE inline #endif +#include "PosixSource.h" #include "Rts.h" + #include "RtsUtils.h" #include "RetainerProfile.h" #include "RetainerSet.h" #include "Schedule.h" #include "Printer.h" -#include "RtsFlags.h" #include "Weak.h" #include "Sanity.h" #include "Profiling.h" diff --git a/rts/RetainerProfile.h b/rts/RetainerProfile.h index f33c079f04..5f4503c84b 100644 --- a/rts/RetainerProfile.h +++ b/rts/RetainerProfile.h @@ -20,7 +20,7 @@ extern void printRetainer ( FILE *, retainer ); extern void retainerProfile ( void ); extern void resetStaticObjectForRetainerProfiling( StgClosure *static_objects ); -extern StgWord RTS_VAR(flip); +extern StgWord flip; // extract the retainer set field from c #define RSET(c) ((c)->header.prof.hp.rs) diff --git a/rts/RetainerSet.c b/rts/RetainerSet.c index 201412b958..5e9b37c04c 100644 --- a/rts/RetainerSet.c +++ b/rts/RetainerSet.c @@ -9,15 +9,15 @@ #ifdef PROFILING +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + #include "Stats.h" #include "RtsUtils.h" #include "RetainerSet.h" #include "Arena.h" #include "Profiling.h" -#include <stdlib.h> #include <string.h> #define HASH_TABLE_SIZE 255 diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c index df4315fdb8..3eecab14d4 100644 --- a/rts/RtsAPI.c +++ b/rts/RtsAPI.c @@ -8,18 +8,15 @@ #include "PosixSource.h" #include "Rts.h" -#include "OSThreads.h" #include "RtsAPI.h" -#include "SchedAPI.h" -#include "RtsFlags.h" +#include "HsFFI.h" + #include "RtsUtils.h" #include "Prelude.h" #include "Schedule.h" #include "Capability.h" #include "Stable.h" -#include <stdlib.h> - /* ---------------------------------------------------------------------------- Building Haskell objects from C datatypes. diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 856137119c..1204c59356 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -9,7 +9,7 @@ #include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + #include "RtsUtils.h" #include "Profiling.h" @@ -17,7 +17,6 @@ #include <ctype.h> #endif -#include <stdlib.h> #include <string.h> // Flag Structure @@ -1272,7 +1271,7 @@ decode(const char *s) return (I_)m; } -static void +static void GNU_ATTRIBUTE(__noreturn__) bad_option(const char *s) { errorBelch("bad RTS option: %s", s); diff --git a/rts/RtsMain.c b/rts/RtsMain.c index 438110a179..b6cf546aea 100644 --- a/rts/RtsMain.c +++ b/rts/RtsMain.c @@ -11,8 +11,7 @@ #include "PosixSource.h" #include "Rts.h" #include "RtsAPI.h" -#include "SchedAPI.h" -#include "RtsFlags.h" + #include "RtsUtils.h" #include "RtsMain.h" #include "Prelude.h" @@ -20,7 +19,6 @@ #if defined(mingw32_HOST_OS) #include "win32/seh_excn.h" #endif -#include <stdlib.h> #ifdef DEBUG # include "Printer.h" /* for printing */ diff --git a/rts/RtsMessages.c b/rts/RtsMessages.c index c263a2cf57..ef5c5a226c 100644 --- a/rts/RtsMessages.c +++ b/rts/RtsMessages.c @@ -128,7 +128,7 @@ isGUIApp(void) #define xstr(s) str(s) #define str(s) #s -void +void GNU_ATTRIBUTE(__noreturn__) rtsFatalInternalErrorFn(const char *s, va_list ap) { #if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS) diff --git a/rts/RtsSignals.h b/rts/RtsSignals.h index e130fb4281..601a46b79c 100644 --- a/rts/RtsSignals.h +++ b/rts/RtsSignals.h @@ -6,8 +6,8 @@ * * ---------------------------------------------------------------------------*/ -#ifndef RTS_SIGNALS_H -#define RTS_SIGNALS_H +#ifndef RTSSIGNALS_H +#define RTSSIGNALS_H #if !defined(mingw32_HOST_OS) @@ -17,12 +17,11 @@ #include "win32/ConsoleHandler.h" -#else /* PAR */ +#else #define signals_pending() (rtsFalse) -#endif /* PAR */ - +#endif #if RTS_USER_SIGNALS @@ -78,4 +77,4 @@ extern void markSignalHandlers (evac_fn evac, void *user); #endif /* RTS_USER_SIGNALS */ -#endif /* RTS_SIGNALS_H */ +#endif /* RTSSIGNALS_H */ diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index c21aac767c..2c1c5549f1 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -7,42 +7,38 @@ * ---------------------------------------------------------------------------*/ // PAPI uses caddr_t, which is not POSIX -// #include "PosixSource.h" +#ifndef USE_PAPI +#include "PosixSource.h" +#endif #include "Rts.h" #include "RtsAPI.h" +#include "HsFFI.h" + +#include "sm/Storage.h" #include "RtsUtils.h" -#include "RtsFlags.h" -#include "OSThreads.h" #include "Schedule.h" /* initScheduler */ #include "Stats.h" /* initStats */ #include "STM.h" /* initSTM */ -#include "Signals.h" #include "RtsSignals.h" -#include "ThrIOManager.h" -#include "Timer.h" /* startTimer, stopTimer */ #include "Weak.h" #include "Ticky.h" #include "StgRun.h" #include "Prelude.h" /* fixupRTStoPreludeRefs */ -#include "HsFFI.h" -#include "Linker.h" #include "ThreadLabels.h" -#include "BlockAlloc.h" +#include "sm/BlockAlloc.h" #include "Trace.h" -#include "RtsGlobals.h" #include "Stable.h" -#include "Hpc.h" -#include "FileLock.h" -#include "EventLog.h" +#include "eventlog/EventLog.h" #include "Hash.h" +#include "Profiling.h" +#include "Timer.h" +#include "Globals.h" #if defined(RTS_GTK_FRONTPANEL) #include "FrontPanel.h" #endif -# include "Profiling.h" - #if defined(PROFILING) # include "ProfHeap.h" # include "RetainerProfile.h" @@ -52,14 +48,11 @@ #include "win32/AsyncIO.h" #endif -#include <stdlib.h> - -#ifdef HAVE_TERMIOS_H -#include <termios.h> -#endif -#ifdef HAVE_SIGNAL_H -#include <signal.h> +#if !defined(mingw32_HOST_OS) +#include "posix/TTY.h" +#include "posix/FileLock.h" #endif + #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -74,26 +67,6 @@ // Count of how many outstanding hs_init()s there have been. static int hs_init_count = 0; -// Here we save the terminal settings on the standard file -// descriptors, if we need to change them (eg. to support NoBuffering -// input). -static void *saved_termios[3] = {NULL,NULL,NULL}; - -void* -__hscore_get_saved_termios(int fd) -{ - return (0 <= fd && fd < (int)(sizeof(saved_termios) / sizeof(*saved_termios))) ? - saved_termios[fd] : NULL; -} - -void -__hscore_set_saved_termios(int fd, void* ts) -{ - if (0 <= fd && fd < (int)(sizeof(saved_termios) / sizeof(*saved_termios))) { - saved_termios[fd] = ts; - } -} - /* ----------------------------------------------------------------------------- Initialise floating point unit on x86 (currently disabled. why?) (see comment in ghc/compiler/nativeGen/MachInstrs.lhs). @@ -292,7 +265,7 @@ startupHaskell(int argc, char *argv[], void (*init_root)(void)) /* The init functions use an explicit stack... */ #define INIT_STACK_BLOCKS 4 -static F_ *init_stack = NULL; +static StgFunPtr *init_stack = NULL; void hs_add_root(void (*init_root)(void)) @@ -311,10 +284,10 @@ hs_add_root(void (*init_root)(void)) to the last occupied word */ init_sp = INIT_STACK_BLOCKS*BLOCK_SIZE_W; bd = allocGroup_lock(INIT_STACK_BLOCKS); - init_stack = (F_ *)bd->start; - init_stack[--init_sp] = (F_)stg_init_finish; + init_stack = (StgFunPtr *)bd->start; + init_stack[--init_sp] = (StgFunPtr)stg_init_finish; if (init_root != NULL) { - init_stack[--init_sp] = (F_)init_root; + init_stack[--init_sp] = (StgFunPtr)init_root; } cap->r.rSp = (P_)(init_stack + init_sp); @@ -391,30 +364,9 @@ hs_exit_(rtsBool wait_foreign) stopTimer(); exitTimer(); - /* reset the standard file descriptors to blocking mode */ - resetNonBlockingFd(0); - resetNonBlockingFd(1); - resetNonBlockingFd(2); - -#if HAVE_TERMIOS_H - // Reset the terminal settings on the standard file descriptors, - // if we changed them. See System.Posix.Internals.tcSetAttr for - // more details, including the reason we termporarily disable - // SIGTTOU here. - { - int fd; - sigset_t sigset, old_sigset; - sigemptyset(&sigset); - sigaddset(&sigset, SIGTTOU); - sigprocmask(SIG_BLOCK, &sigset, &old_sigset); - for (fd = 0; fd <= 2; fd++) { - struct termios* ts = (struct termios*)__hscore_get_saved_termios(fd); - if (ts != NULL) { - tcsetattr(fd,TCSANOW,ts); - } - } - sigprocmask(SIG_SETMASK, &old_sigset, NULL); - } + // set the terminal settings back to what they were +#if !defined(mingw32_HOST_OS) + resetTerminalSettings(); #endif // uninstall signal handlers diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c index ed082a31f4..1953e1e838 100644 --- a/rts/RtsUtils.c +++ b/rts/RtsUtils.c @@ -7,10 +7,9 @@ * ---------------------------------------------------------------------------*/ #include "PosixSource.h" - #include "Rts.h" #include "RtsAPI.h" -#include "RtsFlags.h" + #include "RtsUtils.h" #include "Ticky.h" #include "Schedule.h" @@ -284,22 +283,6 @@ heapOverflow(void) } /* ----------------------------------------------------------------------------- - Out-of-line strlen. - - Used in addr2Integer because the C compiler on x86 chokes on - strlen, trying to inline it with not enough registers available. - -------------------------------------------------------------------------- */ - -nat stg_strlen(char *s) -{ - char *p = s; - - while (*p) p++; - return p-s; -} - - -/* ----------------------------------------------------------------------------- genSym stuff, used by GHC itself for its splitting unique supply. ToDo: put this somewhere sensible. @@ -343,44 +326,6 @@ time_str(void) } /* ----------------------------------------------------------------------------- - * Reset a file handle to blocking mode. We do this for the standard - * file descriptors before exiting, because the shell doesn't always - * clean up for us. - * -------------------------------------------------------------------------- */ - -#if !defined(mingw32_HOST_OS) -void -resetNonBlockingFd(int fd) -{ - long fd_flags; - - /* clear the non-blocking flag on this file descriptor */ - fd_flags = fcntl(fd, F_GETFL); - if (fd_flags & O_NONBLOCK) { - fcntl(fd, F_SETFL, fd_flags & ~O_NONBLOCK); - } -} - -void -setNonBlockingFd(int fd) -{ - long fd_flags; - - /* clear the non-blocking flag on this file descriptor */ - fd_flags = fcntl(fd, F_GETFL); - if (!(fd_flags & O_NONBLOCK)) { - fcntl(fd, F_SETFL, fd_flags | O_NONBLOCK); - } -} -#else -/* Stub defns -- async / non-blocking IO is not done - * via O_NONBLOCK and select() under Win32. - */ -void resetNonBlockingFd(int fd STG_UNUSED) {} -void setNonBlockingFd(int fd STG_UNUSED) {} -#endif - -/* ----------------------------------------------------------------------------- Print large numbers, with punctuation. -------------------------------------------------------------------------- */ diff --git a/rts/RtsUtils.h b/rts/RtsUtils.h index 11a2826596..14856bf943 100644 --- a/rts/RtsUtils.h +++ b/rts/RtsUtils.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------------- * - * (c) The GHC Team, 1998-2005 + * (c) The GHC Team, 1998-2009 * * General utility functions used in the RTS. * @@ -13,42 +13,44 @@ * (Checked) dynamic allocation * -------------------------------------------------------------------------- */ -extern void initAllocator(void); -extern void shutdownAllocator(void); +void initAllocator(void); +void shutdownAllocator(void); -extern void *stgMallocBytes(int n, char *msg) +void *stgMallocBytes(int n, char *msg) GNUC3_ATTRIBUTE(__malloc__); -extern void *stgReallocBytes(void *p, int n, char *msg); +void *stgReallocBytes(void *p, int n, char *msg); -extern void *stgCallocBytes(int n, int m, char *msg) +void *stgCallocBytes(int n, int m, char *msg) GNUC3_ATTRIBUTE(__malloc__); -extern void stgFree(void* p); +void stgFree(void* p); /* ----------------------------------------------------------------------------- * Misc other utilities * -------------------------------------------------------------------------- */ -extern void heapOverflow(void); +void heapOverflow(void); -extern void setNonBlockingFd(int fd); -extern void resetNonBlockingFd(int fd); - -extern nat stg_strlen(char *str); - -extern char *time_str(void); -extern char *ullong_format_string(ullong, char *, rtsBool); +char *time_str(void); +char *ullong_format_string(ullong, char *, rtsBool); #ifdef DEBUG -extern void heapCheckFail( void ); +void heapCheckFail( void ); #endif -extern void* __hscore_get_saved_termios(int fd); -extern void __hscore_set_saved_termios(int fd, void* ts); +// XXX shouldn't be here +void* __hscore_get_saved_termios(int fd); +void __hscore_set_saved_termios(int fd, void* ts); void printRtsInfo(void); +HsInt genSymZh(void); +HsInt resetGenSymZh(void); + +/* Alternate to raise(3) for threaded rts, for OpenBSD */ +int genericRaise(int sig); + int rts_isProfiled(void); #endif /* RTSUTILS_H */ @@ -74,25 +74,24 @@ * (d) release the locks on the TVars, writing updates to them in the case of a * commit, (e) unlock the STM. * - * Queues of waiting threads hang off the first_watch_queue_entry field of each - * TVar. This may only be manipulated when holding that TVar's lock. In - * particular, when a thread is putting itself to sleep, it mustn't release - * the TVar's lock until it has added itself to the wait queue and marked its - * TSO as BlockedOnSTM -- this makes sure that other threads will know to wake it. + * Queues of waiting threads hang off the first_watch_queue_entry + * field of each TVar. This may only be manipulated when holding that + * TVar's lock. In particular, when a thread is putting itself to + * sleep, it mustn't release the TVar's lock until it has added itself + * to the wait queue and marked its TSO as BlockedOnSTM -- this makes + * sure that other threads will know to wake it. * * ---------------------------------------------------------------------------*/ #include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + #include "RtsUtils.h" -#include "Storage.h" #include "Schedule.h" -#include "SMP.h" #include "STM.h" #include "Trace.h" +#include "Threads.h" -#include <stdlib.h> #include <stdio.h> #define TRUE 1 diff --git a/rts/STM.h b/rts/STM.h new file mode 100644 index 0000000000..3bf976551d --- /dev/null +++ b/rts/STM.h @@ -0,0 +1,245 @@ +/*---------------------------------------------------------------------- + * + * (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/rts/Sanity.c b/rts/Sanity.c index 02d81ed7ce..d666d57f3b 100644 --- a/rts/Sanity.c +++ b/rts/Sanity.c @@ -18,14 +18,13 @@ #ifdef DEBUG /* whole file */ -#include "RtsFlags.h" #include "RtsUtils.h" -#include "BlockAlloc.h" +#include "sm/Storage.h" +#include "sm/BlockAlloc.h" #include "Sanity.h" -#include "MBlock.h" -#include "Storage.h" #include "Schedule.h" #include "Apply.h" +#include "Printer.h" /* ----------------------------------------------------------------------------- Forward decls. diff --git a/rts/Sanity.h b/rts/Sanity.h index 48f3383714..3020246a70 100644 --- a/rts/Sanity.h +++ b/rts/Sanity.h @@ -7,6 +7,7 @@ * ---------------------------------------------------------------------------*/ #ifndef SANITY_H +#define SANITY_H #ifdef DEBUG @@ -39,4 +40,3 @@ extern rtsBool isBlackhole( StgTSO* tso, StgClosure* p ); #endif /* DEBUG */ #endif /* SANITY_H */ - diff --git a/rts/Schedule.c b/rts/Schedule.c index c840c78644..b3d523e111 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -9,34 +9,25 @@ #include "PosixSource.h" #define KEEP_LOCKCLOSURE #include "Rts.h" -#include "SchedAPI.h" + +#include "sm/Storage.h" #include "RtsUtils.h" -#include "RtsFlags.h" -#include "OSThreads.h" -#include "Storage.h" #include "StgRun.h" -#include "Hooks.h" #include "Schedule.h" -#include "StgMiscClosures.h" #include "Interpreter.h" #include "Printer.h" #include "RtsSignals.h" #include "Sanity.h" #include "Stats.h" #include "STM.h" -#include "Timer.h" #include "Prelude.h" #include "ThreadLabels.h" -#include "LdvProfile.h" #include "Updates.h" #include "Proftimer.h" #include "ProfHeap.h" -#include "GC.h" #include "Weak.h" -#include "EventLog.h" - -/* PARALLEL_HASKELL includes go here */ - +#include "eventlog/EventLog.h" +#include "sm/GC.h" // waitForGcThreads, releaseGCThreads, N #include "Sparks.h" #include "Capability.h" #include "Task.h" @@ -47,7 +38,8 @@ #include "Trace.h" #include "RaiseAsync.h" #include "Threads.h" -#include "ThrIOManager.h" +#include "Timer.h" +#include "ThreadPaused.h" #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> @@ -64,12 +56,6 @@ #include <errno.h> #endif -// Turn off inlining when debugging - it obfuscates things -#ifdef DEBUG -# undef STATIC_INLINE -# define STATIC_INLINE static -#endif - /* ----------------------------------------------------------------------------- * Global variables * -------------------------------------------------------------------------- */ @@ -2383,7 +2369,9 @@ interruptStgRts(void) { sched_state = SCHED_INTERRUPTING; setContextSwitches(); +#if defined(THREADED_RTS) wakeUpRts(); +#endif } /* ----------------------------------------------------------------------------- @@ -2399,16 +2387,15 @@ interruptStgRts(void) will have interrupted any blocking system call in progress anyway. -------------------------------------------------------------------------- */ -void -wakeUpRts(void) -{ #if defined(THREADED_RTS) +void wakeUpRts(void) +{ // This forces the IO Manager thread to wakeup, which will // in turn ensure that some OS thread wakes up and runs the // scheduler loop, which will cause a GC and deadlock check. ioManagerWakeup(); -#endif } +#endif /* ----------------------------------------------------------------------------- * checkBlackHoles() diff --git a/rts/Schedule.h b/rts/Schedule.h index 0e18168755..378bd68c66 100644 --- a/rts/Schedule.h +++ b/rts/Schedule.h @@ -10,9 +10,9 @@ #ifndef SCHEDULE_H #define SCHEDULE_H -#include "OSThreads.h" +#include "rts/OSThreads.h" #include "Capability.h" -#include "EventLog.h" +#include "eventlog/EventLog.h" /* initScheduler(), exitScheduler() * Called from STG : no @@ -30,28 +30,13 @@ void scheduleThread (Capability *cap, StgTSO *tso); // the desired Capability). void scheduleThreadOn(Capability *cap, StgWord cpu, StgTSO *tso); -/* awakenBlockedQueue() - * - * Takes a pointer to the beginning of a blocked TSO queue, and - * wakes up the entire queue. - * Called from STG : yes - * Locks assumed : none - */ -void awakenBlockedQueue (Capability *cap, StgTSO *tso); - /* wakeUpRts() * * Causes an OS thread to wake up and run the scheduler, if necessary. */ +#if defined(THREADED_RTS) void wakeUpRts(void); - -/* unblockOne() - * - * Put the specified thread on the run queue of the given Capability. - * Called from STG : yes - * Locks assumed : we own the Capability. - */ -StgTSO * unblockOne (Capability *cap, StgTSO *tso); +#endif /* raiseExceptionHelper */ StgWord raiseExceptionHelper (StgRegTable *reg, StgTSO *tso, StgClosure *exception); @@ -69,11 +54,6 @@ StgWord findRetryFrameHelper (StgTSO *tso); void OSThreadProcAttr workerStart(Task *task); #endif -char *info_type(StgClosure *closure); // dummy -char *info_type_by_ip(StgInfoTable *ip); // dummy -void awaken_blocked_queue(StgTSO *q); -void initThread(StgTSO *tso, nat stack_size); - /* The state of the scheduler. This is used to control the sequence * of events during shutdown, and when the runtime is interrupted * using ^C. @@ -82,7 +62,7 @@ void initThread(StgTSO *tso, nat stack_size); #define SCHED_INTERRUPTING 1 /* ^C detected, before threads are deleted */ #define SCHED_SHUTTING_DOWN 2 /* final shutdown */ -extern volatile StgWord RTS_VAR(sched_state); +extern volatile StgWord sched_state; /* * flag that tracks whether we have done any execution in this time slice. @@ -105,10 +85,10 @@ extern volatile StgWord recent_activity; * * In GranSim we have one run/blocked_queue per PE. */ -extern StgTSO *RTS_VAR(blackhole_queue); +extern StgTSO *blackhole_queue; #if !defined(THREADED_RTS) -extern StgTSO *RTS_VAR(blocked_queue_hd), *RTS_VAR(blocked_queue_tl); -extern StgTSO *RTS_VAR(sleeping_queue); +extern StgTSO *blocked_queue_hd, *blocked_queue_tl; +extern StgTSO *sleeping_queue; #endif /* Set to rtsTrue if there are threads on the blackhole_queue, and @@ -123,27 +103,15 @@ extern rtsBool blackholes_need_checking; extern rtsBool heap_overflow; #if defined(THREADED_RTS) -extern Mutex RTS_VAR(sched_mutex); +extern Mutex sched_mutex; #endif -SchedulerStatus rts_mainLazyIO(HaskellObj p, /*out*/HaskellObj *ret); - /* Called by shutdown_handler(). */ void interruptStgRts (void); -nat run_queue_len (void); - void resurrectThreads (StgTSO *); void performPendingThrowTos (StgTSO *); -void printAllThreads(void); - -/* debugging only - */ -#ifdef DEBUG -void print_bq (StgClosure *node); -#endif - /* ----------------------------------------------------------------------------- * Some convenient macros/inline functions... */ diff --git a/rts/Sparks.c b/rts/Sparks.c index 0fe8b61b81..ff4beb7fd5 100644 --- a/rts/Sparks.c +++ b/rts/Sparks.c @@ -8,17 +8,11 @@ #include "PosixSource.h" #include "Rts.h" -#include "Storage.h" + #include "Schedule.h" -#include "SchedAPI.h" -#include "RtsFlags.h" #include "RtsUtils.h" -#include "ParTicky.h" #include "Trace.h" #include "Prelude.h" - -#include "SMP.h" // for cas - #include "Sparks.h" #if defined(THREADED_RTS) @@ -128,8 +122,6 @@ pruneSparkQueue (evac_fn evac, void *user, Capability *cap) StgWord botInd,oldBotInd,currInd; // indices in array (always < size) const StgInfoTable *info; - PAR_TICKY_MARK_SPARK_QUEUE_START(); - n = 0; pruned_sparks = 0; @@ -246,8 +238,6 @@ pruneSparkQueue (evac_fn evac, void *user, Capability *cap) pool->bottom = (oldBotInd <= botInd) ? botInd : (botInd + pool->size); // first free place we did not use (corrected by wraparound) - PAR_TICKY_MARK_SPARK_QUEUE_END(n); - debugTrace(DEBUG_sched, "pruned %d sparks", pruned_sparks); debugTrace(DEBUG_sched, @@ -296,7 +286,8 @@ traverseSparkQueue (evac_fn evac, void *user, Capability *cap) * * Could be called after GC, before Cap. release, from scheduler. * -------------------------------------------------------------------------- */ -void balanceSparkPoolsCaps(nat n_caps, Capability caps[]); +void balanceSparkPoolsCaps(nat n_caps, Capability caps[]) + GNUC3_ATTRIBUTE(__noreturn__); void balanceSparkPoolsCaps(nat n_caps STG_UNUSED, Capability caps[] STG_UNUSED) { diff --git a/rts/Stable.c b/rts/Stable.c index 97796b89a7..b427c94965 100644 --- a/rts/Stable.c +++ b/rts/Stable.c @@ -8,13 +8,10 @@ #include "PosixSource.h" #include "Rts.h" +#include "RtsAPI.h" + #include "Hash.h" #include "RtsUtils.h" -#include "OSThreads.h" -#include "Storage.h" -#include "RtsAPI.h" -#include "RtsFlags.h" -#include "OSThreads.h" #include "Trace.h" #include "Stable.h" @@ -83,6 +80,8 @@ static unsigned int SPT_size = 0; static Mutex stable_mutex; #endif +static void enlargeStablePtrTable(void); + /* This hash table maps Haskell objects to stable names, so that every * call to lookupStableName on a given object will return the same * stable name. @@ -300,7 +299,7 @@ freeStablePtr(StgStablePtr sp) RELEASE_LOCK(&stable_mutex); } -void +static void enlargeStablePtrTable(void) { nat old_SPT_size = SPT_size; diff --git a/rts/Stable.h b/rts/Stable.h new file mode 100644 index 0000000000..258a6bea80 --- /dev/null +++ b/rts/Stable.h @@ -0,0 +1,34 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2004 + * + * Stable Pointers: A stable pointer is represented as an index into + * the stable pointer table. + * + * 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 + +#include "sm/GC.h" // for evac_fn below + +void freeStablePtr (StgStablePtr sp); + +void initStablePtrTable ( void ); +void exitStablePtrTable ( void ); +StgWord lookupStableName ( StgPtr p ); + +void markStablePtrTable ( evac_fn evac, void *user ); +void threadStablePtrTable ( evac_fn evac, void *user ); +void gcStablePtrTable ( void ); +void updateStablePtrTable ( rtsBool full ); + +void stablePtrPreGC ( void ); +void stablePtrPostGC ( void ); + +#endif /* STABLE_H */ diff --git a/rts/Stats.c b/rts/Stats.c index ae3d843157..6029745368 100644 --- a/rts/Stats.c +++ b/rts/Stats.c @@ -6,17 +6,16 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + #include "RtsUtils.h" -#include "MBlock.h" -#include "Storage.h" #include "Schedule.h" #include "Stats.h" -#include "ParTicky.h" /* ToDo: move into Rts.h */ #include "Profiling.h" #include "GetTime.h" -#include "GC.h" +#include "sm/Storage.h" +#include "sm/GC.h" // gc_alloc_block_sync, whitehole_spin #if USE_PAPI #include "Papi.h" @@ -506,21 +505,11 @@ stat_endHeapCensus(void) -------------------------------------------------------------------------- */ #ifdef DEBUG -#define TICK_VAR(arity) \ - extern StgInt SLOW_CALLS_##arity; \ - 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) -TICK_VAR(2) - TICK_VAR_INI(1) TICK_VAR_INI(2) diff --git a/rts/Stats.h b/rts/Stats.h index bd39ced57d..4b98739fe2 100644 --- a/rts/Stats.h +++ b/rts/Stats.h @@ -51,7 +51,6 @@ double mut_user_time_during_heap_census(void); #endif /* PROFILING */ void statDescribeGens( void ); -HsInt64 getAllocations( void ); Ticks stat_getElapsedGCTime(void); Ticks stat_getElapsedTime(void); diff --git a/rts/StgCRun.c b/rts/StgCRun.c index a211da3577..92ce6ebb19 100644 --- a/rts/StgCRun.c +++ b/rts/StgCRun.c @@ -34,7 +34,6 @@ #include "PosixSource.h" - /* * We define the following (unused) global register variables, because for * some reason gcc generates sub-optimal code for StgRun() on the Alpha @@ -70,9 +69,8 @@ register double fake_f9 __asm__("$f9"); #define IN_STGCRUN 1 #include "Stg.h" #include "Rts.h" + #include "StgRun.h" -#include "RtsFlags.h" -#include "OSThreads.h" #include "Capability.h" #ifdef DEBUG diff --git a/rts/StgPrimFloat.c b/rts/StgPrimFloat.c index 5987aa9589..e523f328c3 100644 --- a/rts/StgPrimFloat.c +++ b/rts/StgPrimFloat.c @@ -10,7 +10,12 @@ #include "PosixSource.h" #include "Rts.h" +#include "StgPrimFloat.h" + #include <math.h> +#include <float.h> + +#define IEEE_FLOATING_POINT 1 /* * Encoding and decoding Doubles. Code based on the HBC code @@ -218,252 +223,3 @@ __decodeFloat_Int (I_ *man, I_ *exp, StgFloat flt) } } -union stg_ieee754_flt -{ - float f; - struct { - -#if WORDS_BIGENDIAN - unsigned int negative:1; - unsigned int exponent:8; - unsigned int mantissa:23; -#else - unsigned int mantissa:23; - unsigned int exponent:8; - unsigned int negative:1; -#endif - } ieee; - struct { - -#if WORDS_BIGENDIAN - unsigned int negative:1; - unsigned int exponent:8; - unsigned int quiet_nan:1; - unsigned int mantissa:22; -#else - unsigned int mantissa:22; - unsigned int quiet_nan:1; - unsigned int exponent:8; - unsigned int negative:1; -#endif - } ieee_nan; -}; - -/* - - To recap, here's the representation of a double precision - IEEE floating point number: - - sign 63 sign bit (0==positive, 1==negative) - exponent 62-52 exponent (biased by 1023) - fraction 51-0 fraction (bits to right of binary point) -*/ - -union stg_ieee754_dbl -{ - double d; - struct { - -#if WORDS_BIGENDIAN - unsigned int negative:1; - unsigned int exponent:11; - unsigned int mantissa0:20; - unsigned int mantissa1:32; -#else -#if FLOAT_WORDS_BIGENDIAN - unsigned int mantissa0:20; - unsigned int exponent:11; - unsigned int negative:1; - unsigned int mantissa1:32; -#else - unsigned int mantissa1:32; - unsigned int mantissa0:20; - unsigned int exponent:11; - unsigned int negative:1; -#endif -#endif - } ieee; - /* This format makes it easier to see if a NaN is a signalling NaN. */ - struct { - -#if WORDS_BIGENDIAN - unsigned int negative:1; - unsigned int exponent:11; - unsigned int quiet_nan:1; - unsigned int mantissa0:19; - unsigned int mantissa1:32; -#else -#if FLOAT_WORDS_BIGENDIAN - unsigned int mantissa0:19; - unsigned int quiet_nan:1; - unsigned int exponent:11; - unsigned int negative:1; - unsigned int mantissa1:32; -#else - unsigned int mantissa1:32; - unsigned int mantissa0:19; - unsigned int quiet_nan:1; - unsigned int exponent:11; - unsigned int negative:1; -#endif -#endif - } ieee_nan; -}; - -/* - * Predicates for testing for extreme IEEE fp values. Used - * by the bytecode evaluator and the Prelude. - * - */ - -/* In case you don't suppport IEEE, you'll just get dummy defs.. */ -#ifdef IEEE_FLOATING_POINT - -StgInt -isDoubleNaN(StgDouble d) -{ - union stg_ieee754_dbl u; - - u.d = d; - - return ( - u.ieee.exponent == 2047 /* 2^11 - 1 */ && /* Is the exponent all ones? */ - (u.ieee.mantissa0 != 0 || u.ieee.mantissa1 != 0) - /* and the mantissa non-zero? */ - ); -} - -StgInt -isDoubleInfinite(StgDouble d) -{ - union stg_ieee754_dbl u; - - u.d = d; - - /* Inf iff exponent is all ones, mantissa all zeros */ - return ( - u.ieee.exponent == 2047 /* 2^11 - 1 */ && - u.ieee.mantissa0 == 0 && - u.ieee.mantissa1 == 0 - ); -} - -StgInt -isDoubleDenormalized(StgDouble d) -{ - union stg_ieee754_dbl u; - - u.d = d; - - /* A (single/double/quad) precision floating point number - is denormalised iff: - - exponent is zero - - mantissa is non-zero. - - (don't care about setting of sign bit.) - - */ - return ( - u.ieee.exponent == 0 && - (u.ieee.mantissa0 != 0 || - u.ieee.mantissa1 != 0) - ); - -} - -StgInt -isDoubleNegativeZero(StgDouble d) -{ - union stg_ieee754_dbl u; - - u.d = d; - /* sign (bit 63) set (only) => negative zero */ - - return ( - u.ieee.negative == 1 && - u.ieee.exponent == 0 && - u.ieee.mantissa0 == 0 && - u.ieee.mantissa1 == 0); -} - -/* Same tests, this time for StgFloats. */ - -/* - To recap, here's the representation of a single precision - IEEE floating point number: - - sign 31 sign bit (0 == positive, 1 == negative) - exponent 30-23 exponent (biased by 127) - fraction 22-0 fraction (bits to right of binary point) -*/ - - -StgInt -isFloatNaN(StgFloat f) -{ - union stg_ieee754_flt u; - u.f = f; - - /* Floating point NaN iff exponent is all ones, mantissa is - non-zero (but see below.) */ - return ( - u.ieee.exponent == 255 /* 2^8 - 1 */ && - u.ieee.mantissa != 0); -} - -StgInt -isFloatInfinite(StgFloat f) -{ - union stg_ieee754_flt u; - u.f = f; - - /* A float is Inf iff exponent is max (all ones), - and mantissa is min(all zeros.) */ - return ( - u.ieee.exponent == 255 /* 2^8 - 1 */ && - u.ieee.mantissa == 0); -} - -StgInt -isFloatDenormalized(StgFloat f) -{ - union stg_ieee754_flt u; - u.f = f; - - /* A (single/double/quad) precision floating point number - is denormalised iff: - - exponent is zero - - mantissa is non-zero. - - (don't care about setting of sign bit.) - - */ - return ( - u.ieee.exponent == 0 && - u.ieee.mantissa != 0); -} - -StgInt -isFloatNegativeZero(StgFloat f) -{ - union stg_ieee754_flt u; - u.f = f; - - /* sign (bit 31) set (only) => negative zero */ - return ( - u.ieee.negative && - u.ieee.exponent == 0 && - u.ieee.mantissa == 0); -} - -#else /* ! IEEE_FLOATING_POINT */ - -/* Dummy definitions of predicates - they all return false */ -StgInt isDoubleNaN(d) StgDouble d; { return 0; } -StgInt isDoubleInfinite(d) StgDouble d; { return 0; } -StgInt isDoubleDenormalized(d) StgDouble d; { return 0; } -StgInt isDoubleNegativeZero(d) StgDouble d; { return 0; } -StgInt isFloatNaN(f) StgFloat f; { return 0; } -StgInt isFloatInfinite(f) StgFloat f; { return 0; } -StgInt isFloatDenormalized(f) StgFloat f; { return 0; } -StgInt isFloatNegativeZero(f) StgFloat f; { return 0; } - -#endif /* ! IEEE_FLOATING_POINT */ diff --git a/rts/StgPrimFloat.h b/rts/StgPrimFloat.h new file mode 100644 index 0000000000..5de8360efd --- /dev/null +++ b/rts/StgPrimFloat.h @@ -0,0 +1,21 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2009 + * + * Primitive floating-point operations + * + * ---------------------------------------------------------------------------*/ + +#ifndef STGPRIMFLOAT_H +#define STGPRIMFLOAT_H + +/* grimy low-level support functions defined in StgPrimFloat.c */ +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); +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 __int_encodeFloat (I_ j, I_ e); +extern StgFloat __word_encodeFloat (W_ j, I_ e); + +#endif /* STGPRIMFLOAT_H */ diff --git a/rts/Task.c b/rts/Task.c index af94a8aabe..9a8ebd6963 100644 --- a/rts/Task.c +++ b/rts/Task.c @@ -8,14 +8,13 @@ * * -------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" + #include "RtsUtils.h" -#include "OSThreads.h" #include "Task.h" #include "Capability.h" #include "Stats.h" -#include "RtsFlags.h" -#include "Storage.h" #include "Schedule.h" #include "Hash.h" #include "Trace.h" @@ -258,15 +257,15 @@ taskTimeStamp (Task *task USED_IF_THREADS) #endif } +#if defined(THREADED_RTS) + void workerTaskStop (Task *task) { -#if defined(THREADED_RTS) OSThreadId id; id = osThreadId(); ASSERT(task->id == id); ASSERT(myTask() == task); -#endif task->cap = NULL; taskTimeStamp(task); @@ -280,12 +279,7 @@ workerTaskStop (Task *task) RELEASE_LOCK(&sched_mutex); } -void -resetTaskManagerAfterFork (void) -{ - // TODO! - taskCount = 0; -} +#endif #if defined(THREADED_RTS) diff --git a/rts/Task.h b/rts/Task.h index 590dd679b3..c11afb584c 100644 --- a/rts/Task.h +++ b/rts/Task.h @@ -20,26 +20,14 @@ Task, and OS threads that enter the Haskell RTS for the purposes of making a call-in are also Tasks. - The relationship between the number of tasks and capabilities, and - the runtime build (-threaded, -smp etc.) is summarised by the - following table: + In the THREADED_RTS build, multiple Tasks may all be running + Haskell code simultaneously. A task relinquishes its Capability + when it is asked to evaluate an external (C) call. - build Tasks Capabilities - --------------------------------- - normal 1 1 - -threaded N N - - The non-threaded build has a single Task and a single global - Capability. - - The THREADED_RTS build allows multiple tasks and mulitple Capabilities. - Multiple Tasks may all be running Haskell code simultaneously. A task - relinquishes its Capability when it is asked to evaluate an external - (C) call. - - In general, there may be multiple Tasks for an OS thread. This - happens if one Task makes a foreign call from Haskell, and - subsequently calls back in to create a new bound thread. + In general, there may be multiple Tasks associated with a given OS + thread. A second Task is created when one Task makes a foreign + call from Haskell, and subsequently calls back in to Haskell, + creating a new bound thread. A particular Task structure can belong to more than one OS thread over its lifetime. This is to avoid creating an unbounded number @@ -190,7 +178,10 @@ INLINE_HEADER void taskEnter (Task *task); // mainly for stats-gathering purposes. // Requires: sched_mutex. // +#if defined(THREADED_RTS) +// In the non-threaded RTS, tasks never stop. void workerTaskStop (Task *task); +#endif // Record the time spent in this Task. // This is called by workerTaskStop() but not by boundTaskExiting(), @@ -207,12 +198,6 @@ void discardTask (Task *task); // INLINE_HEADER Task *myTask (void); -// After a fork, the tasks are not carried into the child process, so -// we must tell the task manager. -// Requires: sched_mutex. -// -void resetTaskManagerAfterFork (void); - #if defined(THREADED_RTS) // Workers are attached to the supplied Capability. This Capability diff --git a/rts/ThrIOManager.h b/rts/ThrIOManager.h deleted file mode 100644 index eeccc6c420..0000000000 --- a/rts/ThrIOManager.h +++ /dev/null @@ -1,15 +0,0 @@ -/* -----------------------------------------------------------------------------
- *
- * (c) The GHC Team 1998-2006
- *
- * 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
diff --git a/rts/ThreadLabels.c b/rts/ThreadLabels.c index 6919e1ae38..aa620f0b9e 100644 --- a/rts/ThreadLabels.c +++ b/rts/ThreadLabels.c @@ -9,6 +9,7 @@ #include "PosixSource.h" #include "Rts.h" + #include "ThreadLabels.h" #include "RtsUtils.h" #include "Hash.h" diff --git a/rts/ThreadLabels.h b/rts/ThreadLabels.h index 59eb321cb7..60289ef306 100644 --- a/rts/ThreadLabels.h +++ b/rts/ThreadLabels.h @@ -7,8 +7,8 @@ * * ---------------------------------------------------------------------------*/ -#ifndef __THREADLABELS_H__ -#define __THREADLABELS_H__ +#ifndef THREADLABELS_H +#define THREADLABELS_H #if defined(DEBUG) void initThreadLabelTable (void); @@ -19,4 +19,4 @@ void removeThreadLabel (StgWord key); void labelThread (StgPtr tso, char *label); #endif -#endif /* __THREADLABELS_H__ */ +#endif /* THREADLABELS_H */ diff --git a/rts/ThreadPaused.c b/rts/ThreadPaused.c index 4882ab2374..58c30e330e 100644 --- a/rts/ThreadPaused.c +++ b/rts/ThreadPaused.c @@ -6,13 +6,14 @@ * * ---------------------------------------------------------------------------*/ +// #include "PosixSource.h" #include "Rts.h" -#include "Storage.h" -#include "LdvProfile.h" + +#include "ThreadPaused.h" +#include "sm/Storage.h" #include "Updates.h" #include "RaiseAsync.h" #include "Trace.h" -#include "RtsFlags.h" #include <string.h> // for memmove() @@ -141,23 +142,23 @@ stackSqueeze(StgTSO *tso, StgPtr bottom) // <empty> indicates unused // { - void *sp; - void *gap_start, *next_gap_start, *gap_end; + StgWord8 *sp; + StgWord8 *gap_start, *next_gap_start, *gap_end; nat chunk_size; - next_gap_start = (void *)((unsigned char*)gap + sizeof(StgUpdateFrame)); + next_gap_start = (StgWord8*)gap + sizeof(StgUpdateFrame); sp = next_gap_start; while ((StgPtr)gap > tso->sp) { // we're working in *bytes* now... gap_start = next_gap_start; - gap_end = (void*) ((unsigned char*)gap_start - gap->gap_size * sizeof(W_)); + gap_end = gap_start - gap->gap_size * sizeof(W_); gap = gap->next_gap; - next_gap_start = (void *)((unsigned char*)gap + sizeof(StgUpdateFrame)); + next_gap_start = (StgWord8*)gap + sizeof(StgUpdateFrame); - chunk_size = (unsigned char*)gap_end - (unsigned char*)next_gap_start; + chunk_size = gap_end - next_gap_start; sp -= chunk_size; memmove(sp, next_gap_start, chunk_size); } diff --git a/rts/ThreadPaused.h b/rts/ThreadPaused.h new file mode 100644 index 0000000000..60cded2885 --- /dev/null +++ b/rts/ThreadPaused.h @@ -0,0 +1,14 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team 1998-2006 + * + * Tidying up a thread when it stops running + * + * ---------------------------------------------------------------------------*/ + +#ifndef THREADPAUSED_H +#define THREADPAUSED_H + +void threadPaused ( Capability *cap, StgTSO * ); + +#endif /* THREADPAUSED_H */ diff --git a/rts/Threads.c b/rts/Threads.c index 1d871a5856..28820c8d44 100644 --- a/rts/Threads.c +++ b/rts/Threads.c @@ -8,10 +8,8 @@ #include "PosixSource.h" #include "Rts.h" -#include "SchedAPI.h" -#include "Storage.h" + #include "Threads.h" -#include "RtsFlags.h" #include "STM.h" #include "Schedule.h" #include "Trace.h" diff --git a/rts/Threads.h b/rts/Threads.h index f6d2dfd11a..d17235a2cb 100644 --- a/rts/Threads.h +++ b/rts/Threads.h @@ -25,13 +25,6 @@ void printThreadBlockage (StgTSO *tso); void printThreadStatus (StgTSO *t); void printAllThreads (void); void printThreadQueue (StgTSO *t); -# if defined(PARALLEL_HASKELL) -void print_bq (StgClosure *node); -void print_bqe (StgBlockingQueueElement *bqe); -nat run_queue_len (void); -# elif defined(GRAN) -void print_bq (StgClosure *node); -# endif #endif #endif /* THREADS_H */ diff --git a/rts/Ticky.c b/rts/Ticky.c index d319d18f09..4737f4a577 100644 --- a/rts/Ticky.c +++ b/rts/Ticky.c @@ -11,8 +11,8 @@ #define TICKY_C /* define those variables */ #include "PosixSource.h" #include "Rts.h" + #include "TickyCounters.h" -#include "RtsFlags.h" #include "Ticky.h" /* ----------------------------------------------------------------------------- diff --git a/rts/Ticky.h b/rts/Ticky.h index 21765e4bbb..c8da50a940 100644 --- a/rts/Ticky.h +++ b/rts/Ticky.h @@ -6,4 +6,9 @@ * * ---------------------------------------------------------------------------*/ -extern void PrintTickyInfo(void); +#ifndef TICKY_H +#define TICKY_H + +void PrintTickyInfo(void); + +#endif /* TICKY_H */ diff --git a/rts/Timer.c b/rts/Timer.c index 96ea5e2211..8c178a076b 100644 --- a/rts/Timer.c +++ b/rts/Timer.c @@ -14,12 +14,13 @@ * on platform-specific services to install and run the timers. * */ + +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + +#include "Timer.h" #include "Proftimer.h" -#include "Storage.h" #include "Schedule.h" -#include "Timer.h" #include "Ticker.h" #include "Capability.h" #include "RtsSignals.h" diff --git a/rts/Timer.h b/rts/Timer.h index 59b695cac2..c679a5881a 100644 --- a/rts/Timer.h +++ b/rts/Timer.h @@ -9,9 +9,7 @@ #ifndef TIMER_H #define TIMER_H -extern void initTimer(void); -extern void startTimer(void); -extern void stopTimer(void); -extern void exitTimer(void); +void initTimer (void); +void exitTimer (void); #endif /* TIMER_H */ diff --git a/rts/Trace.c b/rts/Trace.c index 63d4816585..0a47ea3860 100644 --- a/rts/Trace.c +++ b/rts/Trace.c @@ -8,10 +8,12 @@ #ifdef DEBUG +// external headers #include "Rts.h" -#include "OSThreads.h" +#include "rts/Flags.h" + +// internal headers #include "Trace.h" -#include "RtsFlags.h" #include "GetTime.h" #include "Stats.h" diff --git a/rts/Updates.cmm b/rts/Updates.cmm index 4043da05a5..fadf63b857 100644 --- a/rts/Updates.cmm +++ b/rts/Updates.cmm @@ -12,8 +12,9 @@ #include "Cmm.h" +#include "rts/prof/LDV.h" + #include "Updates.h" -#include "StgLdvProf.h" /* on entry to the update code (1) R1 points to the closure being returned diff --git a/rts/parallel/WSDeque.c b/rts/WSDeque.c index acecb85e5f..090a549709 100644 --- a/rts/parallel/WSDeque.c +++ b/rts/WSDeque.c @@ -38,10 +38,11 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" + #include "RtsUtils.h" #include "WSDeque.h" -#include "SMP.h" // for cas #define CASTOP(addr,old,new) ((old) == cas(((StgPtr)addr),(old),(new))) diff --git a/rts/parallel/WSDeque.h b/rts/WSDeque.h index d85567c38a..d85567c38a 100644 --- a/rts/parallel/WSDeque.h +++ b/rts/WSDeque.h diff --git a/rts/Weak.c b/rts/Weak.c index 17150f6b3c..f5c3a62bda 100644 --- a/rts/Weak.c +++ b/rts/Weak.c @@ -8,13 +8,12 @@ #include "PosixSource.h" #include "Rts.h" +#include "RtsAPI.h" + #include "RtsUtils.h" -#include "SchedAPI.h" -#include "RtsFlags.h" #include "Weak.h" #include "Schedule.h" #include "Prelude.h" -#include "RtsAPI.h" #include "Trace.h" // ForeignPtrs with C finalizers rely on weak pointers inside weak_ptr_list @@ -26,7 +25,7 @@ StgWeak *weak_ptr_list; rtsBool running_finalizers = rtsFalse; void -runCFinalizer(StgVoid *fn, StgVoid *ptr, StgVoid *env, StgWord flag) +runCFinalizer(void *fn, void *ptr, void *env, StgWord flag) { if (flag) ((void (*)(void *, void *))fn)(env, ptr); @@ -47,9 +46,9 @@ runAllCFinalizers(StgWeak *list) farr = (StgArrWords *)UNTAG_CLOSURE(w->cfinalizer); if ((StgClosure *)farr != &stg_NO_FINALIZER_closure) - runCFinalizer((StgVoid *)farr->payload[0], - (StgVoid *)farr->payload[1], - (StgVoid *)farr->payload[2], + runCFinalizer((void *)farr->payload[0], + (void *)farr->payload[1], + (void *)farr->payload[2], farr->payload[3]); } @@ -97,9 +96,9 @@ scheduleFinalizers(Capability *cap, StgWeak *list) farr = (StgArrWords *)UNTAG_CLOSURE(w->cfinalizer); if ((StgClosure *)farr != &stg_NO_FINALIZER_closure) - runCFinalizer((StgVoid *)farr->payload[0], - (StgVoid *)farr->payload[1], - (StgVoid *)farr->payload[2], + runCFinalizer((void *)farr->payload[0], + (void *)farr->payload[1], + (void *)farr->payload[2], farr->payload[3]); #ifdef PROFILING diff --git a/rts/Weak.h b/rts/Weak.h index 8fccae2a63..4f60bf9ebd 100644 --- a/rts/Weak.h +++ b/rts/Weak.h @@ -12,10 +12,12 @@ #include "Capability.h" extern rtsBool running_finalizers; +extern StgWeak * weak_ptr_list; -void runCFinalizer(StgVoid *fn, StgVoid *ptr, StgVoid *env, StgWord flag); +void runCFinalizer(void *fn, void *ptr, void *env, StgWord flag); void runAllCFinalizers(StgWeak *w); void scheduleFinalizers(Capability *cap, StgWeak *w); void markWeakList(void); -#endif +#endif /* WEAK_H */ + diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c index 098934c1ba..7f93d73d00 100644 --- a/rts/eventlog/EventLog.c +++ b/rts/eventlog/EventLog.c @@ -8,12 +8,15 @@ #ifdef EVENTLOG +#include "PosixSource.h" #include "Rts.h" + #include "EventLog.h" #include "Capability.h" #include "Trace.h" #include "RtsUtils.h" #include "Stats.h" + #include <string.h> #include <stdio.h> diff --git a/rts/eventlog/EventLog.h b/rts/eventlog/EventLog.h index c2511b986b..10903709d8 100644 --- a/rts/eventlog/EventLog.h +++ b/rts/eventlog/EventLog.h @@ -9,8 +9,8 @@ #ifndef EVENTLOG_H #define EVENTLOG_H +#include "rts/EventLogFormat.h" #include "Capability.h" -#include "EventLogFormat.h" #ifdef EVENTLOG diff --git a/rts/ghc.mk b/rts/ghc.mk index a7bfd12e58..4bb4118284 100644 --- a/rts/ghc.mk +++ b/rts/ghc.mk @@ -72,7 +72,7 @@ rts/dist/build/sm/Scav_thr.c : rts/sm/Scav.c "$(MKDIRHIER)" $(dir $@) cp $< $@ -rts_H_FILES = $(wildcard $(GHC_INCLUDE_DIR)/*.h) $(wildcard rts/*.h) +rts_H_FILES = $(wildcard includes/*.h) $(wildcard rts/*.h) # collect the -l flags that we need to link the rts dyn lib. rts/libs.depend : $(GHC_PKG_INPLACE) @@ -130,27 +130,26 @@ $(foreach way,$(rts_WAYS),$(eval $(call build-rts-way,$(way)))) #----------------------------------------------------------------------------- # Flags for compiling every file -# gcc provides lots of useful warnings if you ask it. -# This is a pretty good list to start with - use a # to comment out -# any you don't like. -WARNING_OPTS += -Wall -WARNING_OPTS += -W +# We like plenty of warnings. +WARNING_OPTS += -Wall -Wextra WARNING_OPTS += -Wstrict-prototypes WARNING_OPTS += -Wmissing-prototypes WARNING_OPTS += -Wmissing-declarations WARNING_OPTS += -Winline WARNING_OPTS += -Waggregate-return -#WARNING_OPTS += -Wpointer-arith +WARNING_OPTS += -Wpointer-arith +WARNING_OPTS += -Wmissing-noreturn +WARNING_OPTS += -Wcast-align +WARNING_OPTS += -Wnested-externs +WARNING_OPTS += -Wredundant-decls + +# These ones are hard to avoid: +#WARNING_OPTS += -Wconversion #WARNING_OPTS += -Wbad-function-cast -#WARNING_OPTS += -Wcast-align -#WARNING_OPTS += -Wnested-externs #WARNING_OPTS += -Wshadow #WARNING_OPTS += -Wcast-qual -#WARNING_OPTS += -Wno-unused -#WARNING_OPTS += -Wredundant-decls -#WARNING_OPTS += -Wconversion -STANDARD_OPTS += -I$(GHC_INCLUDE_DIR) -I$(GHC_RTS_DIR) -Irts/parallel -Irts/sm -Irts/eventlog +STANDARD_OPTS += -Iincludes -Irts # COMPILING_RTS is only used when building Win32 DLL support. STANDARD_OPTS += -DCOMPILING_RTS @@ -205,6 +204,8 @@ rts_HC_OPTS += -dcmm-lint # upd_evacee() assigments get moved before the object copy. rts_CC_OPTS += -fno-strict-aliasing +rts_CC_OPTS += -fno-common + ifeq "$(BeConservative)" "YES" rts_CC_OPTS += -DBE_CONSERVATIVE endif @@ -244,14 +245,14 @@ RtsUtils_CC_OPTS += -DGhcEnableTablesNextToCode=$(DQ)$(GhcEnableTablesNextToCode # ffi.h triggers prototype warnings, so disable them here: Interpreter_CC_OPTS += -Wno-strict-prototypes -Adjustor_CC_OPTS += -Wno-strict-prototypes -sm/Storage_CC_OPTS += -Wno-strict-prototypes +Adjustor_CC_OPTS += -Wno-strict-prototypes +sm/Storage_CC_OPTS += -Wno-strict-prototypes + +# inlining warnings happen in Compact +sm/Compact_CC_OPTS += -Wno-inline -StgCRun_CC_OPTS += -w -Typeable_CC_OPTS += -w RetainerProfile_CC_OPTS += -w RetainerSet_CC_OPTS += -Wno-format -sm/Compact_CC_OPTS += -w # On Windows: win32/ConsoleHandler_CC_OPTS += -w win32/ThrIOManager_CC_OPTS += -w @@ -271,8 +272,8 @@ sm/Evac_thr_HC_OPTS += -optc-funroll-loops # These files are just copies of sm/Evac.c and sm/Scav.c respectively, # but compiled with -DPARALLEL_GC. -sm/Evac_thr_HC_OPTS += -optc-DPARALLEL_GC -sm/Scav_thr_HC_OPTS += -optc-DPARALLEL_GC +sm/Evac_thr_HC_OPTS += -optc-DPARALLEL_GC -Irts/sm +sm/Scav_thr_HC_OPTS += -optc-DPARALLEL_GC -Irts/sm #----------------------------------------------------------------------------- # Add PAPI library if needed diff --git a/rts/hooks/FlagDefaults.c b/rts/hooks/FlagDefaults.c index 393d39bc39..ce1666f06d 100644 --- a/rts/hooks/FlagDefaults.c +++ b/rts/hooks/FlagDefaults.c @@ -4,6 +4,7 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" void diff --git a/rts/hooks/MallocFail.c b/rts/hooks/MallocFail.c index 1218d1d8d0..41c0d2a855 100644 --- a/rts/hooks/MallocFail.c +++ b/rts/hooks/MallocFail.c @@ -4,6 +4,7 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" #include <stdio.h> diff --git a/rts/hooks/OnExit.c b/rts/hooks/OnExit.c index dd4c3b4bb0..e8019c046b 100644 --- a/rts/hooks/OnExit.c +++ b/rts/hooks/OnExit.c @@ -4,6 +4,7 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" /* Note: by the time this hook has been called, Haskell land diff --git a/rts/hooks/OutOfHeap.c b/rts/hooks/OutOfHeap.c index e998237764..1945c51802 100644 --- a/rts/hooks/OutOfHeap.c +++ b/rts/hooks/OutOfHeap.c @@ -4,6 +4,7 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" #include <stdio.h> diff --git a/rts/hooks/RtsOpts.c b/rts/hooks/RtsOpts.c index b934b05f1b..2aae37246e 100644 --- a/rts/hooks/RtsOpts.c +++ b/rts/hooks/RtsOpts.c @@ -4,6 +4,7 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" #include <stdlib.h> diff --git a/rts/hooks/StackOverflow.c b/rts/hooks/StackOverflow.c index a395a3a1a5..0a1a23a65b 100644 --- a/rts/hooks/StackOverflow.c +++ b/rts/hooks/StackOverflow.c @@ -4,6 +4,7 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" #include <stdio.h> diff --git a/rts/parallel/GranSim.c b/rts/parallel/GranSim.c index 1b26bb9dff..7f7ad4424f 100644 --- a/rts/parallel/GranSim.c +++ b/rts/parallel/GranSim.c @@ -1,5 +1,5 @@ /* - Time-stamp: <2006-10-19 15:12:58 simonmar> + Time-stamp: <2009-07-06 21:48:36 simonmar> Variables and functions specific to GranSim the parallelism simulator for GPH. @@ -40,6 +40,8 @@ //@node Includes, Prototypes and externs, GranSim specific code, GranSim specific code //@subsection Includes +#if defined(GRAN) + #include "Rts.h" #include "RtsFlags.h" #include "RtsUtils.h" @@ -58,8 +60,6 @@ //@node Prototypes and externs, Constants and Variables, Includes, GranSim specific code //@subsection Prototypes and externs -#if defined(GRAN) - /* Prototypes */ static inline PEs ga_to_proc(StgWord); static inline rtsBool any_idle(void); diff --git a/rts/posix/FileLock.c b/rts/posix/FileLock.c index 26e9de4dc2..a6052c7381 100644 --- a/rts/posix/FileLock.c +++ b/rts/posix/FileLock.c @@ -6,11 +6,12 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "Hash.h" + #include "FileLock.h" +#include "Hash.h" #include "RtsUtils.h" -#include "OSThreads.h" #include <unistd.h> #include <sys/stat.h> diff --git a/rts/posix/FileLock.h b/rts/posix/FileLock.h new file mode 100644 index 0000000000..2edee5ba6e --- /dev/null +++ b/rts/posix/FileLock.h @@ -0,0 +1,15 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 2007 + * + * File locking support as required by Haskell 98 + * + * ---------------------------------------------------------------------------*/ + +#ifndef POSIX_FILELOCK_H +#define POSIX_FILELOCK_H + +void initFileLocking(void); +void freeFileLocking(void); + +#endif /* POSIX_FILELOCK_H */ diff --git a/rts/posix/Itimer.c b/rts/posix/Itimer.c index eb26cd3699..3a09e804b5 100644 --- a/rts/posix/Itimer.c +++ b/rts/posix/Itimer.c @@ -16,15 +16,15 @@ * Hence, we use the old-fashioned @setitimer@ that just about everyone seems * to support. So much for standards. */ + +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" -#include "Timer.h" + #include "Ticker.h" -#include "posix/Itimer.h" +#include "Itimer.h" #include "Proftimer.h" -#include "Storage.h" #include "Schedule.h" -#include "posix/Select.h" +#include "Select.h" /* As recommended in the autoconf manual */ # ifdef TIME_WITH_SYS_TIME @@ -229,31 +229,6 @@ exitTicker(void) #endif } -#if 0 -/* Currently unused */ -void -block_vtalrm_signal(void) -{ - sigset_t signals; - - sigemptyset(&signals); - sigaddset(&signals, ITIMER_SIGNAL); - - (void) sigprocmask(SIG_BLOCK, &signals, NULL); -} - -void -unblock_vtalrm_signal(void) -{ - sigset_t signals; - - sigemptyset(&signals); - sigaddset(&signals, ITIMER_SIGNAL); - - (void) sigprocmask(SIG_UNBLOCK, &signals, NULL); -} -#endif - /* gettimeofday() takes around 1us on our 500MHz PIII. Since we're * only calling it 50 times/s, it shouldn't have any great impact. */ diff --git a/rts/posix/Itimer.h b/rts/posix/Itimer.h index 09d01bde54..4cae935710 100644 --- a/rts/posix/Itimer.h +++ b/rts/posix/Itimer.h @@ -10,10 +10,5 @@ #define ITIMER_H extern lnat getourtimeofday ( void ); -#if 0 -/* unused */ -extern void block_vtalrm_signal ( void ); -extern void unblock_vtalrm_signal ( void ); -#endif #endif /* ITIMER_H */ diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c index 51737ad650..0a37256022 100644 --- a/rts/posix/OSMem.c +++ b/rts/posix/OSMem.c @@ -6,12 +6,12 @@ * * ---------------------------------------------------------------------------*/ -/* This is non-posix compliant. */ -/* #include "PosixSource.h" */ +// This is non-posix compliant. +// #include "PosixSource.h" #include "Rts.h" -#include "OSMem.h" -#include "RtsFlags.h" + +#include "sm/OSMem.h" #ifdef HAVE_UNISTD_H #include <unistd.h> @@ -138,7 +138,7 @@ static void * gen_map_mblocks (lnat size) { int slop; - void *ret; + StgWord8 *ret; // Try to map a larger block, and take the aligned portion from // it (unmap the rest). diff --git a/rts/posix/OSThreads.c b/rts/posix/OSThreads.c index 324701d40d..a813eebf9e 100644 --- a/rts/posix/OSThreads.c +++ b/rts/posix/OSThreads.c @@ -13,9 +13,10 @@ #define _GNU_SOURCE #endif +#include "PosixSource.h" #include "Rts.h" + #if defined(THREADED_RTS) -#include "OSThreads.h" #include "RtsUtils.h" #include "Task.h" diff --git a/rts/posix/Select.c b/rts/posix/Select.c index 32dca96cd8..46db4054bb 100644 --- a/rts/posix/Select.c +++ b/rts/posix/Select.c @@ -6,19 +6,16 @@ * * ---------------------------------------------------------------------------*/ -/* we're outside the realms of POSIX here... */ -/* #include "PosixSource.h" */ - +#include "PosixSource.h" #include "Rts.h" -#include "Storage.h" + +#include "Signals.h" #include "Schedule.h" #include "RtsUtils.h" -#include "RtsFlags.h" -#include "Timer.h" #include "Itimer.h" -#include "Signals.h" #include "Capability.h" -#include "posix/Select.h" +#include "Select.h" +#include "AwaitEvent.h" # ifdef HAVE_SYS_TYPES_H # include <sys/types.h> diff --git a/rts/posix/Select.h b/rts/posix/Select.h index 8825562974..e92a4bc889 100644 --- a/rts/posix/Select.h +++ b/rts/posix/Select.h @@ -6,21 +6,12 @@ * * -------------------------------------------------------------------------*/ -#ifndef SELECT_H -#define SELECT_H +#ifndef POSIX_SELECT_H +#define POSIX_SELECT_H #if !defined(THREADED_RTS) /* In Select.c */ -extern lnat RTS_VAR(timestamp); - -/* awaitEvent(rtsBool wait) - * - * Checks for blocked threads that need to be woken. - * - * Called from STG : NO - * Locks assumed : sched_mutex - */ -void awaitEvent(rtsBool wait); /* In Select.c */ +extern lnat timestamp; #endif -#endif /* SELECT_H */ +#endif /* POSIX_SELECT_H */ diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c index ace58c2f98..660065734b 100644 --- a/rts/posix/Signals.c +++ b/rts/posix/Signals.c @@ -6,18 +6,15 @@ * * ---------------------------------------------------------------------------*/ -/* This is non-Posix-compliant. - #include "PosixSource.h" -*/ +#include "PosixSource.h" #include "Rts.h" -#include "SchedAPI.h" + #include "Schedule.h" #include "RtsSignals.h" -#include "posix/Signals.h" +#include "Signals.h" #include "RtsUtils.h" -#include "RtsFlags.h" #include "Prelude.h" -#include "ThrIOManager.h" +#include "Stable.h" #ifdef alpha_HOST_ARCH # if defined(linux_HOST_OS) diff --git a/rts/posix/TTY.c b/rts/posix/TTY.c new file mode 100644 index 0000000000..d39ef37b86 --- /dev/null +++ b/rts/posix/TTY.c @@ -0,0 +1,65 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2009 + * + * TTY-related functionality + * + * ---------------------------------------------------------------------------*/ + +#include "PosixSource.h" +#include "Rts.h" + +#include "RtsUtils.h" // __hscore_get/set prototypes +#include "TTY.h" + +#ifdef HAVE_TERMIOS_H +#include <termios.h> +#endif +#ifdef HAVE_SIGNAL_H +#include <signal.h> +#endif + +// Here we save the terminal settings on the standard file +// descriptors, if we need to change them (eg. to support NoBuffering +// input). +static void *saved_termios[3] = {NULL,NULL,NULL}; + +void* +__hscore_get_saved_termios(int fd) +{ + return (0 <= fd && fd < (int)(sizeof(saved_termios) / sizeof(*saved_termios))) ? + saved_termios[fd] : NULL; +} + +void +__hscore_set_saved_termios(int fd, void* ts) +{ + if (0 <= fd && fd < (int)(sizeof(saved_termios) / sizeof(*saved_termios))) { + saved_termios[fd] = ts; + } +} + +void +resetTerminalSettings (void) +{ +#if HAVE_TERMIOS_H + // Reset the terminal settings on the standard file descriptors, + // if we changed them. See System.Posix.Internals.tcSetAttr for + // more details, including the reason we termporarily disable + // SIGTTOU here. + { + int fd; + sigset_t sigset, old_sigset; + sigemptyset(&sigset); + sigaddset(&sigset, SIGTTOU); + sigprocmask(SIG_BLOCK, &sigset, &old_sigset); + for (fd = 0; fd <= 2; fd++) { + struct termios* ts = (struct termios*)__hscore_get_saved_termios(fd); + if (ts != NULL) { + tcsetattr(fd,TCSANOW,ts); + } + } + sigprocmask(SIG_SETMASK, &old_sigset, NULL); + } +#endif +} diff --git a/rts/posix/TTY.h b/rts/posix/TTY.h new file mode 100644 index 0000000000..f291d30de4 --- /dev/null +++ b/rts/posix/TTY.h @@ -0,0 +1,15 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2009 + * + * TTY-related functionality + * + * ---------------------------------------------------------------------------*/ + +#ifndef POSIX_TTY_H +#define POSIX_TTY_H + +void resetTerminalSettings (void); + +#endif /* POSIX_TTY_H */ + diff --git a/rts/sm/BlockAlloc.c b/rts/sm/BlockAlloc.c index 280ebfc7db..bf7a55e7a9 100644 --- a/rts/sm/BlockAlloc.c +++ b/rts/sm/BlockAlloc.c @@ -17,11 +17,10 @@ #include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + +#include "Storage.h" #include "RtsUtils.h" #include "BlockAlloc.h" -#include "MBlock.h" -#include "Storage.h" #include <string.h> @@ -284,7 +283,7 @@ alloc_mega_group (nat mblocks) { // we take our chunk off the end here. nat best_mblocks = BLOCKS_TO_MBLOCKS(best->blocks); - bd = FIRST_BDESCR(MBLOCK_ROUND_DOWN(best) + + bd = FIRST_BDESCR((StgWord8*)MBLOCK_ROUND_DOWN(best) + (best_mblocks-mblocks)*MBLOCK_SIZE); best->blocks = MBLOCK_GROUP_BLOCKS(best_mblocks - mblocks); @@ -415,7 +414,8 @@ coalesce_mblocks (bdescr *p) q = p->link; if (q != NULL && MBLOCK_ROUND_DOWN(q) == - MBLOCK_ROUND_DOWN(p) + BLOCKS_TO_MBLOCKS(p->blocks) * MBLOCK_SIZE) { + (StgWord8*)MBLOCK_ROUND_DOWN(p) + + BLOCKS_TO_MBLOCKS(p->blocks) * MBLOCK_SIZE) { // can coalesce p->blocks = MBLOCK_GROUP_BLOCKS(BLOCKS_TO_MBLOCKS(p->blocks) + BLOCKS_TO_MBLOCKS(q->blocks)); @@ -610,20 +610,21 @@ splitBlockGroup (bdescr *bd, nat blocks) static void initMBlock(void *mblock) { - bdescr *bd; - void *block; - - /* the first few Bdescr's in a block are unused, so we don't want to - * put them all on the free list. - */ - block = FIRST_BLOCK(mblock); - bd = FIRST_BDESCR(mblock); - - /* Initialise the start field of each block descriptor - */ - for (; block <= LAST_BLOCK(mblock); bd += 1, block += BLOCK_SIZE) { - bd->start = block; - } + bdescr *bd; + StgWord8 *block; + + /* the first few Bdescr's in a block are unused, so we don't want to + * put them all on the free list. + */ + block = FIRST_BLOCK(mblock); + bd = FIRST_BDESCR(mblock); + + /* Initialise the start field of each block descriptor + */ + for (; block <= (StgWord8*)LAST_BLOCK(mblock); bd += 1, + block += BLOCK_SIZE) { + bd->start = (void*)block; + } } /* ----------------------------------------------------------------------------- @@ -708,7 +709,7 @@ checkFreeListSanity(void) if (bd->link != NULL) { ASSERT (MBLOCK_ROUND_DOWN(bd->link) != - MBLOCK_ROUND_DOWN(bd) + + (StgWord8*)MBLOCK_ROUND_DOWN(bd) + BLOCKS_TO_MBLOCKS(bd->blocks) * MBLOCK_SIZE); } } @@ -758,7 +759,8 @@ reportUnmarkedBlocks (void) debugBelch(" %p\n",bd); } if (bd->blocks >= BLOCKS_PER_MBLOCK) { - mblock += (BLOCKS_TO_MBLOCKS(bd->blocks) - 1) * MBLOCK_SIZE; + mblock = (StgWord8*)mblock + + (BLOCKS_TO_MBLOCKS(bd->blocks) - 1) * MBLOCK_SIZE; break; } else { bd += bd->blocks; diff --git a/rts/sm/Compact.c b/rts/sm/Compact.c index 9c13253c32..892364dfa5 100644 --- a/rts/sm/Compact.c +++ b/rts/sm/Compact.c @@ -13,16 +13,18 @@ #include "PosixSource.h" #include "Rts.h" + +#include "Storage.h" #include "RtsUtils.h" -#include "RtsFlags.h" -#include "OSThreads.h" #include "BlockAlloc.h" -#include "MBlock.h" #include "GC.h" #include "Compact.h" #include "Schedule.h" #include "Apply.h" #include "Trace.h" +#include "Weak.h" +#include "MarkWeak.h" +#include "Stable.h" // Turn off inlining when debugging - it obfuscates things #ifdef DEBUG @@ -166,7 +168,7 @@ loop: case 1: { StgWord r = *(StgPtr)(q-1); - ASSERT(LOOKS_LIKE_INFO_PTR(UNTAG_CLOSURE((StgClosure *)r))); + ASSERT(LOOKS_LIKE_INFO_PTR((StgWord)UNTAG_CLOSURE((StgClosure *)r))); return r; } case 2: @@ -929,7 +931,7 @@ update_bkwd_compact( step *stp ) iptr = get_threaded_info(p); unthread(p, (StgWord)free + GET_CLOSURE_TAG((StgClosure *)iptr)); - ASSERT(LOOKS_LIKE_INFO_PTR(((StgClosure *)p)->header.info)); + ASSERT(LOOKS_LIKE_INFO_PTR((StgWord)((StgClosure *)p)->header.info)); info = get_itbl((StgClosure *)p); size = closure_sizeW_((StgClosure *)p,info); diff --git a/rts/sm/Compact.h b/rts/sm/Compact.h index 40622c5682..7a237ac362 100644 --- a/rts/sm/Compact.h +++ b/rts/sm/Compact.h @@ -11,8 +11,8 @@ * * ---------------------------------------------------------------------------*/ -#ifndef GCCOMPACT_H -#define GCCOMPACT_H +#ifndef SM_COMPACT_H +#define SM_COMPACT_H INLINE_HEADER rtsBool mark_stack_empty(void) @@ -76,4 +76,4 @@ is_marked(StgPtr p, bdescr *bd) extern void compact (StgClosure *static_objects); -#endif /* GCCOMPACT_H */ +#endif /* SM_COMPACT_H */ diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c index 5935f9069e..9e6d0f1783 100644 --- a/rts/sm/Evac.c +++ b/rts/sm/Evac.c @@ -11,16 +11,16 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "Storage.h" -#include "MBlock.h" + #include "Evac.h" +#include "Storage.h" #include "GC.h" #include "GCThread.h" #include "GCUtils.h" #include "Compact.h" #include "Prelude.h" -#include "LdvProfile.h" #include "Trace.h" #if defined(PROF_SPIN) && defined(THREADED_RTS) && defined(PARALLEL_GC) diff --git a/rts/sm/Evac.h b/rts/sm/Evac.h index e6ef02cfcc..78d024f3e9 100644 --- a/rts/sm/Evac.h +++ b/rts/sm/Evac.h @@ -11,6 +11,9 @@ * * ---------------------------------------------------------------------------*/ +#ifndef SM_EVAC_H +#define SM_EVAC_H + // Use a register argument for evacuate, if available. // Earlier, the regparm attribute was used whenever __GNUC__ >= 2, but this // generated warnings on PPC. So the use is restricted further. @@ -31,3 +34,6 @@ REGPARM1 void evacuate (StgClosure **p); REGPARM1 void evacuate1 (StgClosure **p); extern lnat thunk_selector_depth; + +#endif /* SM_EVAC_H */ + diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 88b11aae88..02fd6d9161 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -11,28 +11,23 @@ * * ---------------------------------------------------------------------------*/ -// #include "PosixSource.h" +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" +#include "HsFFI.h" + +#include "Storage.h" #include "RtsUtils.h" #include "Apply.h" -#include "OSThreads.h" -#include "LdvProfile.h" #include "Updates.h" #include "Stats.h" #include "Schedule.h" #include "Sanity.h" #include "BlockAlloc.h" -#include "MBlock.h" #include "ProfHeap.h" -#include "SchedAPI.h" #include "Weak.h" #include "Prelude.h" -#include "ParTicky.h" // ToDo: move into Rts.h #include "RtsSignals.h" #include "STM.h" -#include "HsFFI.h" -#include "Linker.h" #if defined(RTS_GTK_FRONTPANEL) #include "FrontPanel.h" #endif @@ -40,6 +35,7 @@ #include "RetainerProfile.h" #include "RaiseAsync.h" #include "Papi.h" +#include "Stable.h" #include "GC.h" #include "GCThread.h" @@ -1112,10 +1108,11 @@ gcWorkerThread (Capability *cap) #endif +#if defined(THREADED_RTS) + void waitForGcThreads (Capability *cap USED_IF_THREADS) { -#if defined(THREADED_RTS) nat n_threads = RtsFlags.ParFlags.nNodes; nat me = cap->no; nat i, j; @@ -1141,9 +1138,10 @@ waitForGcThreads (Capability *cap USED_IF_THREADS) if (!retry) break; } } -#endif } +#endif // THREADED_RTS + static void start_gc_threads (void) { @@ -1185,10 +1183,10 @@ shutdown_gc_threads (nat n_threads USED_IF_THREADS, nat me USED_IF_THREADS) #endif } +#if defined(THREADED_RTS) void releaseGCThreads (Capability *cap USED_IF_THREADS) { -#if defined(THREADED_RTS) nat n_threads = RtsFlags.ParFlags.nNodes; nat me = cap->no; nat i; @@ -1201,8 +1199,8 @@ releaseGCThreads (Capability *cap USED_IF_THREADS) ACQUIRE_SPIN_LOCK(&gc_threads[i]->gc_spin); RELEASE_SPIN_LOCK(&gc_threads[i]->mut_spin); } -#endif } +#endif /* ---------------------------------------------------------------------------- Initialise a generation that is to be collected diff --git a/rts/sm/GC.h b/rts/sm/GC.h index fb4381dc0b..920b464bbb 100644 --- a/rts/sm/GC.h +++ b/rts/sm/GC.h @@ -11,8 +11,15 @@ * * ---------------------------------------------------------------------------*/ -#ifndef GC_H -#define GC_H +#ifndef SM_GC_H +#define SM_GC_H + +void GarbageCollect(rtsBool force_major_gc, nat gc_type, Capability *cap); + +typedef void (*evac_fn)(void *user, StgClosure **root); + +StgClosure * isAlive ( StgClosure *p ); +void markCAFs ( evac_fn evac, void *user ); extern nat N; extern rtsBool major_gc; @@ -45,9 +52,12 @@ extern StgWord64 whitehole_spin; void gcWorkerThread (Capability *cap); void initGcThreads (void); void freeGcThreads (void); + +#if defined(THREADED_RTS) void waitForGcThreads (Capability *cap); void releaseGCThreads (Capability *cap); +#endif #define WORK_UNIT_WORDS 128 -#endif /* GC_H */ +#endif /* SM_GC_H */ diff --git a/rts/sm/GCAux.c b/rts/sm/GCAux.c index c1ff54123d..404e9bbcbc 100644 --- a/rts/sm/GCAux.c +++ b/rts/sm/GCAux.c @@ -7,10 +7,11 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "Storage.h" -#include "MBlock.h" + #include "GC.h" +#include "Storage.h" #include "Compact.h" #include "Task.h" #include "Capability.h" diff --git a/rts/sm/GCThread.h b/rts/sm/GCThread.h index f91092b7ea..9188a20a9a 100644 --- a/rts/sm/GCThread.h +++ b/rts/sm/GCThread.h @@ -11,10 +11,9 @@ * * ---------------------------------------------------------------------------*/ -#ifndef GCTHREAD_H -#define GCTHREAD_H +#ifndef SM_GCTHREAD_H +#define SM_GCTHREAD_H -#include "OSThreads.h" #include "WSDeque.h" /* ----------------------------------------------------------------------------- @@ -271,5 +270,5 @@ extern StgWord8 the_gc_thread[]; #endif -#endif // GCTHREAD_H +#endif // SM_GCTHREAD_H diff --git a/rts/sm/GCUtils.c b/rts/sm/GCUtils.c index 57cede7d43..6c6f10e01f 100644 --- a/rts/sm/GCUtils.c +++ b/rts/sm/GCUtils.c @@ -11,8 +11,9 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + #include "Storage.h" #include "GC.h" #include "GCThread.h" @@ -101,6 +102,7 @@ grab_local_todo_block (step_workspace *ws) return NULL; } +#if defined(THREADED_RTS) bdescr * steal_todo_block (nat s) { @@ -117,6 +119,7 @@ steal_todo_block (nat s) } return NULL; } +#endif void push_scanned_block (bdescr *bd, step_workspace *ws) diff --git a/rts/sm/GCUtils.h b/rts/sm/GCUtils.h index e71f4374fb..d68ce7876f 100644 --- a/rts/sm/GCUtils.h +++ b/rts/sm/GCUtils.h @@ -11,7 +11,8 @@ * * --------------------------------------------------------------------------*/ -#include "SMP.h" +#ifndef SM_GCUTILS_H +#define SM_GCUTILS_H bdescr *allocBlock_sync(void); void freeChain_sync(bdescr *bd); @@ -21,7 +22,9 @@ StgPtr todo_block_full (nat size, step_workspace *ws); StgPtr alloc_todo_block (step_workspace *ws, nat size); bdescr *grab_local_todo_block (step_workspace *ws); +#if defined(THREADED_RTS) bdescr *steal_todo_block (nat s); +#endif // Returns true if a block is partially full. This predicate is used to try // to re-use partial blocks wherever possible, and to reduce wastage. @@ -55,3 +58,5 @@ recordMutableGen_GC (StgClosure *p, nat gen_no) } *bd->free++ = (StgWord)p; } + +#endif /* SM_GCUTILS_H */ diff --git a/rts/sm/MBlock.c b/rts/sm/MBlock.c index b3fa13b0bc..996b2c9ae9 100644 --- a/rts/sm/MBlock.c +++ b/rts/sm/MBlock.c @@ -9,10 +9,9 @@ * ---------------------------------------------------------------------------*/ #include "PosixSource.h" - #include "Rts.h" + #include "RtsUtils.h" -#include "MBlock.h" #include "BlockAlloc.h" #include "Trace.h" #include "OSMem.h" @@ -235,7 +234,7 @@ getMBlocks(nat n) // fill in the table for (i = 0; i < n; i++) { - markHeapAlloced( ret + i * MBLOCK_SIZE ); + markHeapAlloced( (StgWord8*)ret + i * MBLOCK_SIZE ); } mblocks_allocated += n; diff --git a/rts/sm/MBlock.h b/rts/sm/MBlock.h deleted file mode 100644 index f9dddc3138..0000000000 --- a/rts/sm/MBlock.h +++ /dev/null @@ -1,208 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) The GHC Team, 1998-2008 - * - * MegaBlock Allocator interface. - * - * See wiki commentary at - * http://hackage.haskell.org/trac/ghc/wiki/Commentary/HeapAlloced - * - * ---------------------------------------------------------------------------*/ - -#ifndef MBLOCK_H -#define MBLOCK_H - -#include "GC.h" - -extern lnat RTS_VAR(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 /* MBLOCK_H */ diff --git a/rts/sm/MarkWeak.c b/rts/sm/MarkWeak.c index 78c84ed77a..4f0a7a451b 100644 --- a/rts/sm/MarkWeak.c +++ b/rts/sm/MarkWeak.c @@ -11,14 +11,16 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "Storage.h" + #include "MarkWeak.h" #include "GC.h" #include "GCThread.h" #include "Evac.h" #include "Trace.h" #include "Schedule.h" +#include "Weak.h" /* ----------------------------------------------------------------------------- Weak Pointers diff --git a/rts/sm/MarkWeak.h b/rts/sm/MarkWeak.h index 7b3a806857..2647a22eec 100644 --- a/rts/sm/MarkWeak.h +++ b/rts/sm/MarkWeak.h @@ -11,6 +11,9 @@ * * ---------------------------------------------------------------------------*/ +#ifndef SM_MARKWEAK_H +#define SM_MARKWEAK_H + extern StgWeak *old_weak_ptr_list; extern StgTSO *resurrected_threads; extern StgTSO *exception_threads; @@ -19,3 +22,5 @@ void initWeakForGC ( void ); rtsBool traverseWeakPtrList ( void ); void markWeakPtrList ( void ); rtsBool traverseBlackholeQueue ( void ); + +#endif /* SM_MARKWEAK_H */ diff --git a/rts/sm/OSMem.h b/rts/sm/OSMem.h index dcf8eb73df..3dbca23d11 100644 --- a/rts/sm/OSMem.h +++ b/rts/sm/OSMem.h @@ -6,8 +6,13 @@ * * ---------------------------------------------------------------------------*/ +#ifndef SM_OSMEM_H +#define SM_OSMEM_H + void osMemInit(void); void *osGetMBlocks(nat n); void osFreeAllMBlocks(void); lnat getPageSize (void); void setExecutable (void *p, lnat len, rtsBool exec); + +#endif /* SM_OSMEM_H */ diff --git a/rts/sm/README b/rts/sm/README deleted file mode 100644 index 61cb7d2c06..0000000000 --- a/rts/sm/README +++ /dev/null @@ -1,11 +0,0 @@ -The Storage Manager -=================== - -This directory contains the storage manager and garbage collector. -The interfaces exported from here are: - - Storage.h (in ../includes) - Block.h (in ../includes) - GC.h - Arena.h - BlockAlloc.h diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c index b850423244..9ebd4c5597 100644 --- a/rts/sm/Scav.c +++ b/rts/sm/Scav.c @@ -11,10 +11,10 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + #include "Storage.h" -#include "MBlock.h" #include "GC.h" #include "GCThread.h" #include "GCUtils.h" @@ -23,7 +23,6 @@ #include "Scav.h" #include "Apply.h" #include "Trace.h" -#include "LdvProfile.h" #include "Sanity.h" #include "Capability.h" diff --git a/rts/sm/Scav.h b/rts/sm/Scav.h index df774cd63d..10b9ffde40 100644 --- a/rts/sm/Scav.h +++ b/rts/sm/Scav.h @@ -11,6 +11,9 @@ * * ---------------------------------------------------------------------------*/ +#ifndef SM_SCAV_H +#define SM_SCAV_H + void scavenge_loop (void); void scavenge_mutable_list (bdescr *bd, generation *gen); void scavenge_capability_mut_lists (Capability *cap); @@ -20,3 +23,6 @@ void scavenge_loop1 (void); void scavenge_mutable_list1 (bdescr *bd, generation *gen); void scavenge_capability_mut_Lists1 (Capability *cap); #endif + +#endif /* SM_SCAV_H */ + diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index d14e58856f..97615e9d1b 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -13,18 +13,15 @@ #include "PosixSource.h" #include "Rts.h" + +#include "Storage.h" #include "RtsUtils.h" -#include "RtsFlags.h" #include "Stats.h" -#include "Hooks.h" #include "BlockAlloc.h" -#include "MBlock.h" #include "Weak.h" #include "Sanity.h" #include "Arena.h" -#include "OSThreads.h" #include "Capability.h" -#include "Storage.h" #include "Schedule.h" #include "RetainerProfile.h" // for counting memory blocks (memInventory) #include "OSMem.h" @@ -32,7 +29,6 @@ #include "GC.h" #include "Evac.h" -#include <stdlib.h> #include <string.h> #include "ffi.h" @@ -71,6 +67,7 @@ step *nurseries = NULL; /* array of nurseries, >1 only if THREADED_RTS * Mutex sm_mutex; #endif +static void allocNurseries ( void ); static void initStep (step *stp, int g, int s) @@ -440,7 +437,7 @@ assignNurseriesToCapabilities (void) #endif } -void +static void allocNurseries( void ) { nat i; diff --git a/rts/sm/Storage.h b/rts/sm/Storage.h new file mode 100644 index 0000000000..c6aa45e162 --- /dev/null +++ b/rts/sm/Storage.h @@ -0,0 +1,169 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2009 + * + * External Storage Manger Interface + * + * ---------------------------------------------------------------------------*/ + +#ifndef SM_STORAGE_H +#define SM_STORAGE_H + +/* ----------------------------------------------------------------------------- + Initialisation / De-initialisation + -------------------------------------------------------------------------- */ + +void initStorage(void); +void exitStorage(void); +void freeStorage(void); + +/* ----------------------------------------------------------------------------- + Storage manager state + -------------------------------------------------------------------------- */ + +extern bdescr * pinned_object_block; + +extern nat alloc_blocks; +extern nat alloc_blocks_lim; + +INLINE_HEADER rtsBool +doYouWantToGC( void ) +{ + return (alloc_blocks >= alloc_blocks_lim); +} + +/* for splitting blocks groups in two */ +bdescr * splitLargeBlock (bdescr *bd, nat blocks); + +/* ----------------------------------------------------------------------------- + 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 + +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; +} + +/* ----------------------------------------------------------------------------- + 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); + +/* ----------------------------------------------------------------------------- + Similarly, the write barrier for MVARs + -------------------------------------------------------------------------- */ + +void dirty_MVAR(StgRegTable *reg, StgClosure *p); + +/* ----------------------------------------------------------------------------- + Nursery manipulation + -------------------------------------------------------------------------- */ + +void resetNurseries ( void ); +void resizeNurseries ( nat blocks ); +void resizeNurseriesFixed ( nat blocks ); +lnat countNurseryBlocks ( void ); + +/* ----------------------------------------------------------------------------- + Stats 'n' DEBUG stuff + -------------------------------------------------------------------------- */ + +extern ullong total_allocated; + +lnat calcAllocated (void); +lnat calcLiveBlocks (void); +lnat calcLiveWords (void); +lnat countOccupied (bdescr *bd); +lnat calcNeeded (void); +HsInt64 getAllocations (void); + +#if defined(DEBUG) +void memInventory (rtsBool show); +void checkSanity (void); +nat countBlocks (bdescr *); +void checkNurserySanity (step *stp); +#endif + +/* ---------------------------------------------------------------------------- + Storage manager internal APIs and globals + ------------------------------------------------------------------------- */ + +#define END_OF_STATIC_LIST ((StgClosure*)1) + +void move_TSO (StgTSO *src, StgTSO *dest); + +extern StgClosure * caf_list; +extern StgClosure * revertible_caf_list; + +#endif /* SM_STORAGE_H */ diff --git a/rts/sm/Sweep.c b/rts/sm/Sweep.c index 444c3d5111..b6574024eb 100644 --- a/rts/sm/Sweep.c +++ b/rts/sm/Sweep.c @@ -11,9 +11,11 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" + +#include "Storage.h" #include "Sweep.h" -#include "Block.h" #include "Trace.h" void diff --git a/rts/sm/Sweep.h b/rts/sm/Sweep.h index e7904a90a8..562a934faa 100644 --- a/rts/sm/Sweep.h +++ b/rts/sm/Sweep.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------------- * - * (c) The GHC Team 2008 + * (c) The GHC Team 2008 * * Simple mark/sweep, collecting whole blocks. * @@ -11,4 +11,9 @@ * * ---------------------------------------------------------------------------*/ +#ifndef SM_SWEEP_H +#define SM_SWEEP_H + void sweep(step *gen); + +#endif /* SM_SWEEP_H */ diff --git a/rts/win32/AsyncIO.h b/rts/win32/AsyncIO.h index ffbe71e1af..27669ce0b4 100644 --- a/rts/win32/AsyncIO.h +++ b/rts/win32/AsyncIO.h @@ -4,8 +4,10 @@ * * (c) sof, 2002-2003. */ -#ifndef __ASYNCHIO_H__ -#define __ASYNCHIO_H__ + +#ifndef WIN32_ASYNCHIO_H +#define WIN32_ASYNCHIO_H + extern unsigned int addIORequest(int fd, int forWriting, @@ -22,4 +24,4 @@ extern int awaitRequests(rtsBool wait); extern void abandonRequestWait(void); extern void resetAbandonRequestWait(void); -#endif /* __ASYNCHIO_H__ */ +#endif /* WIN32_ASYNCHIO_H */ diff --git a/rts/win32/ConsoleHandler.h b/rts/win32/ConsoleHandler.h index 33fa065733..0d09a67b94 100644 --- a/rts/win32/ConsoleHandler.h +++ b/rts/win32/ConsoleHandler.h @@ -2,8 +2,8 @@ * Console control handler support. * */ -#ifndef __CONSOLEHANDLER_H__ -#define __CONSOLEHANDLER_H__ +#ifndef WIN32_CONSOLEHANDLER_H +#define WIN32_CONSOLEHANDLER_H /* * Console control handlers lets an application handle Ctrl+C, Ctrl+Break etc. @@ -52,14 +52,6 @@ extern StgInt stg_pending_events; extern void startSignalHandlers(Capability *cap); /* - * Function: handleSignalsInThisThread() - * - * Have current (OS) thread assume responsibility of handling console events/signals. - * Currently not used (by the console event handling code.) - */ -extern void handleSignalsInThisThread(void); - -/* * Function: rts_waitConsoleHandlerCompletion() * * Esoteric entry point used by worker thread that got woken @@ -69,4 +61,4 @@ extern int rts_waitConsoleHandlerCompletion(void); #endif /* THREADED_RTS */ -#endif /* __CONSOLEHANDLER_H__ */ +#endif /* Win32_CONSOLEHANDLER_H */ diff --git a/rts/win32/IOManager.h b/rts/win32/IOManager.h index 7379ce3b16..145a1e549b 100644 --- a/rts/win32/IOManager.h +++ b/rts/win32/IOManager.h @@ -4,8 +4,9 @@ * * (c) sof, 2002-2003 */ -#ifndef __IOMANAGER_H__ -#define __IOMANAGER_H__ + +#ifndef WIN32_IOMANAGER_H +#define WIN32_IOMANAGER_H #include <windows.h> @@ -103,4 +104,4 @@ extern int AddProcRequest ( void* proc, extern void abandonWorkRequest ( int reqID ); -#endif /* __IOMANAGER_H__ */ +#endif /* WIN32_IOMANAGER_H */ diff --git a/rts/win32/ThrIOManager.c b/rts/win32/ThrIOManager.c index c52928c3a2..e62b33d9d3 100644 --- a/rts/win32/ThrIOManager.c +++ b/rts/win32/ThrIOManager.c @@ -8,7 +8,7 @@ * ---------------------------------------------------------------------------*/
#include "Rts.h"
-#include "ThrIOManager.h"
+#include "IOManager.h"
#include "Prelude.h"
#include <windows.h>
diff --git a/rts/win32/WorkQueue.h b/rts/win32/WorkQueue.h index bde82a3a77..3ed2385ec9 100644 --- a/rts/win32/WorkQueue.h +++ b/rts/win32/WorkQueue.h @@ -5,8 +5,9 @@ * (c) sof, 2002-2003 * */ -#ifndef __WORKQUEUE_H__ -#define __WORKQUEUE_H__ + +#ifndef WIN32_WORKQUEUE_H +#define WIN32_WORKQUEUE_H #include <windows.h> /* This is a fixed-size queue. */ @@ -34,4 +35,4 @@ extern BOOL GetWork ( WorkQueue* pq, void** ppw ); extern BOOL FetchWork ( WorkQueue* pq, void** ppw ); extern int SubmitWork ( WorkQueue* pq, void* pw ); -#endif /* __WORKQUEUE_H__ */ +#endif /* WIN32_WORKQUEUE_H */ diff --git a/rts/win32/seh_excn.h b/rts/win32/seh_excn.h index 410d430871..9d67fb405a 100644 --- a/rts/win32/seh_excn.h +++ b/rts/win32/seh_excn.h @@ -1,5 +1,6 @@ -#ifndef __SEH_EXCN_H__ -#define __SEH_EXCN_H__ +#ifndef WIN32_SEH_EXCN_H +#define WIN32_SEH_EXCN_H + #include <stdio.h> #include <stdlib.h> @@ -87,5 +88,5 @@ catchDivZero(struct _EXCEPTION_RECORD*, #error Don't know what sort of Windows system this is #endif -#endif /* __SEH_EXCN_H__ */ +#endif /* WIN32_SEH_EXCN_H */ |