From faf398790cdbca2308348facfcce1947ee6b948f Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 17 Aug 2024 22:02:06 -0700 Subject: [PATCH] cleanup; use new mutex for mempool --- xwords4/common/comms.c | 3 +- xwords4/common/mempool.c | 45 +++++++-------------------- xwords4/common/stats.c | 3 +- xwords4/common/timers.c | 3 +- xwords4/common/xwmutex.c | 8 ++++- xwords4/common/xwmutex.h | 15 ++++----- xwords4/linux/gamesdb.c | 7 +++-- xwords4/linux/scripts/netGamesTest.py | 20 +++++++++++- 8 files changed, 56 insertions(+), 48 deletions(-) diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index cab5c18b5..4f5389312 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -417,7 +417,7 @@ comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer, XP_U16 forceChannel ) { CommsCtxt* comms = (CommsCtxt*)XP_CALLOC( mpool, sizeof(*comms) ); - initMutex( &comms->mutex, XP_TRUE ); + mtx_init( &comms->mutex, XP_TRUE ); comms->util = util; comms->dutil = util_getDevUtilCtxt( util, xwe ); #ifdef DEBUG @@ -587,6 +587,7 @@ comms_destroy( CommsCtxt* comms, XWEnv xwe ) util_clearTimer( comms->util, xwe, TIMER_COMMS ); END_WITH_MUTEX(); + mtx_destroy( &comms->mutex ); XP_FREE( comms->mpool, comms ); } /* comms_destroy */ diff --git a/xwords4/common/mempool.c b/xwords4/common/mempool.c index a3c85afcd..965ae41ee 100644 --- a/xwords4/common/mempool.c +++ b/xwords4/common/mempool.c @@ -24,35 +24,15 @@ #include "comtypes.h" #include "xwstream.h" +// #define MUTEX_LOG_VERBOSE +#include "xwmutex.h" + /* #define MPOOL_DEBUG */ #ifdef CPLUS extern "C" { #endif -#ifndef MEMPOOL_SYNC_DECL -# include -# define MEMPOOL_SYNC_DECL pthread_mutex_t mutex -#endif - -#ifndef MEMPOOL_SYNC_INIT -# define MEMPOOL_SYNC_INIT(mp) \ - pthread_mutex_init( &((mp)->mutex), NULL ) -#endif - -#ifndef MEMPOOL_SYNC_DESTROY -# define MEMPOOL_SYNC_DESTROY(mp) \ - pthread_mutex_destroy( &((mp)->mutex ) ) -#endif - -#ifndef MEMPOOL_SYNC_START -# define MEMPOOL_SYNC_START(mp) \ - pthread_mutex_lock( &((mp)->mutex) ) -#endif -#ifndef MEMPOOL_SYNC_END -# define MEMPOOL_SYNC_END(mp) \ - pthread_mutex_unlock( &((mp)->mutex) ) -#endif typedef struct MemPoolEntry { struct MemPoolEntry* next; @@ -65,7 +45,7 @@ typedef struct MemPoolEntry { } MemPoolEntry; struct MemPoolCtx { - MEMPOOL_SYNC_DECL; + MutexState mutex; MemPoolEntry* freeList; MemPoolEntry* usedList; @@ -84,12 +64,11 @@ mpool_make( const XP_UCHAR* tag ) { MemPoolCtx* result = (MemPoolCtx*)XP_PLATMALLOC( sizeof(*result) ); XP_MEMSET( result, 0, sizeof(*result) ); - MEMPOOL_SYNC_INIT(result); + mtx_init( &result->mutex, XP_TRUE ); mpool_setTag( result, tag ); return result; } /* mpool_make */ - void mpool_setTag( MemPoolCtx* mpool, const XP_UCHAR* tag ) { @@ -181,7 +160,7 @@ mpool_destroy( MemPoolCtx* mpool ) #endif freeList( mpool->freeList ); - MEMPOOL_SYNC_DESTROY(mpool); + mtx_destroy( &mpool->mutex ); XP_PLATFREE( mpool ); } /* mpool_destroy */ @@ -189,10 +168,10 @@ void* mpool_alloc( MemPoolCtx* mpool, XP_U32 size, const char* file, const char* func, XP_U32 lineNo ) { - MemPoolEntry* entry; void* result = NULL; - MEMPOOL_SYNC_START(mpool); - + + WITH_MUTEX( &mpool->mutex ); + MemPoolEntry* entry; if ( mpool->nFree > 0 ) { entry = mpool->freeList; mpool->freeList = entry->next; @@ -224,7 +203,7 @@ mpool_alloc( MemPoolCtx* mpool, XP_U32 size, const char* file, #endif result = entry->ptr; - MEMPOOL_SYNC_END(mpool); + END_WITH_MUTEX(); return result; } /* mpool_alloc */ @@ -301,7 +280,7 @@ mpool_free( MemPoolCtx* mpool, void* ptr, const char* file, { MemPoolEntry* prev; - MEMPOOL_SYNC_START(mpool); + WITH_MUTEX( &mpool->mutex ); MemPoolEntry* entry = findEntryFor( mpool, ptr, &prev ); @@ -337,7 +316,7 @@ mpool_free( MemPoolCtx* mpool, void* ptr, const char* file, ++mpool->nFree; --mpool->nUsed; } - MEMPOOL_SYNC_END(mpool); + END_WITH_MUTEX(); } /* mpool_free */ void diff --git a/xwords4/common/stats.c b/xwords4/common/stats.c index 783b58481..6e92d718b 100644 --- a/xwords4/common/stats.c +++ b/xwords4/common/stats.c @@ -40,7 +40,7 @@ void sts_init( XW_DUtilCtxt* dutil ) { StatsState* ss = XP_CALLOC( dutil->mpool, sizeof(*ss) ); - initMutex( &ss->mutex, XP_TRUE ); + mtx_init( &ss->mutex, XP_TRUE ); dutil->statsState = ss; } @@ -49,6 +49,7 @@ sts_cleanup( XW_DUtilCtxt* dutil, XWEnv XP_UNUSED(xwe) ) { StatsState* ss = dutil->statsState; XP_ASSERT( !!ss ); + mtx_destroy( &ss->mutex ); XP_FREEP( dutil->mpool, &ss->statsVals ); XP_FREEP( dutil->mpool, &ss ); } diff --git a/xwords4/common/timers.c b/xwords4/common/timers.c index da72c68e8..08e4877c4 100644 --- a/xwords4/common/timers.c +++ b/xwords4/common/timers.c @@ -47,7 +47,7 @@ tmr_init( XW_DUtilCtxt* dutil ) TimerMgrState* tms = XP_CALLOC( dutil->mpool, sizeof(*tms) ); tms->dutil = dutil; dutil->timersState = tms; - initMutex( &tms->mutex, XP_TRUE ); + mtx_init( &tms->mutex, XP_TRUE ); } void @@ -56,6 +56,7 @@ tmr_cleanup( XW_DUtilCtxt* dutil, XWEnv xwe ) TimerMgrState* timersState = (TimerMgrState*)dutil->timersState; XP_ASSERT( !!timersState ); clearPendings( dutil, xwe ); + mtx_destroy( &timersState->mutex ); XP_FREEP( dutil->mpool, &dutil->timersState ); } diff --git a/xwords4/common/xwmutex.c b/xwords4/common/xwmutex.c index e756300d4..0fff12e85 100644 --- a/xwords4/common/xwmutex.c +++ b/xwords4/common/xwmutex.c @@ -20,7 +20,7 @@ #include "xwmutex.h" void -initMutex( MutexState* mutex, XP_Bool recursive ) +mtx_init( MutexState* mutex, XP_Bool recursive ) { pthread_mutexattr_t attr; int ret = pthread_mutexattr_init(&attr); @@ -44,3 +44,9 @@ initMutex( MutexState* mutex, XP_Bool recursive ) /* } */ #endif } + +void +mtx_destroy( MutexState* mutex ) +{ + pthread_mutex_destroy( &mutex->mutex ); +} diff --git a/xwords4/common/xwmutex.h b/xwords4/common/xwmutex.h index 258eac8c6..56376cf18 100644 --- a/xwords4/common/xwmutex.h +++ b/xwords4/common/xwmutex.h @@ -28,7 +28,7 @@ typedef struct _MutexState { pthread_mutex_t mutex; } MutexState; -#if 0 +#ifdef MUTEX_LOG_VERBOSE # define MUTEX_LOG(...) XP_LOGFF(__VA_ARGS__) #else # define MUTEX_LOG(...) @@ -56,12 +56,12 @@ typedef struct _MutexState { MUTEX_LOG( "released mutex %p", _state ); \ } \ -#define WITH_MUTEX_LOCK_RELEASE(COMMS) { \ - CommsCtxt* _comms = COMMS; \ - pthread_mutex_lock(&_comms->mutex); \ +#define WITH_MUTEX_LOCK_RELEASE(COMMS) { \ + MutexState* _state = (STATEP); \ + pthread_mutex_lock(&_state->mutex); \ -#define WITH_MUTEX_UNLOCK_RELEASE() \ - pthread_mutex_unlock(&_comms->mutex); \ +#define WITH_MUTEX_UNLOCK_RELEASE() \ + pthread_mutex_unlock(&_state->mutex); \ } \ #ifdef DEBUG @@ -72,6 +72,7 @@ typedef struct _MutexState { #define END_WITH_MUTEX WITH_MUTEX_UNLOCK_RELEASE #endif -void initMutex( MutexState* mutex, XP_Bool recursive ); +void mtx_init( MutexState* mutex, XP_Bool recursive ); +void mtx_destroy( MutexState* mutex ); #endif diff --git a/xwords4/linux/gamesdb.c b/xwords4/linux/gamesdb.c index afc99d9cd..9f3449c7b 100644 --- a/xwords4/linux/gamesdb.c +++ b/xwords4/linux/gamesdb.c @@ -752,8 +752,8 @@ gdb_store( sqlite3* pDb, const gchar* key, const gchar* value ) { XP_ASSERT( !!pDb ); gchar* query = - g_strdup_printf( "INSERT OR REPLACE INTO pairs (key, value) VALUES ('%s', '%s')", - key, value ); + g_strdup_printf( "INSERT OR REPLACE INTO pairs (key, value) " + "VALUES ('%s', '%s')", key, value ); execNoResult( pDb, query, false ); g_free( query ); } @@ -905,7 +905,8 @@ assertPrintResult( sqlite3* pDb, int result, int expect ) } if ( result != expect ) { XP_LOGFF( "sqlite3 error: %d (%s)", result, sqlite3_errstr(result) ); - XP_LOGFF( "Err msg (which could be out-of-sync): %s", sqlite3_errmsg( pDb ) ); + XP_LOGFF( "Err msg (which could be out-of-sync): %s", + sqlite3_errmsg( pDb ) ); XP_ASSERT(0); } } diff --git a/xwords4/linux/scripts/netGamesTest.py b/xwords4/linux/scripts/netGamesTest.py index b4c5fc422..5221d0e3f 100755 --- a/xwords4/linux/scripts/netGamesTest.py +++ b/xwords4/linux/scripts/netGamesTest.py @@ -199,6 +199,7 @@ class Device(): _nSteps = 0 _nextChatID = 0 _kps = {} + _stats = None @staticmethod def setup(logdir): @@ -239,6 +240,8 @@ class Device(): return self.app + def stats(self): return self._stats + # called by thread proc def _launchProc(self): assert not self.endTime @@ -560,7 +563,7 @@ class Device(): # PENDING. Don't print this, but include in summary on exit response = self._sendWaitReply('stats') - print('stats => {}'.format(response)) + self._addStats(response) response = self \ ._sendWaitReply('getStates', gids=gids, orders=orders) @@ -601,6 +604,14 @@ class Device(): self.watcher = None assert not self.endTime + def _addStats(self, stats): + stats = stats.get('stats') + if stats and self._stats: + for key in stats.keys(): + if key in self._stats: + assert self._stats[key] <= stats[key] + self._stats = stats + def _checkScript(self): if not os.path.exists(self.script): scriptArgs = ['exec'] # without exec means terminate() won't work @@ -747,6 +758,10 @@ def printKPs(): assert 1 == len(names) print('Known players: {}'.format(kps)) +def printStats(): + for dev in Device.getAll(): + print('stats for {}: {}'.format(dev.host, dev.stats())) + def mainLoop(args, devs): startCount = len(devs) nCores = countCores(args) @@ -790,6 +805,7 @@ def mainLoop(args, devs): if not args.VERBOSE: Device.printStatus(args.STATUS_STEPS) + # kill anybody left alive for dev in devs: print('killing {}'.format(dev.host)) dev.quit() @@ -998,6 +1014,8 @@ def main(): mainLoop(args, devs) printKPs() + printStats() + elapsed = datetime.datetime.now() - startTime print('played {} games in {}'.format(gGamesMade, elapsed))