1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-05 19:35:52 +03:00

* nscd/cache.c (cache_add): Take additional parameter specifying

whether this is in response of a cache refill.  Check alignment
	of package data.  Revamp waking of pruning thread.
	(prune_cache): Small optimization.
	* nscd/nscd.h: Adjust cache_add prototypes.
	* nscd/aicache.c: Adjust cache_add calls.
	* nscd/grpcache.c: Likewise.
	* nscd/hstcache.c: Likewise.
	* nscd/initgrcache.c: Likewise.
	* nscd/pwdcache.c: Likewise.
	* nscd/servicescache.c: Likewise.
	* nscd/connections.c (restart): Really disable cache use before
	exec attempt.  If it fails, reenable cache.
	(nscd_run_prune): Initialize wakeup_time.  After wakeup, set wakeup
	time to max to be able to notice concurrent cache additions.  Unlock
	prune_lock while performing gc.  Afterwards compute wakeup time with
	current wakeup_time value in mind.
This commit is contained in:
Ulrich Drepper
2008-05-18 21:54:43 +00:00
parent 5811d72b73
commit 528741cb6c
10 changed files with 114 additions and 42 deletions

View File

@@ -1,3 +1,23 @@
2008-05-18 Ulrich Drepper <drepper@redhat.com>
* nscd/cache.c (cache_add): Take additional parameter specifying
whether this is in response of a cache refill. Check alignment
of package data. Revamp waking of pruning thread.
(prune_cache): Small optimization.
* nscd/nscd.h: Adjust cache_add prototypes.
* nscd/aicache.c: Adjust cache_add calls.
* nscd/grpcache.c: Likewise.
* nscd/hstcache.c: Likewise.
* nscd/initgrcache.c: Likewise.
* nscd/pwdcache.c: Likewise.
* nscd/servicescache.c: Likewise.
* nscd/connections.c (restart): Really disable cache use before
exec attempt. If it fails, reenable cache.
(nscd_run_prune): Initialize wakeup_time. After wakeup, set wakeup
time to max to be able to notice concurrent cache additions. Unlock
prune_lock while performing gc. Afterwards compute wakeup time with
current wakeup_time value in mind.
2008-05-17 Ulrich Drepper <drepper@redhat.com> 2008-05-17 Ulrich Drepper <drepper@redhat.com>
* nscd/mem.c (gc): Avoid stack overflow when allocating move list. * nscd/mem.c (gc): Avoid stack overflow when allocating move list.

View File

@@ -558,7 +558,7 @@ next_nip:
pthread_rwlock_rdlock (&db->lock); pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, key_copy, req->key_len, &dataset->head, (void) cache_add (req->type, key_copy, req->key_len, &dataset->head,
true, db, uid); true, db, uid, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);

View File

@@ -135,7 +135,7 @@ cache_search (request_type type, void *key, size_t len,
int int
cache_add (int type, const void *key, size_t len, struct datahead *packet, cache_add (int type, const void *key, size_t len, struct datahead *packet,
bool first, struct database_dyn *table, bool first, struct database_dyn *table,
uid_t owner) uid_t owner, bool prune_wakeup)
{ {
if (__builtin_expect (debug_level >= 2, 0)) if (__builtin_expect (debug_level >= 2, 0))
{ {
@@ -180,6 +180,7 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
assert (newp->key + newp->len <= table->head->first_free); assert (newp->key + newp->len <= table->head->first_free);
newp->owner = owner; newp->owner = owner;
newp->packet = (char *) packet - table->data; newp->packet = (char *) packet - table->data;
assert ((newp->packet & BLOCK_ALIGN_M1) == 0);
/* Put the new entry in the first position. */ /* Put the new entry in the first position. */
do do
@@ -211,19 +212,27 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
(char *) &table->head->array[hash] - (char *) table->head (char *) &table->head->array[hash] - (char *) table->head
+ sizeof (ref_t), MS_ASYNC); + sizeof (ref_t), MS_ASYNC);
/* Perhaps the prune thread for the data is not running in a long /* We do not have to worry about the pruning thread if we are
time. Wake it if necessary. */ re-adding the data since this is done by the pruning thread. We
time_t next_wakeup = table->wakeup_time; also do not have to do anything in case this is not the first
while (next_wakeup + CACHE_PRUNE_INTERVAL > packet->timeout) time the data is entered since different data heads all have the
if (atomic_compare_and_exchange_bool_acq (&table->wakeup_time, same timeout. */
packet->timeout, if (first && prune_wakeup)
next_wakeup) == 0) {
{ /* Perhaps the prune thread for the table is not running in a long
time. Wake it if necessary. */
pthread_mutex_lock (&table->prune_lock);
time_t next_wakeup = table->wakeup_time;
bool do_wakeup = false;
if (next_wakeup > packet->timeout + CACHE_PRUNE_INTERVAL)
{
table->wakeup_time = packet->timeout;
do_wakeup = true;
}
pthread_mutex_unlock (&table->prune_lock);
if (do_wakeup)
pthread_cond_signal (&table->prune_cond); pthread_cond_signal (&table->prune_cond);
break; }
}
else
next_wakeup = table->wakeup_time;
/* Mark the in-flight memory as unused. */ /* Mark the in-flight memory as unused. */
for (enum in_flight idx = 0; idx < IDX_last; ++idx) for (enum in_flight idx = 0; idx < IDX_last; ++idx)
@@ -436,7 +445,8 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
ref_t *old = &table->head->array[first]; ref_t *old = &table->head->array[first];
ref_t run = table->head->array[first]; ref_t run = table->head->array[first];
while (run != ENDREF) assert (run != ENDREF);
do
{ {
struct hashentry *runp = (struct hashentry *) (data + run); struct hashentry *runp = (struct hashentry *) (data + run);
struct datahead *dh struct datahead *dh
@@ -462,6 +472,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
run = runp->next; run = runp->next;
} }
} }
while (run != ENDREF);
} }
++first; ++first;

View File

@@ -1330,11 +1330,14 @@ cannot change to old working directory: %s; disabling paranoia mode"),
} }
/* Synchronize memory. */ /* Synchronize memory. */
int32_t certainly[lastdb];
for (int cnt = 0; cnt < lastdb; ++cnt) for (int cnt = 0; cnt < lastdb; ++cnt)
if (dbs[cnt].enabled) if (dbs[cnt].enabled)
{ {
/* Make sure nobody keeps using the database. */ /* Make sure nobody keeps using the database. */
dbs[cnt].head->timestamp = 0; dbs[cnt].head->timestamp = 0;
certainly[cnt] = dbs[cnt].head->nscd_certainly_running;
dbs[cnt].head->nscd_certainly_running = 0;
if (dbs[cnt].persistent) if (dbs[cnt].persistent)
// XXX async OK? // XXX async OK?
@@ -1357,6 +1360,15 @@ cannot change to old working directory: %s; disabling paranoia mode"),
dbg_log (_("cannot change current working directory to \"/\": %s"), dbg_log (_("cannot change current working directory to \"/\": %s"),
strerror (errno)); strerror (errno));
paranoia = 0; paranoia = 0;
/* Reenable the databases. */
time_t now = time (NULL);
for (int cnt = 0; cnt < lastdb; ++cnt)
if (dbs[cnt].enabled)
{
dbs[cnt].head->timestamp = now;
dbs[cnt].head->nscd_certainly_running = certainly[cnt];
}
} }
@@ -1394,42 +1406,68 @@ nscd_run_prune (void *p)
int dont_need_update = setup_thread (&dbs[my_number]); int dont_need_update = setup_thread (&dbs[my_number]);
time_t now = time (NULL);
/* We are running. */ /* We are running. */
dbs[my_number].head->timestamp = time (NULL); dbs[my_number].head->timestamp = now;
struct timespec prune_ts; struct timespec prune_ts;
if (clock_gettime (timeout_clock, &prune_ts) == -1) if (__builtin_expect (clock_gettime (timeout_clock, &prune_ts) == -1, 0))
/* Should never happen. */ /* Should never happen. */
abort (); abort ();
/* Compute the initial timeout time. Prevent all the timers to go /* Compute the initial timeout time. Prevent all the timers to go
off at the same time by adding a db-based value. */ off at the same time by adding a db-based value. */
prune_ts.tv_sec += CACHE_PRUNE_INTERVAL + my_number; prune_ts.tv_sec += CACHE_PRUNE_INTERVAL + my_number;
dbs[my_number].wakeup_time = now + CACHE_PRUNE_INTERVAL + my_number;
pthread_mutex_lock (&dbs[my_number].prune_lock); pthread_mutex_t *prune_lock = &dbs[my_number].prune_lock;
pthread_cond_t *prune_cond = &dbs[my_number].prune_cond;
pthread_mutex_lock (prune_lock);
while (1) while (1)
{ {
/* Wait, but not forever. */ /* Wait, but not forever. */
int e = pthread_cond_timedwait (&dbs[my_number].prune_cond, int e = pthread_cond_timedwait (prune_cond, prune_lock, &prune_ts);
&dbs[my_number].prune_lock, assert (__builtin_expect (e == 0 || e == ETIMEDOUT, 1));
&prune_ts);
assert (e == 0 || e == ETIMEDOUT);
time_t next_wait; time_t next_wait;
time_t now = time (NULL); now = time (NULL);
if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time) if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time)
{ {
/* We will determine the new timout values based on the
cache content. Should there be concurrent additions to
the cache which are not accounted for in the cache
pruning we want to know about it. Therefore set the
timeout to the maximum. It will be descreased when adding
new entries to the cache, if necessary. */
if (sizeof (time_t) == sizeof (long int))
dbs[my_number].wakeup_time = LONG_MAX;
else
dbs[my_number].wakeup_time = INT_MAX;
pthread_mutex_unlock (prune_lock);
next_wait = prune_cache (&dbs[my_number], now, -1); next_wait = prune_cache (&dbs[my_number], now, -1);
next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL); next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL);
/* If clients cannot determine for sure whether nscd is running /* If clients cannot determine for sure whether nscd is running
we need to wake up occasionally to update the timestamp. we need to wake up occasionally to update the timestamp.
Wait 90% of the update period. */ Wait 90% of the update period. */
#define UPDATE_MAPPING_TIMEOUT (MAPPING_TIMEOUT * 9 / 10) #define UPDATE_MAPPING_TIMEOUT (MAPPING_TIMEOUT * 9 / 10)
if (__builtin_expect (! dont_need_update, 0)) if (__builtin_expect (! dont_need_update, 0))
next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait); {
next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
dbs[my_number].head->timestamp = now;
}
pthread_mutex_lock (prune_lock);
/* Make it known when we will wake up again. */ /* Make it known when we will wake up again. */
dbs[my_number].wakeup_time = now + next_wait; if (now + next_wait < dbs[my_number].wakeup_time)
dbs[my_number].wakeup_time = now + next_wait;
else
next_wait = dbs[my_number].wakeup_time - now;
} }
else else
/* The cache was just pruned. Do not do it again now. Just /* The cache was just pruned. Do not do it again now. Just

View File

@@ -147,7 +147,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock); pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, &dataset->strdata, req->key_len, (void) cache_add (req->type, &dataset->strdata, req->key_len,
&dataset->head, true, db, owner); &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);
@@ -353,7 +353,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
if (req->type == GETGRBYGID) if (req->type == GETGRBYGID)
{ {
if (cache_add (GETGRBYGID, cp, key_offset, &dataset->head, true, if (cache_add (GETGRBYGID, cp, key_offset, &dataset->head, true,
db, owner) < 0) db, owner, he == NULL) < 0)
goto out; goto out;
first = false; first = false;
@@ -362,7 +362,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
else if (strcmp (key_copy, gr_name) != 0) else if (strcmp (key_copy, gr_name) != 0)
{ {
if (cache_add (GETGRBYNAME, key_copy, key_len + 1, if (cache_add (GETGRBYNAME, key_copy, key_len + 1,
&dataset->head, true, db, owner) < 0) &dataset->head, true, db, owner, he == NULL) < 0)
goto out; goto out;
first = false; first = false;
@@ -372,12 +372,13 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
if ((req->type == GETGRBYNAME || db->propagate) if ((req->type == GETGRBYNAME || db->propagate)
&& __builtin_expect (cache_add (GETGRBYNAME, gr_name, && __builtin_expect (cache_add (GETGRBYNAME, gr_name,
gr_name_len, gr_name_len,
&dataset->head, first, db, owner) &dataset->head, first, db, owner,
he == NULL)
== 0, 1)) == 0, 1))
{ {
if (req->type == GETGRBYNAME && db->propagate) if (req->type == GETGRBYNAME && db->propagate)
(void) cache_add (GETGRBYGID, cp, key_offset, &dataset->head, (void) cache_add (GETGRBYGID, cp, key_offset, &dataset->head,
false, db, owner); false, db, owner, false);
} }
out: out:

View File

@@ -156,7 +156,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock); pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, &dataset->strdata, req->key_len, (void) cache_add (req->type, &dataset->strdata, req->key_len,
&dataset->head, true, db, owner); &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);
@@ -408,7 +408,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
|| req->type == GETHOSTBYADDRv6); || req->type == GETHOSTBYADDRv6);
(void) cache_add (req->type, key_copy, req->key_len, (void) cache_add (req->type, key_copy, req->key_len,
&dataset->head, true, db, owner); &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);
} }

View File

@@ -231,7 +231,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock); pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, key_copy, req->key_len, (void) cache_add (req->type, key_copy, req->key_len,
&dataset->head, true, db, uid); &dataset->head, true, db, uid, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);
@@ -398,7 +398,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock); pthread_rwlock_rdlock (&db->lock);
(void) cache_add (INITGROUPS, cp, req->key_len, &dataset->head, true, (void) cache_add (INITGROUPS, cp, req->key_len, &dataset->head, true,
db, uid); db, uid, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);
} }

View File

@@ -231,7 +231,8 @@ extern struct datahead *cache_search (request_type, void *key, size_t len,
uid_t owner); uid_t owner);
extern int cache_add (int type, const void *key, size_t len, extern int cache_add (int type, const void *key, size_t len,
struct datahead *packet, bool first, struct datahead *packet, bool first,
struct database_dyn *table, uid_t owner); struct database_dyn *table, uid_t owner,
bool prune_wakeup);
extern time_t prune_cache (struct database_dyn *table, time_t now, int fd); extern time_t prune_cache (struct database_dyn *table, time_t now, int fd);
/* pwdcache.c */ /* pwdcache.c */

View File

@@ -154,7 +154,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock); pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, key_copy, req->key_len, (void) cache_add (req->type, key_copy, req->key_len,
&dataset->head, true, db, owner); &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);
@@ -348,7 +348,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
if (req->type == GETPWBYUID) if (req->type == GETPWBYUID)
{ {
if (cache_add (GETPWBYUID, cp, key_offset, &dataset->head, true, if (cache_add (GETPWBYUID, cp, key_offset, &dataset->head, true,
db, owner) < 0) db, owner, he == NULL) < 0)
goto out; goto out;
first = false; first = false;
@@ -357,7 +357,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
else if (strcmp (key_copy, dataset->strdata) != 0) else if (strcmp (key_copy, dataset->strdata) != 0)
{ {
if (cache_add (GETPWBYNAME, key_copy, key_len + 1, if (cache_add (GETPWBYNAME, key_copy, key_len + 1,
&dataset->head, true, db, owner) < 0) &dataset->head, true, db, owner, he == NULL) < 0)
goto out; goto out;
first = false; first = false;
@@ -367,11 +367,12 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
if ((req->type == GETPWBYNAME || db->propagate) if ((req->type == GETPWBYNAME || db->propagate)
&& __builtin_expect (cache_add (GETPWBYNAME, dataset->strdata, && __builtin_expect (cache_add (GETPWBYNAME, dataset->strdata,
pw_name_len, &dataset->head, pw_name_len, &dataset->head,
first, db, owner) == 0, 1)) first, db, owner, he == NULL)
== 0, 1))
{ {
if (req->type == GETPWBYNAME && db->propagate) if (req->type == GETPWBYNAME && db->propagate)
(void) cache_add (GETPWBYUID, cp, key_offset, &dataset->head, (void) cache_add (GETPWBYUID, cp, key_offset, &dataset->head,
false, db, owner); false, db, owner, false);
} }
out: out:

View File

@@ -137,7 +137,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock); pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, &dataset->strdata, req->key_len, (void) cache_add (req->type, &dataset->strdata, req->key_len,
&dataset->head, true, db, owner); &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);
@@ -331,7 +331,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
pthread_rwlock_rdlock (&db->lock); pthread_rwlock_rdlock (&db->lock);
(void) cache_add (req->type, key_copy, req->key_len, (void) cache_add (req->type, key_copy, req->key_len,
&dataset->head, true, db, owner); &dataset->head, true, db, owner, he == NULL);
pthread_rwlock_unlock (&db->lock); pthread_rwlock_unlock (&db->lock);
} }