From a4933e22d0b56bf07cf35cb90eb1f6fd6c9e48cb Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Mar 2016 14:22:52 +0000 Subject: (experiment) Use TclpMasterLock() in stead of a separate notifierInitMutex. One less mutex to be worried about. --- generic/tclInt.h | 1 + unix/tclUnixNotfy.c | 21 ++++++++++----------- unix/tclUnixThrd.c | 25 +++++++++++++++++++++++++ win/tclWinNotify.c | 26 ++++++++++++++++++-------- 4 files changed, 54 insertions(+), 19 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 42c13dd..da792aa 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3059,6 +3059,7 @@ MODULE_SCOPE void TclpInitUnlock(void); MODULE_SCOPE Tcl_Obj * TclpObjListVolumes(void); MODULE_SCOPE void TclpMasterLock(void); MODULE_SCOPE void TclpMasterUnlock(void); +MODULE_SCOPE void TclpMasterReset(void); MODULE_SCOPE int TclpMatchFiles(Tcl_Interp *interp, char *separators, Tcl_DString *dirPtr, char *pattern, char *tail); MODULE_SCOPE int TclpObjNormalizePath(Tcl_Interp *interp, diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index 1457890..ca6a7ef 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -152,7 +152,6 @@ static int triggerPipe = -1; * The notifierMutex locks access to all of the global notifier state. */ -pthread_mutex_t notifierInitMutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t notifierMutex = PTHREAD_MUTEX_INITIALIZER; /* * The following static indicates if the notifier thread is running. @@ -281,7 +280,7 @@ static void StartNotifierThread(const char *proc) { if (!notifierThreadRunning) { - pthread_mutex_lock(¬ifierInitMutex); + TclpMasterLock(); if (!notifierThreadRunning) { if (TclpThreadCreate(¬ifierThread, NotifierThreadProc, NULL, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE) != TCL_OK) { @@ -300,7 +299,7 @@ StartNotifierThread(const char *proc) notifierThreadRunning = 1; } - pthread_mutex_unlock(¬ifierInitMutex); + TclpMasterUnlock(); } } #endif /* TCL_THREADS */ @@ -362,7 +361,7 @@ Tcl_InitNotifier(void) tsdPtr->waitCVinitialized = 1; } - pthread_mutex_lock(¬ifierInitMutex); + TclpMasterLock(); #if defined(HAVE_PTHREAD_ATFORK) /* * Install pthread_atfork handlers to clean up the notifier in the @@ -381,7 +380,7 @@ Tcl_InitNotifier(void) notifierCount++; - pthread_mutex_unlock(¬ifierInitMutex); + TclpMasterUnlock(); #endif /* TCL_THREADS */ return tsdPtr; @@ -417,7 +416,7 @@ Tcl_FinalizeNotifier( #ifdef TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - pthread_mutex_lock(¬ifierInitMutex); + TclpMasterLock(); notifierCount--; /* @@ -462,7 +461,7 @@ Tcl_FinalizeNotifier( #endif /* __CYGWIN__ */ tsdPtr->waitCVinitialized = 0; - pthread_mutex_unlock(¬ifierInitMutex); + TclpMasterUnlock(); #endif /* TCL_THREADS */ } } @@ -1368,7 +1367,7 @@ static void AtForkPrepare(void) { #if RESET_ATFORK_MUTEX == 0 - pthread_mutex_lock(¬ifierInitMutex); + TclpMasterLock(); #endif } @@ -1392,7 +1391,7 @@ static void AtForkParent(void) { #if RESET_ATFORK_MUTEX == 0 - pthread_mutex_unlock(¬ifierInitMutex); + TclpMasterUnlock(); #endif } @@ -1419,9 +1418,9 @@ AtForkChild(void) pthread_cond_destroy(¬ifierCV); } #if RESET_ATFORK_MUTEX == 0 - pthread_mutex_unlock(¬ifierInitMutex); + TclpMasterUnlock(); #else - pthread_mutex_init(¬ifierInitMutex, NULL); + TclpMasterReset(); pthread_mutex_init(¬ifierMutex, NULL); #endif pthread_cond_init(¬ifierCV, NULL); diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 554a2dc..4130993 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -357,6 +357,31 @@ TclpMasterUnlock(void) /* *---------------------------------------------------------------------- * + * TclpMasterReset + * + * This procedure is used to reset a lock that serializes creation and + * finalization of synchronization objects. + * + * Results: + * None. + * + * Side effects: + * Reset the master mutex. + * + *---------------------------------------------------------------------- + */ + +void +TclpMasterReset(void) +{ +#ifdef TCL_THREADS + pthread_mutex_init(&masterLock, NULL); +#endif +} + +/* + *---------------------------------------------------------------------- + * * Tcl_GetAllocMutex * * This procedure returns a pointer to a statically initialized mutex for diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c index 4543b02..985a769 100644 --- a/win/tclWinNotify.c +++ b/win/tclWinNotify.c @@ -51,7 +51,8 @@ static Tcl_ThreadDataKey dataKey; static int notifierCount = 0; static const TCHAR classname[] = TEXT("TclNotifier"); -TCL_DECLARE_MUTEX(notifierMutex) +static int initialized = 0; +static CRITICAL_SECTION notifierMutex; /* * Static routines defined in this file. @@ -85,12 +86,19 @@ Tcl_InitNotifier(void) ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); WNDCLASS class; + TclpMasterLock(); + if (!initialized) { + initialized = 1; + InitializeCriticalSection(¬ifierMutex); + } + TclpMasterUnlock(); + /* * Register Notifier window class if this is the first thread to use * this module. */ - Tcl_MutexLock(¬ifierMutex); + EnterCriticalSection(¬ifierMutex); if (notifierCount == 0) { class.style = 0; class.cbClsExtra = 0; @@ -108,7 +116,7 @@ Tcl_InitNotifier(void) } } notifierCount++; - Tcl_MutexUnlock(¬ifierMutex); + LeaveCriticalSection(¬ifierMutex); tsdPtr->pending = 0; tsdPtr->timerActive = 0; @@ -183,12 +191,14 @@ Tcl_FinalizeNotifier( * notifier window class. */ - Tcl_MutexLock(¬ifierMutex); - notifierCount--; - if (notifierCount == 0) { - UnregisterClass(classname, TclWinGetTclInstance()); + EnterCriticalSection(¬ifierMutex); + if (notifierCount) { + notifierCount--; + if (notifierCount == 0) { + UnregisterClass(classname, TclWinGetTclInstance()); + } } - Tcl_MutexUnlock(¬ifierMutex); + LeaveCriticalSection(¬ifierMutex); } } -- cgit v0.12