mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
[BZ #5382]
* nscd/nscd.h (NSCD_THREAD_STACKSIZE): Define. * nscd/connections.c (start_threads): Use NSCD_THREAD_STACKSIZE. * nscd/mem.c (gc): Don't allocate arrays on stack if it can overflow it. * sysdeps/unix/sysv/linux/nscd_setup_thread.c (setup_thread): Return zero in case thread library is not NPTL.
This commit is contained in:
@ -1,5 +1,14 @@
|
|||||||
2007-11-22 Ulrich Drepper <drepper@redhat.com>
|
2007-11-22 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
[BZ #5382]
|
||||||
|
* nscd/nscd.h (NSCD_THREAD_STACKSIZE): Define.
|
||||||
|
* nscd/connections.c (start_threads): Use NSCD_THREAD_STACKSIZE.
|
||||||
|
* nscd/mem.c (gc): Don't allocate arrays on stack if it can
|
||||||
|
overflow it.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/nscd_setup_thread.c (setup_thread):
|
||||||
|
Return zero in case thread library is not NPTL.
|
||||||
|
|
||||||
[BZ #5375]
|
[BZ #5375]
|
||||||
* resolv/res_hconf.c (_res_hconf_reorder_addrs): Fix locking when
|
* resolv/res_hconf.c (_res_hconf_reorder_addrs): Fix locking when
|
||||||
initializing interface list.
|
initializing interface list.
|
||||||
|
@ -1840,7 +1840,7 @@ start_threads (void)
|
|||||||
pthread_attr_init (&attr);
|
pthread_attr_init (&attr);
|
||||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||||
/* Use 1MB stacks, twice as much for 64-bit architectures. */
|
/* Use 1MB stacks, twice as much for 64-bit architectures. */
|
||||||
pthread_attr_setstacksize (&attr, 1024 * 1024 * (sizeof (void *) / 4));
|
pthread_attr_setstacksize (&attr, NSCD_THREAD_STACKSIZE);
|
||||||
|
|
||||||
/* We allow less than LASTDB threads only for debugging. */
|
/* We allow less than LASTDB threads only for debugging. */
|
||||||
if (debug_level == 0)
|
if (debug_level == 0)
|
||||||
|
55
nscd/mem.c
55
nscd/mem.c
@ -34,6 +34,11 @@
|
|||||||
#include "nscd.h"
|
#include "nscd.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Wrapper functions with error checking for standard functions. */
|
||||||
|
extern void *xmalloc (size_t n);
|
||||||
|
extern void *xcalloc (size_t n, size_t s);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sort_he (const void *p1, const void *p2)
|
sort_he (const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
@ -69,6 +74,10 @@ sort_he_data (const void *p1, const void *p2)
|
|||||||
#define ALLBITS ((((BITMAP_T) 1) << BITS) - 1)
|
#define ALLBITS ((((BITMAP_T) 1) << BITS) - 1)
|
||||||
#define HIGHBIT (((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
|
static void
|
||||||
markrange (BITMAP_T *mark, ref_t start, size_t len)
|
markrange (BITMAP_T *mark, ref_t start, size_t len)
|
||||||
@ -117,13 +126,43 @@ gc (struct database_dyn *db)
|
|||||||
we have to look at the memory. We use a mark and sweep algorithm
|
we have to look at the memory. We use a mark and sweep algorithm
|
||||||
where the marks are placed in this array. */
|
where the marks are placed in this array. */
|
||||||
assert (db->head->first_free % BLOCK_ALIGN == 0);
|
assert (db->head->first_free % BLOCK_ALIGN == 0);
|
||||||
BITMAP_T mark[(db->head->first_free / BLOCK_ALIGN + BITS - 1) / BITS];
|
|
||||||
memset (mark, '\0', sizeof (mark));
|
BITMAP_T *mark;
|
||||||
|
bool mark_use_malloc;
|
||||||
|
size_t 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)
|
||||||
|
{
|
||||||
|
mark = (BITMAP_T *) alloca (memory_needed);
|
||||||
|
mark_use_malloc = false;
|
||||||
|
memset (mark, '\0', memory_needed);
|
||||||
|
stack_used = memory_needed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mark = (BITMAP_T *) xcalloc (1, memory_needed);
|
||||||
|
mark_use_malloc = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create an array which can hold pointer to all the entries in hash
|
/* Create an array which can hold pointer to all the entries in hash
|
||||||
entries. */
|
entries. */
|
||||||
struct hashentry *he[db->head->nentries];
|
memory_needed = 2 * db->head->nentries * sizeof (struct hashentry *);
|
||||||
struct hashentry *he_data[db->head->nentries];
|
struct hashentry **he;
|
||||||
|
struct hashentry **he_data;
|
||||||
|
bool he_use_malloc;
|
||||||
|
if (stack_used + memory_needed <= MAX_STACK_USE)
|
||||||
|
{
|
||||||
|
he = alloca (db->head->nentries * sizeof (struct hashentry *));
|
||||||
|
he_data = alloca (db->head->nentries * sizeof (struct hashentry *));
|
||||||
|
he_use_malloc = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
he = xmalloc (memory_needed);
|
||||||
|
he_data = &he[db->head->nentries * sizeof (struct hashentry *)];
|
||||||
|
he_use_malloc = true;
|
||||||
|
}
|
||||||
|
|
||||||
size_t cnt = 0;
|
size_t cnt = 0;
|
||||||
for (size_t idx = 0; idx < db->head->module; ++idx)
|
for (size_t idx = 0; idx < db->head->module; ++idx)
|
||||||
@ -455,6 +494,11 @@ gc (struct database_dyn *db)
|
|||||||
out:
|
out:
|
||||||
pthread_mutex_unlock (&db->memlock);
|
pthread_mutex_unlock (&db->memlock);
|
||||||
pthread_rwlock_unlock (&db->lock);
|
pthread_rwlock_unlock (&db->lock);
|
||||||
|
|
||||||
|
if (he_use_malloc)
|
||||||
|
free (he);
|
||||||
|
if (mark_use_malloc)
|
||||||
|
free (mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -481,7 +525,8 @@ mempool_alloc (struct database_dyn *db, size_t len)
|
|||||||
{
|
{
|
||||||
/* Try to resize the database. Grow size of 1/8th. */
|
/* Try to resize the database. Grow size of 1/8th. */
|
||||||
size_t oldtotal = (sizeof (struct database_pers_head)
|
size_t oldtotal = (sizeof (struct database_pers_head)
|
||||||
+ roundup (db->head->module * sizeof (ref_t), ALIGN)
|
+ roundup (db->head->module * sizeof (ref_t),
|
||||||
|
ALIGN)
|
||||||
+ db->head->data_size);
|
+ db->head->data_size);
|
||||||
size_t new_data_size = (db->head->data_size
|
size_t new_data_size = (db->head->data_size
|
||||||
+ MAX (2 * len, db->head->data_size / 8));
|
+ MAX (2 * len, db->head->data_size / 8));
|
||||||
|
@ -55,6 +55,10 @@ typedef enum
|
|||||||
#define RESTART_INTERVAL (60 * 60)
|
#define RESTART_INTERVAL (60 * 60)
|
||||||
|
|
||||||
|
|
||||||
|
/* Stack size for worker threads. */
|
||||||
|
#define NSCD_THREAD_STACKSIZE 1024 * 1024 * (sizeof (void *) / 4)
|
||||||
|
|
||||||
|
|
||||||
/* Structure describing dynamic part of one database. */
|
/* Structure describing dynamic part of one database. */
|
||||||
struct database_dyn
|
struct database_dyn
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ setup_thread (struct database_dyn *db)
|
|||||||
char buf[100];
|
char buf[100];
|
||||||
if (confstr (_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof (buf)) >= sizeof (buf)
|
if (confstr (_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof (buf)) >= sizeof (buf)
|
||||||
|| strncmp (buf, "NPTL", 4) != 0)
|
|| strncmp (buf, "NPTL", 4) != 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
/* Do not try this at home, kids. We play with the SETTID address
|
/* Do not try this at home, kids. We play with the SETTID address
|
||||||
even thought the process is multi-threaded. This can only work
|
even thought the process is multi-threaded. This can only work
|
||||||
|
Reference in New Issue
Block a user