summaryrefslogtreecommitdiffstats
path: root/win/tclWinThrd.c
diff options
context:
space:
mode:
authorhobbs <hobbs>2002-04-23 17:03:34 (GMT)
committerhobbs <hobbs>2002-04-23 17:03:34 (GMT)
commitd6befe3b0ecd8da7c936827f0c6c2e3fb41b6496 (patch)
treed5a9ad88cb63d360c0bef3b2ec2d73058e8e0227 /win/tclWinThrd.c
parentbf47097699f7f908f97e75a28b1b8d0817ed7bae (diff)
downloadtcl-d6befe3b0ecd8da7c936827f0c6c2e3fb41b6496.zip
tcl-d6befe3b0ecd8da7c936827f0c6c2e3fb41b6496.tar.gz
tcl-d6befe3b0ecd8da7c936827f0c6c2e3fb41b6496.tar.bz2
* generic/tclAlloc.c:
* generic/tclInt.h: * generic/tclThreadAlloc.c (new): * unix/Makefile.in: * unix/tclUnixThrd.c: * win/Makefile.in: * win/tclWinInt.h: * win/tclWinThrd.c: added new threaded allocator contributed by AOL that significantly reduces lock contention when multiple threads are in use. Only Windows and Unix implementations are ready, and the Windows one may need work. It is only used by default on Unix for now, and requires that USE_THREAD_ALLOC be defined (--enable-threads on Unix will define this).
Diffstat (limited to 'win/tclWinThrd.c')
-rw-r--r--win/tclWinThrd.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c
index e25b145..10a886c 100644
--- a/win/tclWinThrd.c
+++ b/win/tclWinThrd.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinThrd.c,v 1.18 2001/09/07 18:57:20 mdejong Exp $
+ * RCS: @(#) $Id: tclWinThrd.c,v 1.19 2002/04/23 17:03:35 hobbs Exp $
*/
#include "tclWinInt.h"
@@ -367,7 +367,12 @@ Tcl_Mutex *
Tcl_GetAllocMutex()
{
#ifdef TCL_THREADS
- InitializeCriticalSection(&allocLock);
+ static int once = 0;
+
+ if (!once) {
+ InitializeCriticalSection(&allocLock);
+ once = 1;
+ }
return &allocLockPtr;
#else
return NULL;
@@ -628,6 +633,14 @@ TclpFinalizeThreadData(keyPtr)
{
VOID *result;
DWORD *indexPtr;
+#ifdef USE_THREAD_ALLOC
+ static int once = 0;
+
+ if (!once) {
+ once = 1;
+ TclWinFreeAllocCache();
+ }
+#endif
if (*keyPtr != NULL) {
indexPtr = *(DWORD **)keyPtr;
@@ -970,4 +983,65 @@ TclpFinalizeCondition(condPtr)
*condPtr = NULL;
}
}
+
+/*
+ * Additions by AOL for specialized thread memory allocator.
+ */
+#ifdef USE_THREAD_ALLOC
+static DWORD key;
+
+Tcl_Mutex *
+TclpNewAllocMutex(void)
+{
+ struct lock {
+ Tcl_Mutex tlock;
+ CRITICAL_SECTION wlock;
+ } *lockPtr;
+
+ lockPtr = malloc(sizeof(struct lock));
+ if (lockPtr == NULL) {
+ panic("could not allocate lock");
+ }
+ lockPtr->tlock = (Tcl_Mutex) &lockPtr->wlock;
+ InitializeCriticalSection(&lockPtr->wlock);
+ return &lockPtr->tlock;
+}
+
+void *
+TclpGetAllocCache(void)
+{
+ static int once = 0;
+
+ if (!once) {
+ /*
+ * We need to make sure that TclWinFreeAllocCache is called
+ * on each thread that calls this, but only on threads that
+ * call this.
+ */
+ key = TlsAlloc();
+ once = 1;
+ if (key == TLS_OUT_OF_INDEXES) {
+ panic("could not allocate thread local storage");
+ }
+ }
+ return TlsGetValue(key);
+}
+
+void
+TclpSetAllocCache(void *ptr)
+{
+ TlsSetValue(key, ptr);
+}
+
+void
+TclWinFreeAllocCache(void)
+{
+ void *ptr;
+
+ ptr = TlsGetValue(key);
+ TlsSetValue(key, NULL);
+ TclFreeAllocCache(ptr);
+}
+
+#endif /* USE_THREAD_ALLOC */
#endif /* TCL_THREADS */