X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FRtsStartup.c;h=0ce17fe16f10265fb5f4de7ab89da7cf2122af31;hp=08debc0c8c75aadfa8fd4243f78066f2c1388385;hb=8604da0136707cc14845d14a88c2272fe576b6d0;hpb=b33fa57b919b0b315a64662b72203de68958e0a4 diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 08debc0..0ce17fe 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -6,18 +6,20 @@ * * ---------------------------------------------------------------------------*/ -#include "PosixSource.h" +// PAPI uses caddr_t, which is not POSIX +// #include "PosixSource.h" + #include "Rts.h" #include "RtsAPI.h" #include "RtsUtils.h" #include "RtsFlags.h" #include "OSThreads.h" -#include "Storage.h" /* initStorage, exitStorage */ #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" @@ -31,13 +33,15 @@ #include "RtsTypeable.h" #include "Stable.h" #include "Hpc.h" +#include "FileLock.h" #if defined(RTS_GTK_FRONTPANEL) #include "FrontPanel.h" #endif -#if defined(PROFILING) || defined(DEBUG) # include "Profiling.h" + +#if defined(PROFILING) # include "ProfHeap.h" # include "RetainerProfile.h" #endif @@ -55,7 +59,7 @@ # include "LLC.h" #endif -#if defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) && !defined(THREADED_RTS) #include "win32/AsyncIO.h" #endif @@ -68,6 +72,10 @@ #include #endif +#if USE_PAPI +#include "Papi.h" +#endif + // Count of how many outstanding hs_init()s there have been. static int hs_init_count = 0; @@ -132,7 +140,13 @@ hs_init(int *argc, char **argv[]) return; } - /* The very first thing we do is grab the start time...just in case we're +#if defined(DEBUG) + /* Start off by initialising the allocator debugging so we can + * use it anywhere */ + initAllocator(); +#endif + + /* Next we do is grab the start time...just in case we're * collecting timing statistics. */ stat_startInit(); @@ -153,7 +167,32 @@ hs_init(int *argc, char **argv[]) argv++; argc--; #endif + /* Initialise the performance tracking library */ +#ifdef USE_PAPI + { + int ver; + if ((ver = PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT) { + if (ver > 0) { + errorBelch("PAPI_library_init: wrong version: %x", ver); + stg_exit(EXIT_FAILURE); + } else { + sysErrorBelch("PAPI_library_init"); + stg_exit(EXIT_FAILURE); + } + } + } +#ifdef THREADED_RTS + { + int err; + if ((err = PAPI_thread_init(osThreadId)) < 0) { + barf("PAPI_thread_init: %d",err); + } + } +#endif +#endif + /* Set the RTS flags to default values. */ + initRtsFlagsDefaults(); /* Call the user hook to reset defaults, if present */ @@ -161,6 +200,7 @@ hs_init(int *argc, char **argv[]) /* Parse the flags, separating the RTS flags from the programs args */ if (argc != NULL && argv != NULL) { + setFullProgArgv(*argc,*argv); setupRtsFlags(argc, *argv, &rts_argc, rts_argv); setProgArgv(*argc,*argv); } @@ -175,9 +215,6 @@ hs_init(int *argc, char **argv[]) synchroniseSystem(); // calls initParallelSystem etc #endif /* PAR */ - /* Perform initialisation of adjustor thunk layer. */ - initAdjustor(); - /* initialise scheduler data structures (needs to be done before * initStorage()). */ @@ -202,29 +239,35 @@ hs_init(int *argc, char **argv[]) /* initialise the shared Typeable store */ initTypeableStore(); + /* initialise file locking, if necessary */ +#if !defined(mingw32_HOST_OS) + initFileLocking(); +#endif + #if defined(DEBUG) /* initialise thread label table (tso->char*) */ initThreadLabelTable(); #endif -#if defined(PROFILING) || defined(DEBUG) initProfiling1(); -#endif /* start the virtual timer 'subsystem'. */ + initTimer(); startTimer(); /* Initialise the stats department */ initStats(); #if defined(RTS_USER_SIGNALS) - /* Initialise the user signal handler set */ - initUserSignals(); - /* Set up handler to run on SIGINT, etc. */ - initDefaultHandlers(); + if (RtsFlags.MiscFlags.install_signal_handlers) { + /* Initialise the user signal handler set */ + initUserSignals(); + /* Set up handler to run on SIGINT, etc. */ + initDefaultHandlers(); + } #endif -#if defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) && !defined(THREADED_RTS) startupAsyncIO(); #endif @@ -238,10 +281,6 @@ hs_init(int *argc, char **argv[]) x86_init_fpu(); #endif -#if defined(THREADED_RTS) && !defined(mingw32_HOST_OS) - ioManagerStart(); -#endif - /* Record initialization times */ stat_endInit(); } @@ -314,19 +353,35 @@ hs_add_root(void (*init_root)(void)) startupHpc(); -#if defined(PROFILING) || defined(DEBUG) // This must be done after module initialisation. // ToDo: make this work in the presence of multiple hs_add_root()s. initProfiling2(); + + // ditto. +#if defined(THREADED_RTS) + ioManagerStart(); #endif } -/* ----------------------------------------------------------------------------- - Shutting down the RTS - -------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- + * Shutting down the RTS + * + * The wait_foreign parameter means: + * True ==> wait for any threads doing foreign calls now. + * False ==> threads doing foreign calls may return in the + * future, but will immediately block on a mutex. + * (capability->lock). + * + * If this RTS is a DLL that we're about to unload, then you want + * safe=True, otherwise the thread might return to code that has been + * unloaded. If this is a standalone program that is about to exit, + * then you can get away with safe=False, which is better because we + * won't hang on exit if there is a blocked foreign call outstanding. + * + ------------------------------------------------------------------------- */ -void -hs_exit(void) +static void +hs_exit_(rtsBool wait_foreign) { if (hs_init_count <= 0) { errorBelch("warning: too many hs_exit()s"); @@ -341,12 +396,18 @@ hs_exit(void) /* start timing the shutdown */ stat_startExit(); -#if defined(THREADED_RTS) && !defined(mingw32_HOST_OS) +#if defined(RTS_USER_SIGNALS) + if (RtsFlags.MiscFlags.install_signal_handlers) { + freeSignalHandlers(); + } +#endif + +#if defined(THREADED_RTS) ioManagerDie(); #endif /* stop all running tasks */ - exitScheduler(); + exitScheduler(wait_foreign); #if defined(GRAN) /* end_gr_simulation prints global stats if requested -- HWL */ @@ -356,7 +417,8 @@ hs_exit(void) /* stop the ticker */ stopTimer(); - + exitTimer(); + /* reset the standard file descriptors to blocking mode */ resetNonBlockingFd(0); resetNonBlockingFd(1); @@ -401,14 +463,24 @@ hs_exit(void) // also outputs the stats (+RTS -s) info. exitStorage(); + /* free the tasks */ + freeScheduler(); + /* free shared Typeable store */ exitTypeableStore(); - /* initialise the stable pointer table */ + /* free file locking tables, if necessary */ +#if !defined(mingw32_HOST_OS) + freeFileLocking(); +#endif + + /* free the stable pointer table */ exitStablePtrTable(); - /* free hash table storage */ - exitHashTable(); +#if defined(DEBUG) + /* free the thread label table */ + freeThreadLabelTable(); +#endif #ifdef RTS_GTK_FRONTPANEL if (RtsFlags.GcFlags.frontpanel) { @@ -420,27 +492,43 @@ hs_exit(void) reportCCSProfiling(); #endif -#if defined(PROFILING) || defined(DEBUG) endProfiling(); -#endif + freeProfiling1(); #ifdef PROFILING // Originally, this was in report_ccs_profiling(). Now, retainer // profiling might tack some extra stuff on to the end of this file // during endProfiling(). - fclose(prof_file); + if (prof_file != NULL) fclose(prof_file); #endif #if defined(TICKY_TICKY) if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo(); #endif -#if defined(mingw32_HOST_OS) - shutdownAsyncIO(); +#if defined(mingw32_HOST_OS) && !defined(THREADED_RTS) + shutdownAsyncIO(wait_foreign); #endif - // Finally, free all our storage. + /* free hash table storage */ + exitHashTable(); + + // Finally, free all our storage freeStorage(); + +#if defined(DEBUG) + /* and shut down the allocator debugging */ + shutdownAllocator(); +#endif + +} + +// The real hs_exit(): +void +hs_exit(void) +{ + hs_exit_(rtsTrue); + // be safe; this might be a DLL } // Compatibility interfaces @@ -455,7 +543,8 @@ shutdownHaskellAndExit(int n) { if (hs_init_count == 1) { OnExitHook(); - hs_exit(); + hs_exit_(rtsFalse); + // we're about to exit(), no need to wait for foreign calls to return. #if defined(PAR) /* really exit (stg_exit() would call shutdownParallelSystem() again) */ exit(n);