Return-Path: Delivered-To: apmail-apr-cvs-archive@apr.apache.org Received: (qmail 16611 invoked by uid 500); 26 Jun 2002 22:01:05 -0000 Mailing-List: contact cvs-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Reply-To: dev@apr.apache.org Delivered-To: mailing list cvs@apr.apache.org Received: (qmail 16600 invoked from network); 26 Jun 2002 22:01:05 -0000 Date: 26 Jun 2002 22:01:03 -0000 Message-ID: <20020626220103.43840.qmail@icarus.apache.org> From: bnicholes@apache.org To: apr-cvs@apache.org Subject: cvs commit: apr/include/arch/netware apr_private.h X-Spam-Rating: 209.66.108.5 1.6.2 0/1000/N bnicholes 2002/06/26 15:01:02 Modified: . NWGNUmakefile misc/netware libprews.c aprlib.def file_io/netware filestat.c include/arch/netware apr_private.h Log: 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. Revision Changes Path 1.6 +2 -4 apr/NWGNUmakefile Index: NWGNUmakefile =================================================================== RCS file: /home/cvs/apr/NWGNUmakefile,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- NWGNUmakefile 13 Jun 2002 00:40:50 -0000 1.5 +++ NWGNUmakefile 26 Jun 2002 22:01:02 -0000 1.6 @@ -220,10 +220,8 @@ FILES_nlm_Ximports = \ @libc.imp \ @ws2nlm.imp \ - @netware.imp \ - NXGetRandom \ - NXGetCtlInfo \ - NXSetCtlInfo \ + @netware.imp \ + CpuCurrentProcessor \ $(EOLIST) # 1.6 +17 -6 apr/misc/netware/libprews.c Index: libprews.c =================================================================== RCS file: /home/cvs/apr/misc/netware/libprews.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- libprews.c 14 Mar 2002 16:50:11 -0000 1.5 +++ libprews.c 26 Jun 2002 22:01:02 -0000 1.6 @@ -15,10 +15,12 @@ #include "apr_pools.h" +#define MAX_PROCESSORS 128 + typedef struct app_data { int initialized; void* gPool; - void* statCache; + void* statCache[MAX_PROCESSORS]; } APP_DATA; /* library-private data...*/ @@ -174,26 +176,35 @@ return NULL; } -int setStatCache(void *data) +int setStatCache(void *data, int proc) { APP_DATA *app_data = (APP_DATA*) get_app_data(gLibId); + if ((proc < 0) || (proc > (MAX_PROCESSORS-1))) { + data = NULL; + return 0; + } + NXLock(gLibLock); - if (app_data && !app_data->statCache) { - app_data->statCache = data; + if (app_data && !app_data->statCache[proc]) { + app_data->statCache[proc] = data; } NXUnlock(gLibLock); return 1; } -void* getStatCache() +void* getStatCache(int proc) { APP_DATA *app_data = (APP_DATA*) get_app_data(gLibId); + if ((proc < 0) || (proc > (MAX_PROCESSORS-1))) { + return NULL; + } + if (app_data) { - return app_data->statCache; + return app_data->statCache[proc]; } return NULL; 1.6 +1 -0 apr/misc/netware/aprlib.def Index: aprlib.def =================================================================== RCS file: /home/cvs/apr/misc/netware/aprlib.def,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- aprlib.def 5 Mar 2002 19:48:55 -0000 1.5 +++ aprlib.def 26 Jun 2002 22:01:02 -0000 1.6 @@ -1,3 +1,4 @@ MODULE LIBC.NLM MODULE WS2_32.NLM +IMPORT CpuCurrentProcessor EXPORT @aprlib.imp 1.13 +12 -69 apr/file_io/netware/filestat.c Index: filestat.c =================================================================== RCS file: /home/cvs/apr/file_io/netware/filestat.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- filestat.c 11 Jun 2002 15:34:26 -0000 1.12 +++ filestat.c 26 Jun 2002 22:01:02 -0000 1.13 @@ -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 @@ 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 @@ 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 @@ } } + /* 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 @@ } 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; 1.10 +2 -2 apr/include/arch/netware/apr_private.h Index: apr_private.h =================================================================== RCS file: /home/cvs/apr/include/arch/netware/apr_private.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- apr_private.h 13 Mar 2002 20:39:17 -0000 1.9 +++ apr_private.h 26 Jun 2002 22:01:02 -0000 1.10 @@ -170,8 +170,8 @@ /* Application global data management */ int setGlobalPool(void *data); void* getGlobalPool(); -int setStatCache(void *data); -void* getStatCache(); +int setStatCache(void *data, int proc); +void* getStatCache(int proc); /* Redefine malloc to use the library malloc call so that all of the memory resources will be owned