X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FRtsUtils.c;h=0123531e27ab3a8bdeed2607e852e065ae29898f;hp=9f50e3a770019ab82aa31a2351380c25a5bd143b;hb=842e9d6628a27cf1f420d53f6a5901935dc50c54;hpb=d526504719676871376324858fe2073aa2011424 diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c index 9f50e3a..0123531 100644 --- a/rts/RtsUtils.c +++ b/rts/RtsUtils.c @@ -18,6 +18,13 @@ #include #endif +/* HACK: On Mac OS X 10.4 (at least), time.h doesn't declare ctime_r with + * _POSIX_C_SOURCE. If this is the case, we declare it ourselves. + */ +#if HAVE_CTIME_R && !HAVE_DECL_CTIME_R +extern char *ctime_r(const time_t *, char *); +#endif + #ifdef HAVE_FCNTL_H #include #endif @@ -86,51 +93,94 @@ initAllocator(void) void shutdownAllocator(void) { + Allocated *prev, *a; + + if (allocs == NULL) { + barf("Allocator shutdown requested, but not initialised!"); + } + #ifdef THREADED_RTS closeMutex(&allocator_mutex); #endif + + prev = allocs; + while (1) { + a = prev->next; + free(prev); + if (a == NULL) return; + IF_DEBUG(sanity, + debugBelch("Warning: %p still allocated at shutdown\n", + a->addr);) + prev = a; + } } -static void allocate(void *addr, size_t len) { +static void addAllocation(void *addr, size_t len) { Allocated *a; size_t alloc_size; - alloc_size = sizeof(Allocated); - if ((a = (Allocated *) malloc(alloc_size)) == NULL) { - /* don't fflush(stdout); WORKAROUND bug in Linux glibc */ - MallocFailHook((W_) alloc_size, "creating info for debugging allocator"); - stg_exit(EXIT_INTERNAL_ERROR); + if (allocs != NULL) { + alloc_size = sizeof(Allocated); + if ((a = (Allocated *) malloc(alloc_size)) == NULL) { + /* don't fflush(stdout); WORKAROUND bug in Linux glibc */ + MallocFailHook((W_) alloc_size, + "creating info for debugging allocator"); + stg_exit(EXIT_INTERNAL_ERROR); + } + a->addr = addr; + a->len = len; + ACQUIRE_LOCK(&allocator_mutex); + a->next = allocs->next; + allocs->next = a; + RELEASE_LOCK(&allocator_mutex); + } + else { + /* This doesn't actually help as we haven't looked at the flags + * at the time that it matters (while running constructors) */ + IF_DEBUG(sanity, + debugBelch("Ignoring allocation %p %zd as allocs is NULL\n", + addr, len);) } - a->addr = addr; - a->len = len; - ACQUIRE_LOCK(&allocator_mutex); - a->next = allocs->next; - allocs->next = a; - RELEASE_LOCK(&allocator_mutex); } -static void deallocate(void *addr) { +static void removeAllocation(void *addr, int overwrite_with_aa) { Allocated *prev, *a; if (addr == NULL) { barf("Freeing NULL!"); } - ACQUIRE_LOCK(&allocator_mutex); - prev = allocs; - a = prev->next; - while (a != NULL) { - if (a->addr == addr) { - prev->next = a->next; - memset(addr, 0xaa, a->len); - free(a); - RELEASE_LOCK(&allocator_mutex); - return; + if (allocs != NULL) { + ACQUIRE_LOCK(&allocator_mutex); + prev = allocs; + a = prev->next; + while (a != NULL) { + if (a->addr == addr) { + prev->next = a->next; + if (overwrite_with_aa) { + memset(addr, 0xaa, a->len); + } + free(a); + RELEASE_LOCK(&allocator_mutex); + return; + } + prev = a; + a = a->next; } - prev = a; - a = a->next; + /* We would like to barf here, but we can't as conc021 + * allocates some stuff in a constructor which then gets freed + * during hs_exit */ + /* barf("Freeing non-allocated memory at %p", addr); */ + IF_DEBUG(sanity, + debugBelch("Warning: Freeing non-allocated memory at %p\n", + addr);) + RELEASE_LOCK(&allocator_mutex); + } + else { + IF_DEBUG(sanity, + debugBelch("Ignoring free of %p as allocs is NULL\n", + addr);) } - barf("Freeing non-allocated memory at %p", addr); } #endif @@ -151,7 +201,7 @@ stgMallocBytes (int n, char *msg) stg_exit(EXIT_INTERNAL_ERROR); } #if defined(DEBUG) - allocate(space, n2); + addAllocation(space, n2); #endif return space; } @@ -169,8 +219,8 @@ stgReallocBytes (void *p, int n, char *msg) stg_exit(EXIT_INTERNAL_ERROR); } #if defined(DEBUG) - deallocate(p); - allocate(space, n2); + removeAllocation(p, 0); + addAllocation(space, n2); #endif return space; } @@ -186,7 +236,7 @@ stgCallocBytes (int n, int m, char *msg) stg_exit(EXIT_INTERNAL_ERROR); } #if defined(DEBUG) - allocate(space, (size_t) n * (size_t) m); + addAllocation(space, (size_t) n * (size_t) m); #endif return space; } @@ -198,7 +248,7 @@ void stgFree(void* p) { #if defined(DEBUG) - deallocate(p); + removeAllocation(p, 1); #endif free(p); } @@ -255,14 +305,14 @@ nat stg_strlen(char *s) ToDo: put this somewhere sensible. ------------------------------------------------------------------------- */ -static I_ __GenSymCounter = 0; +static HsInt __GenSymCounter = 0; -I_ +HsInt genSymZh(void) { return(__GenSymCounter++); } -I_ +HsInt resetGenSymZh(void) /* it's your funeral */ { __GenSymCounter=0; @@ -273,7 +323,6 @@ resetGenSymZh(void) /* it's your funeral */ Get the current time as a string. Used in profiling reports. -------------------------------------------------------------------------- */ -#if defined(PROFILING) || defined(DEBUG) || defined(PAR) || defined(GRAN) char * time_str(void) { @@ -292,7 +341,6 @@ time_str(void) } return nowstr; } -#endif /* ----------------------------------------------------------------------------- * Reset a file handle to blocking mode. We do this for the standard @@ -419,3 +467,23 @@ int genericRaise(int sig) { return raise(sig); #endif } + +static void mkRtsInfoPair(char *key, char *val) { + /* XXX should check for "s, \s etc in key and val */ + printf(" ,(\"%s\", \"%s\")\n", key, val); +} + +void printRtsInfo(void) { + /* The first entry is just a hack to make it easy to get the + * commas right */ + printf(" [(\"GHC RTS\", \"Yes\")\n"); + mkRtsInfoPair("GHC version", ProjectVersion); + mkRtsInfoPair("RTS way", RtsWay); + mkRtsInfoPair("Host platform", HostPlatform); + mkRtsInfoPair("Build platform", BuildPlatform); + mkRtsInfoPair("Target platform", TargetPlatform); + mkRtsInfoPair("Compiler unregisterised", GhcUnregisterised); + mkRtsInfoPair("Tables next to code", GhcEnableTablesNextToCode); + printf(" ]\n"); +} +