⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclunixthrd.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * tclUnixThrd.c -- * *	This file implements the UNIX-specific thread support. * * 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. * * SCCS:  @(#) tclUnixThrd.c 1.18 98/02/19 14:24:12 */#include "tclInt.h"#include "tclPort.h"#ifdef TCL_THREADS#include "pthread.h"typedef struct ThreadSpecificData {    char	    	nabuf[16];    struct tm   	gtbuf;    struct tm   	ltbuf;    struct {	Tcl_DirEntry ent;	char name[MAXNAMLEN+1];    } rdbuf;} 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. */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. */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. */static pthread_mutex_t allocLock = PTHREAD_MUTEX_INITIALIZER;static pthread_mutex_t *allocLockPtr = &allocLock;/* * These are for the critical sections inside this file. */#define MASTER_LOCK	pthread_mutex_lock(&masterLock)#define MASTER_UNLOCK	pthread_mutex_unlock(&masterLock)#endif /* TCL_THREADS *//* *---------------------------------------------------------------------- * * Tcl_CreateThread -- * *	This procedure creates a new thread. * * Results: *	TCL_OK if the thread could be created.  The thread ID is *	returned in a parameter. * * Side effects: *	A new thread is created. * *---------------------------------------------------------------------- */intTcl_CreateThread(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;    int result;    pthread_attr_init(&attr);    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE    if (stackSize != TCL_THREAD_STACK_DEFAULT) {        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):	 *    make MEM_DEBUG_FLAGS=-DTCL_THREAD_STACK_MIN=131072L	 *	 * This solution is not optimal, as we should allow the user to	 * specify a size at runtime, but we don't want to slow this function	 * down, and that would still leave the main thread at the default.	 */        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    if (! (flags & TCL_THREAD_JOINABLE)) {        pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);    }    if (pthread_create((pthread_t *)idPtr, &attr,	    (void * (*)())proc, (void *)clientData) &&	    pthread_create((pthread_t *)idPtr, NULL,		    (void * (*)())proc, (void *)clientData)) {	result = TCL_ERROR;    } else {	result = TCL_OK;    }    pthread_attr_destroy(&attr);    return result;#else    return TCL_ERROR;#endif /* TCL_THREADS */}/* *---------------------------------------------------------------------- * * Tcl_JoinThread -- * *	This procedure waits upon the exit of the specified thread. * * Results: *	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. * *---------------------------------------------------------------------- */intTcl_JoinThread(id, state)    Tcl_ThreadId id;	/* 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;    result = pthread_join ((pthread_t) id, (VOID**) state);    return (result == 0) ? TCL_OK : TCL_ERROR;#else    return TCL_ERROR;#endif}#ifdef TCL_THREADS/* *---------------------------------------------------------------------- * * TclpThreadExit -- * *	This procedure terminates the current thread. * * Results: *	None. * * Side effects: *	This procedure terminates the current thread. * *---------------------------------------------------------------------- */voidTclpThreadExit(status)    int status;{    pthread_exit((VOID *)status);}#endif /* TCL_THREADS *//* *---------------------------------------------------------------------- * * Tcl_GetCurrentThread -- * *	This procedure returns the ID of the currently running thread. * * Results: *	A thread ID. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_ThreadIdTcl_GetCurrentThread(){#ifdef TCL_THREADS    return (Tcl_ThreadId) pthread_self();#else    return (Tcl_ThreadId) 0;#endif}/* *---------------------------------------------------------------------- * * 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. * * Results: *	None. * * Side effects: *	Acquire the initialization mutex. * *---------------------------------------------------------------------- */voidTclpInitLock(){#ifdef TCL_THREADS    pthread_mutex_lock(&initLock);#endif}/* *---------------------------------------------------------------------- * * TclpInitUnlock * *	This procedure is used to release a lock that serializes initialization *	and finalization of Tcl. * * Results: *	None. * * Side effects: *	Release the initialization mutex. * *---------------------------------------------------------------------- */voidTclpInitUnlock(){#ifdef TCL_THREADS    pthread_mutex_unlock(&initLock);#endif}/* *---------------------------------------------------------------------- * * 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 lock must be different than the initLock because the *	initLock is held during creation of syncronization objects. * * Results: *	None. * * Side effects: *	Acquire the master mutex. * *---------------------------------------------------------------------- */voidTclpMasterLock(){#ifdef TCL_THREADS    pthread_mutex_lock(&masterLock);#endif}/* *---------------------------------------------------------------------- * * TclpMasterUnlock * *	This procedure is used to release a lock that serializes creation *	and finalization of synchronization objects. * * Results: *	None. * * Side effects: *	Release the master mutex. * *---------------------------------------------------------------------- */voidTclpMasterUnlock(){#ifdef TCL_THREADS    pthread_mutex_unlock(&masterLock);#endif}/* *---------------------------------------------------------------------- * * 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... * * Results: *	A pointer to a mutex that is suitable for passing to *	Tcl_MutexLock and Tcl_MutexUnlock. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_Mutex *Tcl_GetAllocMutex(){#ifdef TCL_THREADS    return (Tcl_Mutex *)&allocLockPtr;#else    return NULL;#endif}#ifdef TCL_THREADS/* *---------------------------------------------------------------------- * * 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. * * 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. * *---------------------------------------------------------------------- */voidTcl_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;	    TclRememberMutex(mutexPtr);	}	MASTER_UNLOCK;    }    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. * * Results: *	None. * * Side effects: *	The mutex is released when this returns. * *---------------------------------------------------------------------- */voidTcl_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 assumes the Master Lock is held. * * Results: *	None. * * Side effects: *	The mutex list is deallocated. * *---------------------------------------------------------------------- */voidTclpFinalizeMutex(mutexPtr)    Tcl_Mutex *mutexPtr;{    pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **)mutexPtr;    if (pmutexPtr != NULL) {	ckfree((char *)pmutexPtr);	*mutexPtr = NULL;    }}/* *----------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -