From ad119a80f2628925b289667c8de44e2ca9e08818 Mon Sep 17 00:00:00 2001 From: Chris Jefferson Date: Wed, 25 Oct 2017 09:45:00 +0100 Subject: [PATCH] Add command line option to enable memory profiling at startup --- hpcgap/lib/system.g | 2 ++ lib/system.g | 2 ++ src/profile.c | 28 +++++++++++------- src/system.c | 70 ++++++++++++++++++++++++++------------------- 4 files changed, 63 insertions(+), 39 deletions(-) diff --git a/hpcgap/lib/system.g b/hpcgap/lib/system.g index e4e05359b48..347ce8d00a8 100644 --- a/hpcgap/lib/system.g +++ b/hpcgap/lib/system.g @@ -105,6 +105,8 @@ BIND_GLOBAL( "GAPInfo", AtomicRecord(rec( rec( short := "z", default := "20" ), rec( long := "prof", default := "", arg := "", help := [ "Run ProfileLineByLine() on GAP start"] ), + rec( long := "memprof", default := "", arg := "", + help := [ "Run ProfileLineByLine() with recordMem := true on GAP start"] ), rec( long := "cover", default := "", arg := "", help := [ "Run CoverageLineByLine() on GAP start"] ), ], diff --git a/lib/system.g b/lib/system.g index 422b84fa61c..a594fd1100f 100644 --- a/lib/system.g +++ b/lib/system.g @@ -104,6 +104,8 @@ BIND_GLOBAL( "GAPInfo", rec( rec( short := "z", default := "20" ), rec( long := "prof", default := "", arg := "", help := [ "Run ProfileLineByLine() on GAP start"] ), + rec( long := "memprof", default := "", arg := "", + help := [ "Run ProfileLineByLine() with recordMem := true on GAP start"] ), rec( long := "cover", default := "", arg := "", help := [ "Run CoverageLineByLine() on GAP start"] ), ], diff --git a/src/profile.c b/src/profile.c index 937c87a20da..f6b9681c68a 100644 --- a/src/profile.c +++ b/src/profile.c @@ -462,7 +462,7 @@ struct InterpreterHooks profileHooks = { "line-by-line profiling"}; -void enableAtStartup(char* filename, Int repeats) +void enableAtStartup(char * filename, Int repeats, TickMethod tickMethod) { if(profileState_Active) { fprintf(stderr, "-P or -C can only be passed once\n"); @@ -485,14 +485,8 @@ void enableAtStartup(char* filename, Int repeats) #ifdef HPCGAP profileState.profiledThread = TLS(threadID); #endif + profileState.tickMethod = tickMethod; profileState.lastNotOutputted.line = -1; -#ifdef HAVE_GETTIMEOFDAY - profileState.tickMethod = Tick_WallTime; -#else -#ifdef HAVE_GETRUSAGE - profileState.tickMethod = Tick_CPUTime; -#endif -#endif profileState.lastOutputtedTime = getTicks(); outputVersionInfo(); @@ -503,7 +497,7 @@ void enableAtStartup(char* filename, Int repeats) // we quit straight away. Int enableCodeCoverageAtStartup( Char **argv, void * dummy) { - enableAtStartup(argv[0], 0); + enableAtStartup(argv[0], 0, Tick_Mem); return 1; } @@ -512,7 +506,21 @@ Int enableCodeCoverageAtStartup( Char **argv, void * dummy) // we quit straight away. Int enableProfilingAtStartup( Char **argv, void * dummy) { - enableAtStartup(argv[0], 1); + TickMethod tickMethod = Tick_WallTime; +#ifdef HAVE_GETTIMEOFDAY + tickMethod = Tick_WallTime; +#else +#ifdef HAVE_GETRUSAGE + tickMethod = Tick_CPUTime; +#endif +#endif + enableAtStartup(argv[0], 1, tickMethod); + return 1; +} + +Int enableMemoryProfilingAtStartup(Char ** argv, void * dummy) +{ + enableAtStartup(argv[0], 1, Tick_Mem); return 1; } diff --git a/src/system.c b/src/system.c index 3a040c9857c..e2f08427515 100644 --- a/src/system.c +++ b/src/system.c @@ -73,6 +73,7 @@ ** of the GAP type system */ Int enableProfilingAtStartup( Char **argv, void * dummy); +Int enableMemoryProfilingAtStartup(Char ** argv, void * dummy); Int enableCodeCoverageAtStartup( Char **argv, void * dummy); /**************************************************************************** @@ -1707,37 +1708,48 @@ static Int preAllocAmount; /* These options must be kept in sync with those in system.g, so the help output is correct */ struct optInfo options[] = { - { 'B', "architecture", storeString, &SyArchitecture, 1}, /* default architecture needs to be passed from kernel - to library. Might be needed for autoload of compiled files */ - { 'C', "", processCompilerArgs, 0, 4}, /* must handle in kernel */ - { 'D', "debug-loading", toggle, &SyDebugLoading, 0}, /* must handle in kernel */ - { 'K', "maximal-workspace", storeMemory2, &SyStorKill, 1}, /* could handle from library with new interface */ - { 'L', "", storeString, &SyRestoring, 1}, /* must be handled in kernel */ - { 'M', "", toggle, &SyUseModule, 0}, /* must be handled in kernel */ - { 'R', "", unsetString, &SyRestoring, 0}, /* kernel */ - { 'a', "", storeMemory, &preAllocAmount, 1 }, /* kernel -- is this still useful */ - { 'e', "", toggle, &SyCTRD, 0 }, /* kernel */ - { 'f', "", forceLineEditing, (void *)2, 0 }, /* probably library now */ - { 'E', "", toggle, &SyUseReadline, 0 }, /* kernel */ - { 'l', "roots", setGapRootPath, 0, 1}, /* kernel */ - { 'm', "", storeMemory2, &SyStorMin, 1 }, /* kernel */ - { 'r', "", toggle, &IgnoreGapRC, 0 }, /* kernel */ - { 's', "", storeMemory, &SyAllocPool, 1 }, /* kernel */ - { 'n', "", forceLineEditing, 0, 0}, /* prob library */ - { 'o', "", storeMemory2, &SyStorMax, 1 }, /* library with new interface */ - { 'p', "", toggle, &SyWindow, 0 }, /* ?? */ - { 'q', "", toggle, &SyQuiet, 0 }, /* ?? */ + { 'B', "architecture", storeString, &SyArchitecture, + 1 }, /* default architecture needs to be passed from kernel + to library. Might be needed for autoload of compiled files */ + { 'C', "", processCompilerArgs, 0, 4 }, /* must handle in kernel */ + { 'D', "debug-loading", toggle, &SyDebugLoading, + 0 }, /* must handle in kernel */ + { 'K', "maximal-workspace", storeMemory2, &SyStorKill, + 1 }, /* could handle from library with new interface */ + { 'L', "", storeString, &SyRestoring, 1 }, /* must be handled in kernel */ + { 'M', "", toggle, &SyUseModule, 0 }, /* must be handled in kernel */ + { 'R', "", unsetString, &SyRestoring, 0 }, /* kernel */ + { 'a', "", storeMemory, &preAllocAmount, + 1 }, /* kernel -- is this still useful */ + { 'e', "", toggle, &SyCTRD, 0 }, /* kernel */ + { 'f', "", forceLineEditing, (void *)2, 0 }, /* probably library now */ + { 'E', "", toggle, &SyUseReadline, 0 }, /* kernel */ + { 'l', "roots", setGapRootPath, 0, 1 }, /* kernel */ + { 'm', "", storeMemory2, &SyStorMin, 1 }, /* kernel */ + { 'r', "", toggle, &IgnoreGapRC, 0 }, /* kernel */ + { 's', "", storeMemory, &SyAllocPool, 1 }, /* kernel */ + { 'n', "", forceLineEditing, 0, 0 }, /* prob library */ + { 'o', "", storeMemory2, &SyStorMax, 1 }, /* library with new interface */ + { 'p', "", toggle, &SyWindow, 0 }, /* ?? */ + { 'q', "", toggle, &SyQuiet, 0 }, /* ?? */ #ifdef HPCGAP - { 'S', "", toggle, &ThreadUI, 0 }, /* Thread UI */ - { 'Z', "", toggle, &DeadlockCheck, 0 }, /* Thread UI */ - { 'P', "", storePosInteger, &SyNumProcessors, 1 }, /* Thread UI */ - { 'G', "", storePosInteger, &SyNumGCThreads, 1 }, /* Thread UI */ + { 'S', "", toggle, &ThreadUI, 0 }, /* Thread UI */ + { 'Z', "", toggle, &DeadlockCheck, 0 }, /* Thread UI */ + { 'P', "", storePosInteger, &SyNumProcessors, 1 }, /* Thread UI */ + { 'G', "", storePosInteger, &SyNumGCThreads, 1 }, /* Thread UI */ #endif - /* The following three options must be handled in the kernel so they happen early enough */ - { 0 , "prof", enableProfilingAtStartup, 0, 1}, /* enable profiling at startup */ - { 0 , "cover", enableCodeCoverageAtStartup, 0, 1}, /* enable code coverage at startup */ - { 0 , "quitonbreak", toggle, &SyQuitOnBreak, 0}, /* Quit GAP if we enter the break loop */ - { 0, "", 0, 0, 0}}; + /* The following three options must be handled in the kernel so they + happen early enough */ + { 0, "prof", enableProfilingAtStartup, 0, + 1 }, /* enable profiling at startup */ + { 0, "memprof", enableMemoryProfilingAtStartup, 0, + 1 }, /* enable memory profiling at startup */ + { 0, "cover", enableCodeCoverageAtStartup, 0, + 1 }, /* enable code coverage at startup */ + { 0, "quitonbreak", toggle, &SyQuitOnBreak, + 0 }, /* Quit GAP if we enter the break loop */ + { 0, "", 0, 0, 0 } +}; Char ** SyOriginalArgv;