summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixThrd.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tclUnixThrd.c')
-rw-r--r--unix/tclUnixThrd.c167
1 files changed, 88 insertions, 79 deletions
diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c
index f8131c0..d34bc88 100644
--- a/unix/tclUnixThrd.c
+++ b/unix/tclUnixThrd.c
@@ -5,19 +5,16 @@
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 2008 by George Peter Staplin
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * SCCS: @(#) tclUnixThrd.c 1.18 98/02/19 14:24:12
*/
#include "tclInt.h"
#ifdef TCL_THREADS
-#include "pthread.h"
-
typedef struct ThreadSpecificData {
char nabuf[16];
} ThreadSpecificData;
@@ -55,7 +52,6 @@ static pthread_mutex_t *allocLockPtr = &allocLock;
#define MASTER_UNLOCK pthread_mutex_unlock(&masterLock)
#endif /* TCL_THREADS */
-
/*
*----------------------------------------------------------------------
@@ -77,7 +73,7 @@ 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 */
+ 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
@@ -109,18 +105,19 @@ TclpThreadCreate(
*/
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);
}
-#endif
+#endif /* TCL_THREAD_STACK_MIN */
}
-#endif
+#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
+
if (! (flags & TCL_THREAD_JOINABLE)) {
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
}
-
if (pthread_create(&theThread, &attr,
(void * (*)(void *))proc, (void *)clientData) &&
pthread_create(&theThread, NULL,
@@ -157,13 +154,17 @@ 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. */
+ * thread we wait upon will be written into.
+ * May be NULL. */
{
#ifdef TCL_THREADS
int result;
+ unsigned long retcode, *retcodePtr = &retcode;
- result = pthread_join((pthread_t) threadId, (void**) state);
+ result = pthread_join((pthread_t) threadId, (void**) retcodePtr);
+ if (state) {
+ *state = (int) retcode;
+ }
return (result == 0) ? TCL_OK : TCL_ERROR;
#else
return TCL_ERROR;
@@ -191,56 +192,7 @@ void
TclpThreadExit(
int status)
{
- pthread_exit((VOID *)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.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclpThreadGetStackSize(void)
-{
-#if defined(HAVE_PTHREAD_SETSTACKSIZE) && defined(TclpPthreadGetAttrs)
- pthread_attr_t threadAttr; /* This will hold the thread attributes for
- * the current thread. */
- size_t stackSize;
-
- if (pthread_attr_init(&threadAttr) != 0) {
- return -1;
- }
- if (TclpPthreadGetAttrs(pthread_self(), &threadAttr) != 0) {
- pthread_attr_destroy(&threadAttr);
- return -1;
- }
- if (pthread_attr_getstacksize(&threadAttr, &stackSize) != 0) {
- pthread_attr_destroy(&threadAttr);
- return -1;
- }
- pthread_attr_destroy(&threadAttr);
- return (int) stackSize;
-#else
- /*
- * Cannot determine the real stack size of this thread. The caller might
- * want to try looking at the process accounting limits instead.
- */
-
- return 0;
-#endif
+ pthread_exit(INT2PTR(status));
}
#endif /* TCL_THREADS */
@@ -433,7 +385,8 @@ Tcl_Mutex *
Tcl_GetAllocMutex(void)
{
#ifdef TCL_THREADS
- return (Tcl_Mutex *)&allocLockPtr;
+ pthread_mutex_t **allocLockPtrPtr = &allocLockPtr;
+ return (Tcl_Mutex *) allocLockPtrPtr;
#else
return NULL;
#endif
@@ -467,6 +420,7 @@ Tcl_MutexLock(
Tcl_Mutex *mutexPtr) /* Really (pthread_mutex_t **) */
{
pthread_mutex_t *pmutexPtr;
+
if (*mutexPtr == NULL) {
MASTER_LOCK;
if (*mutexPtr == NULL) {
@@ -474,7 +428,7 @@ Tcl_MutexLock(
* Double inside master lock check to avoid a race condition.
*/
- pmutexPtr = (pthread_mutex_t *)ckalloc(sizeof(pthread_mutex_t));
+ pmutexPtr = ckalloc(sizeof(pthread_mutex_t));
pthread_mutex_init(pmutexPtr, NULL);
*mutexPtr = (Tcl_Mutex)pmutexPtr;
TclRememberMutex(mutexPtr);
@@ -506,7 +460,8 @@ void
Tcl_MutexUnlock(
Tcl_Mutex *mutexPtr) /* Really (pthread_mutex_t **) */
{
- pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **)mutexPtr;
+ pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **) mutexPtr;
+
pthread_mutex_unlock(pmutexPtr);
}
@@ -533,10 +488,11 @@ void
TclpFinalizeMutex(
Tcl_Mutex *mutexPtr)
{
- pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **)mutexPtr;
+ pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **) mutexPtr;
+
if (pmutexPtr != NULL) {
pthread_mutex_destroy(pmutexPtr);
- ckfree((char *) pmutexPtr);
+ ckfree(pmutexPtr);
*mutexPtr = NULL;
}
}
@@ -567,7 +523,7 @@ void
Tcl_ConditionWait(
Tcl_Condition *condPtr, /* Really (pthread_cond_t **) */
Tcl_Mutex *mutexPtr, /* Really (pthread_mutex_t **) */
- Tcl_Time *timePtr) /* Timeout on waiting period */
+ const Tcl_Time *timePtr) /* Timeout on waiting period */
{
pthread_cond_t *pcondPtr;
pthread_mutex_t *pmutexPtr;
@@ -582,9 +538,9 @@ Tcl_ConditionWait(
*/
if (*condPtr == NULL) {
- pcondPtr = (pthread_cond_t *) ckalloc(sizeof(pthread_cond_t));
+ pcondPtr = ckalloc(sizeof(pthread_cond_t));
pthread_cond_init(pcondPtr, NULL);
- *condPtr = (Tcl_Condition)pcondPtr;
+ *condPtr = (Tcl_Condition) pcondPtr;
TclRememberCondition(condPtr);
}
MASTER_UNLOCK;
@@ -666,9 +622,10 @@ TclpFinalizeCondition(
Tcl_Condition *condPtr)
{
pthread_cond_t *pcondPtr = *(pthread_cond_t **)condPtr;
+
if (pcondPtr != NULL) {
pthread_cond_destroy(pcondPtr);
- ckfree((char *) pcondPtr);
+ ckfree(pcondPtr);
*condPtr = NULL;
}
}
@@ -677,7 +634,7 @@ TclpFinalizeCondition(
/*
*----------------------------------------------------------------------
*
- * TclpReaddir, TclpLocaltime, TclpGmtime, TclpInetNtoa --
+ * TclpReaddir, TclpInetNtoa --
*
* These procedures replace core C versions to be used in a threaded
* environment.
@@ -702,19 +659,16 @@ TclpReaddir(
return TclOSreaddir(dir);
}
+#undef TclpInetNtoa
char *
TclpInetNtoa(
struct in_addr addr)
{
#ifdef TCL_THREADS
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- union {
- unsigned long l;
- unsigned char b[4];
- } u;
+ unsigned char *b = (unsigned char*) &addr.s_addr;
- u.l = (unsigned long) addr.s_addr;
- sprintf(tsdPtr->nabuf, "%u.%u.%u.%u", u.b[0], u.b[1], u.b[2], u.b[3]);
+ sprintf(tsdPtr->nabuf, "%u.%u.%u.%u", b[0], b[1], b[2], b[3]);
return tsdPtr->nabuf;
#else
return inet_ntoa(addr);
@@ -739,12 +693,14 @@ 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");
}
- lockPtr->tlock = (Tcl_Mutex) &lockPtr->plock;
+ plockPtr = &lockPtr->plock;
+ lockPtr->tlock = (Tcl_Mutex) plockPtr;
pthread_mutex_init(&lockPtr->plock, NULL);
return &lockPtr->tlock;
}
@@ -771,6 +727,7 @@ TclpFreeAllocCache(
*/
TclFreeAllocCache(ptr);
+ pthread_setspecific(key, NULL);
} else if (initialized) {
/*
@@ -804,6 +761,58 @@ TclpSetAllocCache(
pthread_setspecific(key, arg);
}
#endif /* USE_THREAD_ALLOC */
+
+void *
+TclpThreadCreateKey(void)
+{
+ pthread_key_t *ptkeyPtr;
+
+ ptkeyPtr = TclpSysAlloc(sizeof *ptkeyPtr, 0);
+ if (NULL == ptkeyPtr) {
+ Tcl_Panic("unable to allocate thread key!");
+ }
+
+ if (pthread_key_create(ptkeyPtr, NULL)) {
+ Tcl_Panic("unable to create pthread key!");
+ }
+
+ return ptkeyPtr;
+}
+
+void
+TclpThreadDeleteKey(
+ void *keyPtr)
+{
+ pthread_key_t *ptkeyPtr = keyPtr;
+
+ if (pthread_key_delete(*ptkeyPtr)) {
+ Tcl_Panic("unable to delete key!");
+ }
+
+ TclpSysFree(keyPtr);
+}
+
+void
+TclpThreadSetMasterTSD(
+ void *tsdKeyPtr,
+ void *ptr)
+{
+ pthread_key_t *ptkeyPtr = tsdKeyPtr;
+
+ if (pthread_setspecific(*ptkeyPtr, ptr)) {
+ Tcl_Panic("unable to set master TSD value");
+ }
+}
+
+void *
+TclpThreadGetMasterTSD(
+ void *tsdKeyPtr)
+{
+ pthread_key_t *ptkeyPtr = tsdKeyPtr;
+
+ return pthread_getspecific(*ptkeyPtr);
+}
+
#endif /* TCL_THREADS */
/*