2007-11-25 Ulrich Drepper <drepper@redhat.com> * nscd/nscd.h (MAX_STACK_USE): Define. * nscd/mem.c (MAX_STACK_USE): Remove definition here. (gc): Initialize stack_used based on allocation in prune_cache. * nscd/cache.c (prune_cache): Use heap for mark array if necessary. Clear array before use. --- libc/nscd/cache.c 14 Nov 2007 15:26:02 -0000 1.33 +++ libc/nscd/cache.c 25 Nov 2007 21:47:35 -0000 1.35 @@ -36,6 +36,10 @@ #include "dbg_log.h" +/* Wrapper functions with error checking for standard functions. */ +extern void *xcalloc (size_t n, size_t s); + + /* Number of times a value is reloaded without being used. UINT_MAX means unlimited. */ unsigned int reload_count = DEFAULT_RELOAD_LIMIT; @@ -278,7 +282,20 @@ prune_cache (struct database_dyn *table, we don't need to get any lock. It is at all timed assured that the linked lists are set up correctly and that no second thread prunes the cache. */ - bool mark[cnt]; + bool *mark; + size_t memory_needed = cnt * sizeof (bool); + bool mark_use_alloca; + if (__builtin_expect (memory_needed <= MAX_STACK_USE, 1)) + { + mark = alloca (cnt * sizeof (bool)); + memset (mark, '\0', memory_needed); + mark_use_alloca = true; + } + else + { + mark = xcalloc (1, memory_needed); + mark_use_alloca = false; + } size_t first = cnt + 1; size_t last = 0; char *const data = table->data; @@ -471,6 +488,9 @@ prune_cache (struct database_dyn *table, } } + if (__builtin_expect (! mark_use_alloca, 0)) + free (mark); + /* Run garbage collection if any entry has been removed or replaced. */ if (any) gc (table); --- libc/nscd/mem.c 23 Nov 2007 06:37:12 -0000 1.11 +++ libc/nscd/mem.c 25 Nov 2007 21:07:14 -0000 1.12 @@ -74,10 +74,6 @@ sort_he_data (const void *p1, const void #define ALLBITS ((((BITMAP_T) 1) << BITS) - 1) #define HIGHBIT (((BITMAP_T) 1) << (BITS - 1)) -/* Maximum size of stack frames we allow the thread to use. We use - 80% of the thread stack size. */ -#define MAX_STACK_USE ((8 * NSCD_THREAD_STACKSIZE) / 10) - static void markrange (BITMAP_T *mark, ref_t start, size_t len) @@ -129,7 +125,11 @@ gc (struct database_dyn *db) BITMAP_T *mark; bool mark_use_malloc; - size_t stack_used = 0; + /* In prune_cache we are also using a dynamically allocated array. + If the array in the caller is too large we have malloc'ed it. */ + size_t stack_used = sizeof (bool) * db->head->module; + if (__builtin_expect (stack_used > MAX_STACK_USE, 0)) + stack_used = 0; size_t memory_needed = ((db->head->first_free / BLOCK_ALIGN + BITS - 1) / BITS) * sizeof (BITMAP_T); if (memory_needed <= MAX_STACK_USE) --- libc/nscd/nscd.h 23 Nov 2007 06:28:41 -0000 1.31 +++ libc/nscd/nscd.h 25 Nov 2007 21:06:58 -0000 1.32 @@ -58,6 +58,10 @@ typedef enum /* Stack size for worker threads. */ #define NSCD_THREAD_STACKSIZE 1024 * 1024 * (sizeof (void *) / 4) +/* Maximum size of stack frames we allow the thread to use. We use + 80% of the thread stack size. */ +#define MAX_STACK_USE ((8 * NSCD_THREAD_STACKSIZE) / 10) + /* Structure describing dynamic part of one database. */ struct database_dyn