diff options
Diffstat (limited to 'unix/tclUnixThrd.c')
| -rw-r--r-- | unix/tclUnixThrd.c | 582 |
1 files changed, 323 insertions, 259 deletions
diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index ad36242..7b99896 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -1,4 +1,4 @@ -/* +/* * tclUnixThrd.c -- * * This file implements the UNIX-specific thread support. @@ -6,14 +6,17 @@ * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" +#include "tclPort.h" #ifdef TCL_THREADS +#include "pthread.h" + typedef struct ThreadSpecificData { char nabuf[16]; } ThreadSpecificData; @@ -21,23 +24,24 @@ typedef struct ThreadSpecificData { static Tcl_ThreadDataKey dataKey; /* - * masterLock is used to serialize creation of mutexes, condition variables, - * and thread local storage. This is the only place that can count on the - * ability to statically initialize the mutex. + * masterLock is used to serialize creation of mutexes, condition + * variables, and thread local storage. + * This is the only place that can count on the ability to statically + * initialize the mutex. */ static pthread_mutex_t masterLock = PTHREAD_MUTEX_INITIALIZER; /* - * initLock is used to serialize initialization and finalization of Tcl. It - * cannot use any dyamically allocated storage. + * initLock is used to serialize initialization and finalization + * of Tcl. It cannot use any dyamically allocated storage. */ static pthread_mutex_t initLock = PTHREAD_MUTEX_INITIALIZER; /* - * allocLock is used by Tcl's version of malloc for synchronization. For - * obvious reasons, cannot use any dyamically allocated storage. + * allocLock is used by Tcl's version of malloc for synchronization. + * For obvious reasons, cannot use any dyamically allocated storage. */ static pthread_mutex_t allocLock = PTHREAD_MUTEX_INITIALIZER; @@ -61,8 +65,8 @@ static pthread_mutex_t *allocLockPtr = &allocLock; * This procedure creates a new thread. * * Results: - * TCL_OK if the thread could be created. The thread ID is returned in a - * parameter. + * TCL_OK if the thread could be created. The thread ID is + * returned in a parameter. * * Side effects: * A new thread is created. @@ -71,13 +75,13 @@ static pthread_mutex_t *allocLockPtr = &allocLock; */ int -TclpThreadCreate( - Tcl_ThreadId *idPtr, /* Return, the ID of the thread */ - Tcl_ThreadCreateProc proc, /* Main() function of the thread */ - ClientData clientData, /* The one argument to Main() */ - int stackSize, /* Size of stack for the new thread */ - int flags) /* Flags controlling behaviour of the new - * thread. */ +TclpThreadCreate(idPtr, proc, clientData, stackSize, flags) + Tcl_ThreadId *idPtr; /* Return, the ID of the thread */ + Tcl_ThreadCreateProc proc; /* Main() function of the thread */ + ClientData clientData; /* The one argument to Main() */ + int stackSize; /* Size of stack for the new thread */ + int flags; /* Flags controlling behaviour of + * the new thread */ { #ifdef TCL_THREADS pthread_attr_t attr; @@ -89,14 +93,14 @@ TclpThreadCreate( #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE if (stackSize != TCL_THREAD_STACK_DEFAULT) { - pthread_attr_setstacksize(&attr, (size_t) stackSize); + pthread_attr_setstacksize(&attr, (size_t) stackSize); #ifdef TCL_THREAD_STACK_MIN } else { - /* - * Certain systems define a thread stack size that by default is too - * small for many operations. The user has the option of defining - * TCL_THREAD_STACK_MIN to a value large enough to work for their - * needs. This would look like (for 128K min stack): + /* + * Certain systems define a thread stack size that by default is + * too small for many operations. The user has the option of + * defining TCL_THREAD_STACK_MIN to a value large enough to work + * for their needs. This would look like (for 128K min stack): * make MEM_DEBUG_FLAGS=-DTCL_THREAD_STACK_MIN=131072L * * This solution is not optimal, as we should allow the user to @@ -104,7 +108,7 @@ TclpThreadCreate( * down, and that would still leave the main thread at the default. */ - size_t size; + size_t size; result = pthread_attr_getstacksize(&attr, &size); if (!result && (size < TCL_THREAD_STACK_MIN)) { pthread_attr_setstacksize(&attr, (size_t) TCL_THREAD_STACK_MIN); @@ -113,14 +117,14 @@ TclpThreadCreate( } #endif if (! (flags & TCL_THREAD_JOINABLE)) { - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); } if (pthread_create(&theThread, &attr, - (void * (*)(void *))proc, (void *)clientData) && + (void * (*)())proc, (void *)clientData) && pthread_create(&theThread, NULL, - (void * (*)(void *))proc, (void *)clientData)) { + (void * (*)())proc, (void *)clientData)) { result = TCL_ERROR; } else { *idPtr = (Tcl_ThreadId)theThread; @@ -144,23 +148,24 @@ TclpThreadCreate( * TCL_OK if the wait was successful, TCL_ERROR else. * * Side effects: - * The result area is set to the exit code of the thread we waited upon. + * The result area is set to the exit code of the thread we + * waited upon. * *---------------------------------------------------------------------- */ int -Tcl_JoinThread( - Tcl_ThreadId threadId, /* Id of the thread to wait upon. */ - int *state) /* Reference to the storage the result of the - * thread we wait upon will be written into. - * May be NULL. */ +Tcl_JoinThread(threadId, state) + Tcl_ThreadId threadId; /* Id of the thread to wait upon */ + int* state; /* Reference to the storage the result + * of the thread we wait upon will be + * written into. */ { #ifdef TCL_THREADS int result; - unsigned long retcode, *retcodePtr = &retcode; + unsigned long retcode; - result = pthread_join((pthread_t) threadId, (void**) retcodePtr); + result = pthread_join((pthread_t) threadId, (void**) &retcode); if (state) { *state = (int) retcode; } @@ -188,103 +193,10 @@ Tcl_JoinThread( */ void -TclpThreadExit( - int status) -{ - pthread_exit(INT2PTR(status)); -} -#endif /* TCL_THREADS */ - -#ifdef TCL_THREADS -/* - *---------------------------------------------------------------------- - * - * TclpThreadGetStackSize -- - * - * This procedure returns the size of the current thread's stack. - * - * Results: - * Stack size (in bytes?) or -1 for error or 0 for undeterminable. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -size_t -TclpThreadGetStackSize(void) +TclpThreadExit(status) + int status; { - size_t stackSize = 0; -#if defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && defined(TclpPthreadGetAttrs) - pthread_attr_t threadAttr; /* This will hold the thread attributes for - * the current thread. */ -#ifdef __GLIBC__ - /* - * Fix for [Bug 1815573] - * - * DESCRIPTION: - * On linux TclpPthreadGetAttrs (which is pthread_attr_get_np) may return - * bogus values on the initial thread. - * - * ASSUMPTIONS: - * There seems to be no api to determine if we are on the initial - * thread. The simple scheme implemented here assumes: - * 1. The first Tcl interp to be created lives in the initial thread. If - * this assumption is not true, the fix is to call - * TclpThreadGetStackSize from the initial thread previous to - * creating any Tcl interpreter. In this case, especially if another - * Tcl interpreter may be created in the initial thread, it might be - * better to enable the second branch in the #if below - * 2. There will be no races in creating the first Tcl interp - ie, the - * second Tcl interp will be created only after the first call to - * Tcl_CreateInterp returns. - * - * These assumptions are satisfied by tclsh. Embedders on linux may want - * to check their validity, and possibly adapt the code on failing to meet - * them. - */ - - static int initialized = 0; - - if (!initialized) { - initialized = 1; - return 0; - } else { -#else - { -#endif - if (pthread_attr_init(&threadAttr) != 0) { - return -1; - } - if (TclpPthreadGetAttrs(pthread_self(), &threadAttr) != 0) { - pthread_attr_destroy(&threadAttr); - return (size_t)-1; - } - } - - - if (pthread_attr_getstacksize(&threadAttr, &stackSize) != 0) { - pthread_attr_destroy(&threadAttr); - return (size_t)-1; - } - pthread_attr_destroy(&threadAttr); -#elif defined(HAVE_PTHREAD_GET_STACKSIZE_NP) -#ifdef __APPLE__ - /* - * On Darwin, the API below does not return the correct stack size for the - * main thread (which is not a real pthread), so fallback to getrlimit(). - */ - if (!pthread_main_np()) -#endif - stackSize = pthread_get_stacksize_np(pthread_self()); -#else - /* - * Cannot determine the real stack size of this thread. The caller might - * want to try looking at the process accounting limits instead. - */ -#endif - return stackSize; + pthread_exit((VOID *)status); } #endif /* TCL_THREADS */ @@ -305,7 +217,7 @@ TclpThreadGetStackSize(void) */ Tcl_ThreadId -Tcl_GetCurrentThread(void) +Tcl_GetCurrentThread() { #ifdef TCL_THREADS return (Tcl_ThreadId) pthread_self(); @@ -313,6 +225,7 @@ Tcl_GetCurrentThread(void) return (Tcl_ThreadId) 0; #endif } + /* *---------------------------------------------------------------------- @@ -320,9 +233,9 @@ Tcl_GetCurrentThread(void) * TclpInitLock * * This procedure is used to grab a lock that serializes initialization - * and finalization of Tcl. On some platforms this may also initialize - * the mutex used to serialize creation of more mutexes and thread local - * storage keys. + * and finalization of Tcl. On some platforms this may also initialize + * the mutex used to serialize creation of more mutexes and thread + * local storage keys. * * Results: * None. @@ -334,7 +247,7 @@ Tcl_GetCurrentThread(void) */ void -TclpInitLock(void) +TclpInitLock() { #ifdef TCL_THREADS pthread_mutex_lock(&initLock); @@ -346,29 +259,28 @@ TclpInitLock(void) * * TclpFinalizeLock * - * This procedure is used to destroy all private resources used in this - * file. + * This procedure is used to destroy all private resources used in + * this file. * * Results: * None. * * Side effects: - * Destroys everything private. TclpInitLock must be held entering this - * function. + * Destroys everything private. TclpInitLock must be held + * entering this function. * *---------------------------------------------------------------------- */ void -TclFinalizeLock(void) +TclFinalizeLock () { #ifdef TCL_THREADS /* * You do not need to destroy mutexes that were created with the - * PTHREAD_MUTEX_INITIALIZER macro. These mutexes do not need any - * destruction: masterLock, allocLock, and initLock. + * PTHREAD_MUTEX_INITIALIZER macro. These mutexes do not need + * any destruction: masterLock, allocLock, and initLock. */ - pthread_mutex_unlock(&initLock); #endif } @@ -378,8 +290,8 @@ TclFinalizeLock(void) * * TclpInitUnlock * - * This procedure is used to release a lock that serializes - * initialization and finalization of Tcl. + * This procedure is used to release a lock that serializes initialization + * and finalization of Tcl. * * Results: * None. @@ -391,7 +303,7 @@ TclFinalizeLock(void) */ void -TclpInitUnlock(void) +TclpInitUnlock() { #ifdef TCL_THREADS pthread_mutex_unlock(&initLock); @@ -403,12 +315,13 @@ TclpInitUnlock(void) * * TclpMasterLock * - * This procedure is used to grab a lock that serializes creation and - * finalization of serialization objects. This interface is only needed - * in finalization; it is hidden during creation of the objects. + * This procedure is used to grab a lock that serializes creation + * and finalization of serialization objects. This interface is + * only needed in finalization; it is hidden during + * creation of the objects. * - * This lock must be different than the initLock because the initLock is - * held during creation of syncronization objects. + * This lock must be different than the initLock because the + * initLock is held during creation of syncronization objects. * * Results: * None. @@ -420,7 +333,7 @@ TclpInitUnlock(void) */ void -TclpMasterLock(void) +TclpMasterLock() { #ifdef TCL_THREADS pthread_mutex_lock(&masterLock); @@ -433,8 +346,8 @@ TclpMasterLock(void) * * TclpMasterUnlock * - * This procedure is used to release a lock that serializes creation and - * finalization of synchronization objects. + * This procedure is used to release a lock that serializes creation + * and finalization of synchronization objects. * * Results: * None. @@ -446,7 +359,7 @@ TclpMasterLock(void) */ void -TclpMasterUnlock(void) +TclpMasterUnlock() { #ifdef TCL_THREADS pthread_mutex_unlock(&masterLock); @@ -459,13 +372,13 @@ TclpMasterUnlock(void) * * Tcl_GetAllocMutex * - * This procedure returns a pointer to a statically initialized mutex for - * use by the memory allocator. The alloctor must use this lock, because - * all other locks are allocated... + * This procedure returns a pointer to a statically initialized + * mutex for use by the memory allocator. The alloctor must + * use this lock, because all other locks are allocated... * * Results: - * A pointer to a mutex that is suitable for passing to Tcl_MutexLock and - * Tcl_MutexUnlock. + * A pointer to a mutex that is suitable for passing to + * Tcl_MutexLock and Tcl_MutexUnlock. * * Side effects: * None. @@ -474,11 +387,10 @@ TclpMasterUnlock(void) */ Tcl_Mutex * -Tcl_GetAllocMutex(void) +Tcl_GetAllocMutex() { #ifdef TCL_THREADS - pthread_mutex_t **allocLockPtrPtr = &allocLockPtr; - return (Tcl_Mutex *) allocLockPtrPtr; + return (Tcl_Mutex *)&allocLockPtr; #else return NULL; #endif @@ -491,34 +403,34 @@ Tcl_GetAllocMutex(void) * * Tcl_MutexLock -- * - * This procedure is invoked to lock a mutex. This procedure handles - * initializing the mutex, if necessary. The caller can rely on the fact - * that Tcl_Mutex is an opaque pointer. This routine will change that - * pointer from NULL after first use. + * This procedure is invoked to lock a mutex. This procedure + * handles initializing the mutex, if necessary. The caller + * can rely on the fact that Tcl_Mutex is an opaque pointer. + * This routine will change that pointer from NULL after first use. * * Results: * None. * * Side effects: - * May block the current thread. The mutex is aquired when this returns. - * Will allocate memory for a pthread_mutex_t and initialize this the - * first time this Tcl_Mutex is used. + * May block the current thread. The mutex is aquired when + * this returns. Will allocate memory for a pthread_mutex_t + * and initialize this the first time this Tcl_Mutex is used. * *---------------------------------------------------------------------- */ void -Tcl_MutexLock( - Tcl_Mutex *mutexPtr) /* Really (pthread_mutex_t **) */ +Tcl_MutexLock(mutexPtr) + Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ { pthread_mutex_t *pmutexPtr; if (*mutexPtr == NULL) { MASTER_LOCK; if (*mutexPtr == NULL) { - /* + /* * Double inside master lock check to avoid a race condition. */ - + pmutexPtr = (pthread_mutex_t *)ckalloc(sizeof(pthread_mutex_t)); pthread_mutex_init(pmutexPtr, NULL); *mutexPtr = (Tcl_Mutex)pmutexPtr; @@ -529,14 +441,15 @@ Tcl_MutexLock( pmutexPtr = *((pthread_mutex_t **)mutexPtr); pthread_mutex_lock(pmutexPtr); } + /* *---------------------------------------------------------------------- * * Tcl_MutexUnlock -- * - * This procedure is invoked to unlock a mutex. The mutex must have been - * locked by Tcl_MutexLock. + * This procedure is invoked to unlock a mutex. The mutex must + * have been locked by Tcl_MutexLock. * * Results: * None. @@ -548,20 +461,21 @@ Tcl_MutexLock( */ void -Tcl_MutexUnlock( - Tcl_Mutex *mutexPtr) /* Really (pthread_mutex_t **) */ +Tcl_MutexUnlock(mutexPtr) + Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ { pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **)mutexPtr; pthread_mutex_unlock(pmutexPtr); } + /* *---------------------------------------------------------------------- * * TclpFinalizeMutex -- * - * This procedure is invoked to clean up one mutex. This is only safe to - * call at the end of time. + * This procedure is invoked to clean up one mutex. This is only + * safe to call at the end of time. * * This assumes the Master Lock is held. * @@ -575,25 +489,194 @@ Tcl_MutexUnlock( */ void -TclpFinalizeMutex( - Tcl_Mutex *mutexPtr) +TclpFinalizeMutex(mutexPtr) + Tcl_Mutex *mutexPtr; { pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **)mutexPtr; if (pmutexPtr != NULL) { - pthread_mutex_destroy(pmutexPtr); - ckfree((char *) pmutexPtr); + pthread_mutex_destroy(pmutexPtr); + ckfree((char *)pmutexPtr); *mutexPtr = NULL; } } + + +/* + *---------------------------------------------------------------------- + * + * TclpThreadDataKeyInit -- + * + * This procedure initializes a thread specific data block key. + * Each thread has table of pointers to thread specific data. + * all threads agree on which table entry is used by each module. + * this is remembered in a "data key", that is just an index into + * this table. To allow self initialization, the interface + * passes a pointer to this key and the first thread to use + * the key fills in the pointer to the key. The key should be + * a process-wide static. + * + * Results: + * None. + * + * Side effects: + * Will allocate memory the first time this process calls for + * this key. In this case it modifies its argument + * to hold the pointer to information about the key. + * + *---------------------------------------------------------------------- + */ + +void +TclpThreadDataKeyInit(keyPtr) + Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, + * really (pthread_key_t **) */ +{ + pthread_key_t *pkeyPtr; + + MASTER_LOCK; + if (*keyPtr == NULL) { + pkeyPtr = (pthread_key_t *)ckalloc(sizeof(pthread_key_t)); + pthread_key_create(pkeyPtr, NULL); + *keyPtr = (Tcl_ThreadDataKey)pkeyPtr; + TclRememberDataKey(keyPtr); + } + MASTER_UNLOCK; +} + +/* + *---------------------------------------------------------------------- + * + * TclpThreadDataKeyGet -- + * + * This procedure returns a pointer to a block of thread local storage. + * + * Results: + * A thread-specific pointer to the data structure, or NULL + * if the memory has not been assigned to this key for this thread. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +VOID * +TclpThreadDataKeyGet(keyPtr) + Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, + * really (pthread_key_t **) */ +{ + pthread_key_t *pkeyPtr = *(pthread_key_t **)keyPtr; + if (pkeyPtr == NULL) { + return NULL; + } else { + return (VOID *)pthread_getspecific(*pkeyPtr); + } +} + + +/* + *---------------------------------------------------------------------- + * + * TclpThreadDataKeySet -- + * + * This procedure sets the pointer to a block of thread local storage. + * + * Results: + * None. + * + * Side effects: + * Sets up the thread so future calls to TclpThreadDataKeyGet with + * this key will return the data pointer. + * + *---------------------------------------------------------------------- + */ + +void +TclpThreadDataKeySet(keyPtr, data) + Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, + * really (pthread_key_t **) */ + VOID *data; /* Thread local storage */ +{ + pthread_key_t *pkeyPtr = *(pthread_key_t **)keyPtr; + pthread_setspecific(*pkeyPtr, data); +} + +/* + *---------------------------------------------------------------------- + * + * TclpFinalizeThreadData -- + * + * This procedure cleans up the thread-local storage. This is + * called once for each thread. + * + * Results: + * None. + * + * Side effects: + * Frees up all thread local storage. + * + *---------------------------------------------------------------------- + */ + +void +TclpFinalizeThreadData(keyPtr) + Tcl_ThreadDataKey *keyPtr; +{ + VOID *result; + pthread_key_t *pkeyPtr; + + if (*keyPtr != NULL) { + pkeyPtr = *(pthread_key_t **)keyPtr; + result = (VOID *)pthread_getspecific(*pkeyPtr); + if (result != NULL) { + ckfree((char *)result); + pthread_setspecific(*pkeyPtr, (void *)NULL); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpFinalizeThreadDataKey -- + * + * This procedure is invoked to clean up one key. This is a + * process-wide storage identifier. The thread finalization code + * cleans up the thread local storage itself. + * + * This assumes the master lock is held. + * + * Results: + * None. + * + * Side effects: + * The key is deallocated. + * + *---------------------------------------------------------------------- + */ + +void +TclpFinalizeThreadDataKey(keyPtr) + Tcl_ThreadDataKey *keyPtr; +{ + pthread_key_t *pkeyPtr; + if (*keyPtr != NULL) { + pkeyPtr = *(pthread_key_t **)keyPtr; + pthread_key_delete(*pkeyPtr); + ckfree((char *)pkeyPtr); + *keyPtr = NULL; + } +} + /* *---------------------------------------------------------------------- * * Tcl_ConditionWait -- * - * This procedure is invoked to wait on a condition variable. The mutex - * is automically released as part of the wait, and automatically grabbed - * when the condition is signaled. + * This procedure is invoked to wait on a condition variable. + * The mutex is automically released as part of the wait, and + * automatically grabbed when the condition is signaled. * * The mutex must be held when this procedure is called. * @@ -601,18 +684,18 @@ TclpFinalizeMutex( * None. * * Side effects: - * May block the current thread. The mutex is aquired when this returns. - * Will allocate memory for a pthread_mutex_t and initialize this the - * first time this Tcl_Mutex is used. + * May block the current thread. The mutex is aquired when + * this returns. Will allocate memory for a pthread_mutex_t + * and initialize this the first time this Tcl_Mutex is used. * *---------------------------------------------------------------------- */ void -Tcl_ConditionWait( - Tcl_Condition *condPtr, /* Really (pthread_cond_t **) */ - Tcl_Mutex *mutexPtr, /* Really (pthread_mutex_t **) */ - Tcl_Time *timePtr) /* Timeout on waiting period */ +Tcl_ConditionWait(condPtr, mutexPtr, timePtr) + Tcl_Condition *condPtr; /* Really (pthread_cond_t **) */ + Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ + Tcl_Time *timePtr; /* Timeout on waiting period */ { pthread_cond_t *pcondPtr; pthread_mutex_t *pmutexPtr; @@ -621,13 +704,13 @@ Tcl_ConditionWait( if (*condPtr == NULL) { MASTER_LOCK; - /* - * Double check inside mutex to avoid race, then initialize condition - * variable if necessary. + /* + * Double check inside mutex to avoid race, + * then initialize condition variable if necessary. */ if (*condPtr == NULL) { - pcondPtr = (pthread_cond_t *) ckalloc(sizeof(pthread_cond_t)); + pcondPtr = (pthread_cond_t *)ckalloc(sizeof(pthread_cond_t)); pthread_cond_init(pcondPtr, NULL); *condPtr = (Tcl_Condition)pcondPtr; TclRememberCondition(condPtr); @@ -661,8 +744,8 @@ Tcl_ConditionWait( * * This procedure is invoked to signal a condition variable. * - * The mutex must be held during this call to avoid races, but this - * interface does not enforce that. + * The mutex must be held during this call to avoid races, + * but this interface does not enforce that. * * Results: * None. @@ -674,8 +757,8 @@ Tcl_ConditionWait( */ void -Tcl_ConditionNotify( - Tcl_Condition *condPtr) +Tcl_ConditionNotify(condPtr) + Tcl_Condition *condPtr; { pthread_cond_t *pcondPtr = *((pthread_cond_t **)condPtr); if (pcondPtr != NULL) { @@ -686,14 +769,15 @@ Tcl_ConditionNotify( */ } } + /* *---------------------------------------------------------------------- * * TclpFinalizeCondition -- * - * This procedure is invoked to clean up a condition variable. This is - * only safe to call at the end of time. + * This procedure is invoked to clean up a condition variable. + * This is only safe to call at the end of time. * * This assumes the Master Lock is held. * @@ -707,13 +791,13 @@ Tcl_ConditionNotify( */ void -TclpFinalizeCondition( - Tcl_Condition *condPtr) +TclpFinalizeCondition(condPtr) + Tcl_Condition *condPtr; { pthread_cond_t *pcondPtr = *(pthread_cond_t **)condPtr; if (pcondPtr != NULL) { pthread_cond_destroy(pcondPtr); - ckfree((char *) pcondPtr); + ckfree((char *)pcondPtr); *condPtr = NULL; } } @@ -724,8 +808,8 @@ TclpFinalizeCondition( * * TclpReaddir, TclpInetNtoa -- * - * These procedures replace core C versions to be used in a threaded - * environment. + * These procedures replace core C versions to be used in a + * threaded environment. * * Results: * See documentation of C functions. @@ -734,22 +818,19 @@ TclpFinalizeCondition( * See documentation of C functions. * * Notes: - * TclpReaddir is no longer used by the core (see 1095909), but it - * appears in the internal stubs table (see #589526). - * + * TclpReaddir is no longer used by the core (see 1095909), + * but it appears in the internal stubs table (see #589526). *---------------------------------------------------------------------- */ Tcl_DirEntry * -TclpReaddir( - DIR * dir) +TclpReaddir(DIR * dir) { return TclOSreaddir(dir); } char * -TclpInetNtoa( - struct in_addr addr) +TclpInetNtoa(struct in_addr addr) { #ifdef TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); @@ -761,18 +842,17 @@ TclpInetNtoa( return inet_ntoa(addr); #endif } - -#ifdef TCL_THREADS + +#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) && !defined(TCL_MEM_DEBUG) /* * Additions by AOL for specialized thread memory allocator. */ - #ifdef USE_THREAD_ALLOC static volatile int initialized = 0; -static pthread_key_t key; +static pthread_key_t key; typedef struct allocMutex { - Tcl_Mutex tlock; + Tcl_Mutex tlock; pthread_mutex_t plock; } allocMutex; @@ -780,49 +860,41 @@ Tcl_Mutex * TclpNewAllocMutex(void) { struct allocMutex *lockPtr; - register pthread_mutex_t *plockPtr; lockPtr = malloc(sizeof(struct allocMutex)); if (lockPtr == NULL) { - Tcl_Panic("could not allocate lock"); + panic("could not allocate lock"); } - plockPtr = &lockPtr->plock; - lockPtr->tlock = (Tcl_Mutex) plockPtr; + lockPtr->tlock = (Tcl_Mutex) &lockPtr->plock; pthread_mutex_init(&lockPtr->plock, NULL); return &lockPtr->tlock; } void -TclpFreeAllocMutex( - Tcl_Mutex *mutex) /* The alloc mutex to free. */ +TclpFreeAllocMutex(mutex) + Tcl_Mutex *mutex; /* The alloc mutex to free. */ { allocMutex* lockPtr = (allocMutex*) mutex; - if (!lockPtr) { - return; - } + if (!lockPtr) return; pthread_mutex_destroy(&lockPtr->plock); free(lockPtr); } -void -TclpFreeAllocCache( - void *ptr) +void TclpFreeAllocCache(ptr) + void *ptr; { if (ptr != NULL) { - /* - * Called by the pthread lib when a thread exits - */ - - TclFreeAllocCache(ptr); - + /* + * Called by the pthread lib when a thread exits + */ + TclFreeAllocCache(ptr); } else if (initialized) { - /* - * Called by us in TclFinalizeThreadAlloc() during the library - * finalization initiated from Tcl_Finalize() - */ - - pthread_key_delete(key); - initialized = 0; + /* + * Called by us in TclFinalizeThreadAlloc() during + * the library finalization initiated from Tcl_Finalize() + */ + pthread_key_delete(key); + initialized = 0; } } @@ -841,18 +913,10 @@ TclpGetAllocCache(void) } void -TclpSetAllocCache( - void *arg) +TclpSetAllocCache(void *arg) { pthread_setspecific(key, arg); } + #endif /* USE_THREAD_ALLOC */ #endif /* TCL_THREADS */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ |
