summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Mazon <jmazon+haskell@gmail.com>2020-03-02 21:27:48 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-03-09 16:33:37 -0400
commit7d95260f0b9a91186eb6a99d6235151a22b2c5ae (patch)
treefc81f87fee67ea1de9b92e21477addeed4250c27
parentb8dab057f0730a324b7cb7b74a11152f6b96a889 (diff)
downloadhaskell-7d95260f0b9a91186eb6a99d6235151a22b2c5ae.tar.gz
rts: refactor and comment profile locales
-rw-r--r--rts/ProfHeap.c67
1 files changed, 52 insertions, 15 deletions
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index fd2b32f6d5..85f5a6c741 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -35,6 +35,30 @@
FILE *hp_file;
static char *hp_filename; /* heap profile (hp2ps style) log file */
+/* ------------------------------------------------------------------------
+ * Locales
+ *
+ * The heap profile contains information that is sensitive to the C runtime's
+ * LC_NUMERIC locale settings. By default libc starts in a "C" setting that's
+ * the same everywhere, and the one hp2ps expects. But the program may change
+ * that at runtime. So we change it back when we're writing a sample, and
+ * restore it before yielding back.
+ *
+ * On POSIX.1-2008 systems, this is done with the locale_t opaque type, created
+ * with newlocale() at profiler init, switched to with uselocale() and freed at
+ * exit with freelocale().
+ *
+ * As an exception for Darwin, this comes through the <xlocale.h> header instead
+ * of <locale.h>.
+ *
+ * On Windows, a different _locale_t opaque type does exist, but isn't directly
+ * usable without special-casing all printf() and related calls, which I'm not
+ * motivated to trawl through as I don't even have a Windows box to test on.
+ * (But if you do and are so inclined, be my guest!)
+ * So we just call setlocale(), making it thread-local and restoring the
+ * locale and its thread-locality state on yield.
+ * --------------------------------------------------------------------- */
+
#if defined(mingw32_HOST_OS)
static int prof_locale_per_thread = -1;
static const char *saved_locale = NULL;
@@ -43,6 +67,31 @@ static locale_t prof_locale = 0, saved_locale = 0;
#endif
STATIC_INLINE void
+init_prof_locale( void )
+{
+#if !defined(mingw32_HOST_OS)
+ if (! prof_locale) {
+ prof_locale = newlocale(LC_NUMERIC_MASK, "POSIX", 0);
+ if (! prof_locale) {
+ sysErrorBelch("Couldn't allocate heap profiler locale");
+ /* non-fatal: risk using an unknown locale, but won't crash */
+ }
+ }
+#endif
+}
+
+STATIC_INLINE void
+free_prof_locale( void )
+{
+#if !defined(mingw32_HOST_OS)
+ if (prof_locale) {
+ freelocale(prof_locale);
+ prof_locale = 0;
+ }
+#endif
+}
+
+STATIC_INLINE void
set_prof_locale( void )
{
#if defined(mingw32_HOST_OS)
@@ -64,6 +113,7 @@ restore_locale( void )
uselocale(saved_locale);
#endif
}
+
/* -----------------------------------------------------------------------------
* era stores the current time period. It is the same as the
* number of censuses that have been performed.
@@ -379,12 +429,7 @@ printSample(bool beginSample, StgDouble sampleValue)
void freeHeapProfiling (void)
{
-#if !defined(mingw32_HOST_OS)
- if (prof_locale) {
- freelocale(prof_locale);
- prof_locale = 0;
- }
-#endif
+ free_prof_locale();
}
/* --------------------------------------------------------------------------
@@ -397,15 +442,7 @@ initHeapProfiling(void)
return;
}
-#if !defined(mingw32_HOST_OS)
- if (! prof_locale) {
- prof_locale = newlocale(LC_NUMERIC_MASK, "POSIX", 0);
- if (! prof_locale) {
- sysErrorBelch("Couldn't allocate heap profiler locale");
- /* non-fatal: risk using an unknown locale, but won't crash */
- }
- }
-#endif
+ init_prof_locale();
set_prof_locale();
char *prog;