cleanup; use new mutex for mempool

This commit is contained in:
Eric House 2024-08-17 22:02:06 -07:00
parent 5eb4eb77d3
commit faf398790c
8 changed files with 56 additions and 48 deletions

View file

@ -417,7 +417,7 @@ comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer,
XP_U16 forceChannel ) XP_U16 forceChannel )
{ {
CommsCtxt* comms = (CommsCtxt*)XP_CALLOC( mpool, sizeof(*comms) ); CommsCtxt* comms = (CommsCtxt*)XP_CALLOC( mpool, sizeof(*comms) );
initMutex( &comms->mutex, XP_TRUE ); mtx_init( &comms->mutex, XP_TRUE );
comms->util = util; comms->util = util;
comms->dutil = util_getDevUtilCtxt( util, xwe ); comms->dutil = util_getDevUtilCtxt( util, xwe );
#ifdef DEBUG #ifdef DEBUG
@ -587,6 +587,7 @@ comms_destroy( CommsCtxt* comms, XWEnv xwe )
util_clearTimer( comms->util, xwe, TIMER_COMMS ); util_clearTimer( comms->util, xwe, TIMER_COMMS );
END_WITH_MUTEX(); END_WITH_MUTEX();
mtx_destroy( &comms->mutex );
XP_FREE( comms->mpool, comms ); XP_FREE( comms->mpool, comms );
} /* comms_destroy */ } /* comms_destroy */

View file

@ -24,35 +24,15 @@
#include "comtypes.h" #include "comtypes.h"
#include "xwstream.h" #include "xwstream.h"
// #define MUTEX_LOG_VERBOSE
#include "xwmutex.h"
/* #define MPOOL_DEBUG */ /* #define MPOOL_DEBUG */
#ifdef CPLUS #ifdef CPLUS
extern "C" { extern "C" {
#endif #endif
#ifndef MEMPOOL_SYNC_DECL
# include <pthread.h>
# 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 { typedef struct MemPoolEntry {
struct MemPoolEntry* next; struct MemPoolEntry* next;
@ -65,7 +45,7 @@ typedef struct MemPoolEntry {
} MemPoolEntry; } MemPoolEntry;
struct MemPoolCtx { struct MemPoolCtx {
MEMPOOL_SYNC_DECL; MutexState mutex;
MemPoolEntry* freeList; MemPoolEntry* freeList;
MemPoolEntry* usedList; MemPoolEntry* usedList;
@ -84,12 +64,11 @@ mpool_make( const XP_UCHAR* tag )
{ {
MemPoolCtx* result = (MemPoolCtx*)XP_PLATMALLOC( sizeof(*result) ); MemPoolCtx* result = (MemPoolCtx*)XP_PLATMALLOC( sizeof(*result) );
XP_MEMSET( result, 0, sizeof(*result) ); XP_MEMSET( result, 0, sizeof(*result) );
MEMPOOL_SYNC_INIT(result); mtx_init( &result->mutex, XP_TRUE );
mpool_setTag( result, tag ); mpool_setTag( result, tag );
return result; return result;
} /* mpool_make */ } /* mpool_make */
void void
mpool_setTag( MemPoolCtx* mpool, const XP_UCHAR* tag ) mpool_setTag( MemPoolCtx* mpool, const XP_UCHAR* tag )
{ {
@ -181,7 +160,7 @@ mpool_destroy( MemPoolCtx* mpool )
#endif #endif
freeList( mpool->freeList ); freeList( mpool->freeList );
MEMPOOL_SYNC_DESTROY(mpool); mtx_destroy( &mpool->mutex );
XP_PLATFREE( mpool ); XP_PLATFREE( mpool );
} /* mpool_destroy */ } /* mpool_destroy */
@ -189,10 +168,10 @@ void*
mpool_alloc( MemPoolCtx* mpool, XP_U32 size, const char* file, mpool_alloc( MemPoolCtx* mpool, XP_U32 size, const char* file,
const char* func, XP_U32 lineNo ) const char* func, XP_U32 lineNo )
{ {
MemPoolEntry* entry;
void* result = NULL; void* result = NULL;
MEMPOOL_SYNC_START(mpool);
WITH_MUTEX( &mpool->mutex );
MemPoolEntry* entry;
if ( mpool->nFree > 0 ) { if ( mpool->nFree > 0 ) {
entry = mpool->freeList; entry = mpool->freeList;
mpool->freeList = entry->next; mpool->freeList = entry->next;
@ -224,7 +203,7 @@ mpool_alloc( MemPoolCtx* mpool, XP_U32 size, const char* file,
#endif #endif
result = entry->ptr; result = entry->ptr;
MEMPOOL_SYNC_END(mpool); END_WITH_MUTEX();
return result; return result;
} /* mpool_alloc */ } /* mpool_alloc */
@ -301,7 +280,7 @@ mpool_free( MemPoolCtx* mpool, void* ptr, const char* file,
{ {
MemPoolEntry* prev; MemPoolEntry* prev;
MEMPOOL_SYNC_START(mpool); WITH_MUTEX( &mpool->mutex );
MemPoolEntry* entry = findEntryFor( mpool, ptr, &prev ); MemPoolEntry* entry = findEntryFor( mpool, ptr, &prev );
@ -337,7 +316,7 @@ mpool_free( MemPoolCtx* mpool, void* ptr, const char* file,
++mpool->nFree; ++mpool->nFree;
--mpool->nUsed; --mpool->nUsed;
} }
MEMPOOL_SYNC_END(mpool); END_WITH_MUTEX();
} /* mpool_free */ } /* mpool_free */
void void

View file

@ -40,7 +40,7 @@ void
sts_init( XW_DUtilCtxt* dutil ) sts_init( XW_DUtilCtxt* dutil )
{ {
StatsState* ss = XP_CALLOC( dutil->mpool, sizeof(*ss) ); StatsState* ss = XP_CALLOC( dutil->mpool, sizeof(*ss) );
initMutex( &ss->mutex, XP_TRUE ); mtx_init( &ss->mutex, XP_TRUE );
dutil->statsState = ss; dutil->statsState = ss;
} }
@ -49,6 +49,7 @@ sts_cleanup( XW_DUtilCtxt* dutil, XWEnv XP_UNUSED(xwe) )
{ {
StatsState* ss = dutil->statsState; StatsState* ss = dutil->statsState;
XP_ASSERT( !!ss ); XP_ASSERT( !!ss );
mtx_destroy( &ss->mutex );
XP_FREEP( dutil->mpool, &ss->statsVals ); XP_FREEP( dutil->mpool, &ss->statsVals );
XP_FREEP( dutil->mpool, &ss ); XP_FREEP( dutil->mpool, &ss );
} }

View file

@ -47,7 +47,7 @@ tmr_init( XW_DUtilCtxt* dutil )
TimerMgrState* tms = XP_CALLOC( dutil->mpool, sizeof(*tms) ); TimerMgrState* tms = XP_CALLOC( dutil->mpool, sizeof(*tms) );
tms->dutil = dutil; tms->dutil = dutil;
dutil->timersState = tms; dutil->timersState = tms;
initMutex( &tms->mutex, XP_TRUE ); mtx_init( &tms->mutex, XP_TRUE );
} }
void void
@ -56,6 +56,7 @@ tmr_cleanup( XW_DUtilCtxt* dutil, XWEnv xwe )
TimerMgrState* timersState = (TimerMgrState*)dutil->timersState; TimerMgrState* timersState = (TimerMgrState*)dutil->timersState;
XP_ASSERT( !!timersState ); XP_ASSERT( !!timersState );
clearPendings( dutil, xwe ); clearPendings( dutil, xwe );
mtx_destroy( &timersState->mutex );
XP_FREEP( dutil->mpool, &dutil->timersState ); XP_FREEP( dutil->mpool, &dutil->timersState );
} }

View file

@ -20,7 +20,7 @@
#include "xwmutex.h" #include "xwmutex.h"
void void
initMutex( MutexState* mutex, XP_Bool recursive ) mtx_init( MutexState* mutex, XP_Bool recursive )
{ {
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
int ret = pthread_mutexattr_init(&attr); int ret = pthread_mutexattr_init(&attr);
@ -44,3 +44,9 @@ initMutex( MutexState* mutex, XP_Bool recursive )
/* } */ /* } */
#endif #endif
} }
void
mtx_destroy( MutexState* mutex )
{
pthread_mutex_destroy( &mutex->mutex );
}

View file

@ -28,7 +28,7 @@ typedef struct _MutexState {
pthread_mutex_t mutex; pthread_mutex_t mutex;
} MutexState; } MutexState;
#if 0 #ifdef MUTEX_LOG_VERBOSE
# define MUTEX_LOG(...) XP_LOGFF(__VA_ARGS__) # define MUTEX_LOG(...) XP_LOGFF(__VA_ARGS__)
#else #else
# define MUTEX_LOG(...) # define MUTEX_LOG(...)
@ -56,12 +56,12 @@ typedef struct _MutexState {
MUTEX_LOG( "released mutex %p", _state ); \ MUTEX_LOG( "released mutex %p", _state ); \
} \ } \
#define WITH_MUTEX_LOCK_RELEASE(COMMS) { \ #define WITH_MUTEX_LOCK_RELEASE(COMMS) { \
CommsCtxt* _comms = COMMS; \ MutexState* _state = (STATEP); \
pthread_mutex_lock(&_comms->mutex); \ pthread_mutex_lock(&_state->mutex); \
#define WITH_MUTEX_UNLOCK_RELEASE() \ #define WITH_MUTEX_UNLOCK_RELEASE() \
pthread_mutex_unlock(&_comms->mutex); \ pthread_mutex_unlock(&_state->mutex); \
} \ } \
#ifdef DEBUG #ifdef DEBUG
@ -72,6 +72,7 @@ typedef struct _MutexState {
#define END_WITH_MUTEX WITH_MUTEX_UNLOCK_RELEASE #define END_WITH_MUTEX WITH_MUTEX_UNLOCK_RELEASE
#endif #endif
void initMutex( MutexState* mutex, XP_Bool recursive ); void mtx_init( MutexState* mutex, XP_Bool recursive );
void mtx_destroy( MutexState* mutex );
#endif #endif

View file

@ -752,8 +752,8 @@ gdb_store( sqlite3* pDb, const gchar* key, const gchar* value )
{ {
XP_ASSERT( !!pDb ); XP_ASSERT( !!pDb );
gchar* query = gchar* query =
g_strdup_printf( "INSERT OR REPLACE INTO pairs (key, value) VALUES ('%s', '%s')", g_strdup_printf( "INSERT OR REPLACE INTO pairs (key, value) "
key, value ); "VALUES ('%s', '%s')", key, value );
execNoResult( pDb, query, false ); execNoResult( pDb, query, false );
g_free( query ); g_free( query );
} }
@ -905,7 +905,8 @@ assertPrintResult( sqlite3* pDb, int result, int expect )
} }
if ( result != expect ) { if ( result != expect ) {
XP_LOGFF( "sqlite3 error: %d (%s)", result, sqlite3_errstr(result) ); 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); XP_ASSERT(0);
} }
} }

View file

@ -199,6 +199,7 @@ class Device():
_nSteps = 0 _nSteps = 0
_nextChatID = 0 _nextChatID = 0
_kps = {} _kps = {}
_stats = None
@staticmethod @staticmethod
def setup(logdir): def setup(logdir):
@ -239,6 +240,8 @@ class Device():
return self.app return self.app
def stats(self): return self._stats
# called by thread proc # called by thread proc
def _launchProc(self): def _launchProc(self):
assert not self.endTime assert not self.endTime
@ -560,7 +563,7 @@ class Device():
# PENDING. Don't print this, but include in summary on exit # PENDING. Don't print this, but include in summary on exit
response = self._sendWaitReply('stats') response = self._sendWaitReply('stats')
print('stats => {}'.format(response)) self._addStats(response)
response = self \ response = self \
._sendWaitReply('getStates', gids=gids, orders=orders) ._sendWaitReply('getStates', gids=gids, orders=orders)
@ -601,6 +604,14 @@ class Device():
self.watcher = None self.watcher = None
assert not self.endTime 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): def _checkScript(self):
if not os.path.exists(self.script): if not os.path.exists(self.script):
scriptArgs = ['exec'] # without exec means terminate() won't work scriptArgs = ['exec'] # without exec means terminate() won't work
@ -747,6 +758,10 @@ def printKPs():
assert 1 == len(names) assert 1 == len(names)
print('Known players: {}'.format(kps)) print('Known players: {}'.format(kps))
def printStats():
for dev in Device.getAll():
print('stats for {}: {}'.format(dev.host, dev.stats()))
def mainLoop(args, devs): def mainLoop(args, devs):
startCount = len(devs) startCount = len(devs)
nCores = countCores(args) nCores = countCores(args)
@ -790,6 +805,7 @@ def mainLoop(args, devs):
if not args.VERBOSE: if not args.VERBOSE:
Device.printStatus(args.STATUS_STEPS) Device.printStatus(args.STATUS_STEPS)
# kill anybody left alive
for dev in devs: for dev in devs:
print('killing {}'.format(dev.host)) print('killing {}'.format(dev.host))
dev.quit() dev.quit()
@ -998,6 +1014,8 @@ def main():
mainLoop(args, devs) mainLoop(args, devs)
printKPs() printKPs()
printStats()
elapsed = datetime.datetime.now() - startTime elapsed = datetime.datetime.now() - startTime
print('played {} games in {}'.format(gGamesMade, elapsed)) print('played {} games in {}'.format(gGamesMade, elapsed))