summaryrefslogtreecommitdiff
path: root/file_io/netware/filestat.c
diff options
context:
space:
mode:
authorbnicholes <bnicholes@13f79535-47bb-0310-9956-ffa450edef68>2002-06-26 22:01:02 +0000
committerbnicholes <bnicholes@13f79535-47bb-0310-9956-ffa450edef68>2002-06-26 22:01:02 +0000
commit333ee0ee85c6e648161cc755ffebf1215f640a36 (patch)
tree936b0ef4a887132f5099cc84617b0b06c16f3ffb /file_io/netware/filestat.c
parent9b95ce3a0d8308a6d5e2b50f9bb9555fd16c12a1 (diff)
downloadlibapr-333ee0ee85c6e648161cc755ffebf1215f640a36.tar.gz
Removed the ReadWrite mutex that protects the stat cache table. Instead implemented
separate stat cache tables per processor. This eliminates the lock contention that was occuring each time a cache node expired and had to be refreshed. Having a stat cache per processor may cause some data redundancy but ensures that no other thread will be refreshing a node at the same time a thread is reading it. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@63523 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'file_io/netware/filestat.c')
-rw-r--r--file_io/netware/filestat.c81
1 files changed, 12 insertions, 69 deletions
diff --git a/file_io/netware/filestat.c b/file_io/netware/filestat.c
index 4b3c01558..8bffb5e02 100644
--- a/file_io/netware/filestat.c
+++ b/file_io/netware/filestat.c
@@ -59,13 +59,6 @@
#include "apr_strings.h"
#include "apr_errno.h"
#include "apr_hash.h"
-#define USE_CSTAT_RWLOCK
-#ifdef USE_CSTAT_MUTEX
-#include "apr_thread_mutex.h"
-#endif
-#ifdef USE_CSTAT_RWLOCK
-#include "apr_thread_rwlock.h"
-#endif
static apr_filetype_e filetype_from_mode(mode_t mode)
{
@@ -222,28 +215,11 @@ struct apr_stat_entry_t {
apr_time_t expire;
};
-typedef struct apr_stat_cache_t apr_stat_cache_t;
-
-struct apr_stat_cache_t {
- apr_hash_t *statCache;
-#ifdef USE_CSTAT_MUTEX
- apr_thread_mutex_t *statcache_mutex;
-#endif
-#ifdef USE_CSTAT_RWLOCK
- apr_thread_rwlock_t *statcache_mutex;
-#endif
-};
+extern apr_int32_t CpuCurrentProcessor; /* system variable */
int cstat (const char *path, struct stat *buf, char **casedName, apr_pool_t *pool)
{
- apr_stat_cache_t *statCacheData = (apr_stat_cache_t *)getStatCache();
- apr_hash_t *statCache = NULL;
-#ifdef USE_CSTAT_MUTEX
- apr_thread_mutex_t *statcache_mutex;
-#endif
-#ifdef USE_CSTAT_RWLOCK
- apr_thread_rwlock_t *statcache_mutex;
-#endif
+ apr_hash_t *statCache = (apr_hash_t *)getStatCache(CpuCurrentProcessor);
apr_pool_t *gPool = (apr_pool_t *)getGlobalPool();
apr_stat_entry_t *stat_entry;
struct stat *info;
@@ -263,46 +239,18 @@ int cstat (const char *path, struct stat *buf, char **casedName, apr_pool_t *poo
return ret;
}
- /* If we have a statCacheData structure then use it.
+ /* If we have a statCache hash table then use it.
Otherwise we need to create it and initialized it
with a new mutex lock. */
- if (statCacheData) {
- statCache = statCacheData->statCache;
-#if defined(USE_CSTAT_MUTEX) || defined(USE_CSTAT_RWLOCK)
- statcache_mutex = statCacheData->statcache_mutex;
-#endif
- }
- else {
- statCacheData = (apr_stat_cache_t *)apr_palloc (gPool, sizeof(apr_stat_cache_t));
+ if (!statCache) {
statCache = apr_hash_make(gPool);
-#ifdef USE_CSTAT_MUTEX
- apr_thread_mutex_create(&statcache_mutex, APR_THREAD_MUTEX_DEFAULT, gPool);
- statCacheData->statcache_mutex = statcache_mutex;
-#endif
-#ifdef USE_CSTAT_RWLOCK
- apr_thread_rwlock_create(&statcache_mutex, gPool);
- statCacheData->statcache_mutex = statcache_mutex;
-#endif
- statCacheData->statCache = statCache;
- setStatCache((void*)statCacheData);
+ setStatCache((void*)statCache, CpuCurrentProcessor);
}
/* If we have a statCache then try to pull the information
from the cache. Otherwise just stat the file and return.*/
if (statCache) {
-#ifdef USE_CSTAT_MUTEX
- apr_thread_mutex_lock(statcache_mutex);
-#endif
-#ifdef USE_CSTAT_RWLOCK
- apr_thread_rwlock_rdlock(statcache_mutex);
-#endif
stat_entry = (apr_stat_entry_t*) apr_hash_get(statCache, path, APR_HASH_KEY_STRING);
-#ifdef USE_CSTAT_MUTEX
- apr_thread_mutex_unlock(statcache_mutex);
-#endif
-#ifdef USE_CSTAT_RWLOCK
- apr_thread_rwlock_unlock(statcache_mutex);
-#endif
/* If we got an entry then check the expiration time. If the entry
hasn't expired yet then copy the information and return. */
if (stat_entry) {
@@ -316,16 +264,16 @@ int cstat (const char *path, struct stat *buf, char **casedName, apr_pool_t *poo
}
}
+ /* Since we are creating a separate stat cache for each processor, we
+ don't need to worry about locking the hash table before manipulating
+ it. */
if (!found) {
+ /* Bind the thread to the current cpu so that we don't wake
+ up on some other cpu and try to manipulate the wrong cache. */
+ NXThreadBind (CpuCurrentProcessor);
ret = stat(path, buf);
if (ret == 0) {
*casedName = case_filename(pool, path);
-#ifdef USE_CSTAT_MUTEX
- apr_thread_mutex_lock(statcache_mutex);
-#endif
-#ifdef USE_CSTAT_RWLOCK
- apr_thread_rwlock_wrlock(statcache_mutex);
-#endif
/* If we don't have a stat_entry then create one, copy
the data and add it to the hash table. */
if (!stat_entry) {
@@ -349,12 +297,7 @@ int cstat (const char *path, struct stat *buf, char **casedName, apr_pool_t *poo
}
stat_entry->expire = now;
}
-#ifdef USE_CSTAT_MUTEX
- apr_thread_mutex_unlock(statcache_mutex);
-#endif
-#ifdef USE_CSTAT_RWLOCK
- apr_thread_rwlock_unlock(statcache_mutex);
-#endif
+ NXThreadBind (NX_THR_UNBOUND);
}
else
return ret;