diff options
author | hobbs <hobbs> | 2002-04-23 17:03:34 (GMT) |
---|---|---|
committer | hobbs <hobbs> | 2002-04-23 17:03:34 (GMT) |
commit | d6befe3b0ecd8da7c936827f0c6c2e3fb41b6496 (patch) | |
tree | d5a9ad88cb63d360c0bef3b2ec2d73058e8e0227 /win/tclWinThrd.c | |
parent | bf47097699f7f908f97e75a28b1b8d0817ed7bae (diff) | |
download | tcl-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.c | 78 |
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 */ |