summaryrefslogtreecommitdiff
path: root/nscd/cache.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-04-26 04:15:50 +0000
committerUlrich Drepper <drepper@redhat.com>2003-04-26 04:15:50 +0000
commitc86e6aec55e00afc6aca584b13ce8e64ff305d51 (patch)
tree9ff99e44e223a8ddf051fa116698f59296a389be /nscd/cache.c
parent468777e1d0dbd6cb8bcaee244a954824d5c84167 (diff)
Update.
* nscd/cache.c (cache_search): Keep track of how many chain links we searched and update table statistics. (cache_add): Keep track of how many values are in the table. (prune_cache): Likewise. Keep track of locking success. Print messages about removed entries in separate pass. * nscd/connections.c (handle_request): Don't print debug message here. The caller will do it. Keep track of locking success. (nscd_run): Print debug message. Also print PID of the client process. * nscd/nscd.c (start_time): New variable. (main): Remember start time. * nscd/nscd.h: Declare start_time. (struct database): Add more members for new statistics. * nscd/nscd_stat.c: Add support for sending, receiving, and printing of new statistics.
Diffstat (limited to 'nscd/cache.c')
-rw-r--r--nscd/cache.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/nscd/cache.c b/nscd/cache.c
index 6492092bdd..10b04c3c02 100644
--- a/nscd/cache.c
+++ b/nscd/cache.c
@@ -44,11 +44,14 @@ cache_search (request_type type, void *key, size_t len, struct database *table,
{
unsigned long int hash = __nis_hash (key, len) % table->module;
struct hashentry *work;
+ unsigned long int nsearched = 0;
work = table->array[hash];
while (work != NULL)
{
+ ++nsearched;
+
if (type == work->type && len == work->len
&& memcmp (key, work->key, len) == 0 && work->owner == owner)
{
@@ -58,13 +61,16 @@ cache_search (request_type type, void *key, size_t len, struct database *table,
else
++table->poshit;
- return work;
+ break;
}
work = work->next;
}
- return NULL;
+ if (nsearched > table->maxnsearched)
+ table->maxnsearched = nsearched;
+
+ return work;
}
/* Add a new entry to the cache. The return value is zero if the function
@@ -109,6 +115,12 @@ cache_add (int type, void *key, size_t len, const void *packet, size_t total,
++table->negmiss;
else if (last)
++table->posmiss;
+
+ /* Instead of slowing down the normal process for statistics
+ collection we accept living with some incorrect data. */
+ unsigned long int nentries = ++table->nentries;
+ if (nentries > table->maxnentries)
+ table->maxnentries = nentries;
}
/* Walk through the table and remove all entries which lifetime ended.
@@ -165,10 +177,10 @@ prune_cache (struct database *table, time_t now)
/* We run through the table and find values which are not valid anymore.
- Note that for the initial step, finding the entries to be removed,
- 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. */
+ Note that for the initial step, finding the entries to be removed,
+ 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. */
do
{
struct hashentry *runp = table->array[--cnt];
@@ -195,7 +207,11 @@ prune_cache (struct database *table, time_t now)
/* Now we have to get the write lock since we are about to modify
the table. */
- pthread_rwlock_wrlock (&table->lock);
+ if (__builtin_expect (pthread_rwlock_trywrlock (&table->lock) != 0, 0))
+ {
+ ++table->wrlockdelayed;
+ pthread_rwlock_wrlock (&table->lock);
+ }
while (first <= last)
{
@@ -208,6 +224,7 @@ prune_cache (struct database *table, time_t now)
table->array[first]->dellist = head;
head = table->array[first];
table->array[first] = head->next;
+ --table->nentries;
if (--mark[first] == 0)
break;
}
@@ -221,6 +238,7 @@ prune_cache (struct database *table, time_t now)
head = runp->next;
runp->next = head->next;
--mark[first];
+ --table->nentries;
}
else
runp = runp->next;
@@ -232,29 +250,35 @@ prune_cache (struct database *table, time_t now)
/* It's all done. */
pthread_rwlock_unlock (&table->lock);
- /* And another run to free the data. */
- do
+ /* One extra pass if we do debugging. */
+ if (__builtin_expect (debug_level > 0, 0))
{
- struct hashentry *old = head;
+ struct hashentry *runp = head;
- if (debug_level > 0)
+ while (runp != NULL)
{
char buf[INET6_ADDRSTRLEN];
const char *str;
- if ((old->type == GETHOSTBYADDR || old->type == GETHOSTBYADDRv6)
- && (old->last || old->data == (void *) -1))
+ if (runp->type == GETHOSTBYADDR || runp->type == GETHOSTBYADDRv6)
{
- inet_ntop (old->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
- old->key, buf, sizeof (buf));
+ inet_ntop (runp->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
+ runp->key, buf, sizeof (buf));
str = buf;
}
else
- str = old->last ? old->key : (old->data == (void *) -1
- ? old->key : "???");
+ str = runp->key;
- dbg_log ("remove %s entry \"%s\"", serv2str[old->type], str);
+ dbg_log ("remove %s entry \"%s\"", serv2str[runp->type], str);
+
+ runp = runp->next;
}
+ }
+
+ /* And another run to free the data. */
+ do
+ {
+ struct hashentry *old = head;
/* Free the data structures. */
if (old->data == (void *) -1)