From 2f8824b7743cf21219dc5ed3a70a45f8ad42ba9e Mon Sep 17 00:00:00 2001 From: wez Date: Fri, 30 Apr 2010 21:27:09 +0000 Subject: * allow the sbrk backend to be requested via UMEM_OPTIONS=backend=sbrk, but note that this appears to be broken on non-solaris platforms. * make a safer/better check for number of cpus on linux * use pthread_once to register the forkhandler, as it is possible to call it twice in some scenarios without this protection git-svn-id: https://labs.omniti.com/portableumem/trunk@56 1665872d-e22b-0410-9e5d-a57ad4215e6d --- init_lib.c | 59 +++++++++++++++++++++++++++++++++-------------------------- umem.c | 6 +++++- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/init_lib.c b/init_lib.c index 031c687..d5404a9 100644 --- a/init_lib.c +++ b/init_lib.c @@ -56,28 +56,31 @@ vmem_heap_init(void) { #ifdef _WIN32 vmem_backend = VMEM_BACKEND_MMAP; + (void) vmem_sbrk_arena(NULL, NULL); #else -#if 0 +# if defined(sun) void *handle = dlopen("libmapmalloc.so.1", RTLD_NOLOAD); if (handle != NULL) { -#endif log_message("sbrk backend disabled\n"); vmem_backend = VMEM_BACKEND_MMAP; -#if 0 } -#endif -#endif +# else + if (vmem_backend == 0) { + /* prefer mmap, as sbrk() seems to have problems wither working + * with other allocators or has some Solaris specific assumptions. */ + vmem_backend = VMEM_BACKEND_MMAP; + } +# endif if ((vmem_backend & VMEM_BACKEND_MMAP) != 0) { vmem_backend = VMEM_BACKEND_MMAP; (void) vmem_mmap_arena(NULL, NULL); } else { -#ifndef _WIN32 vmem_backend = VMEM_BACKEND_SBRK; (void) vmem_sbrk_arena(NULL, NULL); -#endif } +#endif } /*ARGSUSED*/ @@ -104,28 +107,32 @@ umem_get_max_ncpus(void) * in /proc/stat. To avoid recursion in the malloc replacement * version of libumem, read /proc/stat into a static buffer. */ - static char proc_stat[8192]; - int fd; - int ncpus = 1; - - fd = open("/proc/stat", O_RDONLY); - if (fd >= 0) { - const ssize_t n = read(fd, proc_stat, sizeof(proc_stat) - 1); - if (n >= 0) { - const char *cur; - const char *next; - - proc_stat[n] = '\0'; - cur = proc_stat; - while (*cur && (next = strstr(cur + 3, "cpu"))) { - cur = next; + static int ncpus = 0; + + if (ncpus == 0) { + char proc_stat[8192]; + int fd; + + ncpus = 1; + fd = open("/proc/stat", O_RDONLY); + if (fd >= 0) { + const ssize_t n = read(fd, proc_stat, sizeof(proc_stat) - 1); + if (n >= 0) { + const char *cur; + const char *next; + + proc_stat[n] = '\0'; + cur = proc_stat; + while (*cur && (next = strstr(cur + 3, "cpu"))) { + cur = next; + } + + if (*cur) + ncpus = atoi(cur + 3) + 1; } - if (*cur) - ncpus = atoi(cur + 3) + 1; + close(fd); } - - close(fd); } return ncpus; diff --git a/umem.c b/umem.c index 064db65..9693eae 100644 --- a/umem.c +++ b/umem.c @@ -621,6 +621,9 @@ static umem_cache_t *umem_alloc_table[UMEM_MAXBUF >> UMEM_ALIGN_SHIFT] = { caddr_t umem_min_stack; caddr_t umem_max_stack; +#ifndef UMEM_STANDALONE +static pthread_once_t umem_forkhandler_once = PTHREAD_ONCE_INIT; +#endif /* * we use the _ versions, since we don't want to be cancelled. @@ -2907,7 +2910,8 @@ umem_startup(caddr_t start, size_t len, size_t pagesize, caddr_t minstack, int idx; /* Standalone doesn't fork */ #else - umem_forkhandler_init(); /* register the fork handler */ + /* register the fork handler */ + (void) pthread_once(&umem_forkhandler_once, umem_forkhandler_init); #endif #ifdef __lint -- cgit v1.2.3