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

📄 tclwinthrd.c

📁 这是leon3处理器的交叉编译链
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * tclWinThread.c -- * *	This file implements the Windows-specific thread operations. * * Copyright (c) 1998 by Sun Microsystems, Inc. * Copyright (c) 1999 by Scriptics Corporation * * 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.20 2002/08/29 19:02:19 andreas_kupries Exp $ */#include "tclWinInt.h"#include <fcntl.h>#include <io.h>#include <sys/stat.h>/* * This is the master lock used to serialize access to other * serialization data structures. */static CRITICAL_SECTION masterLock;static int init = 0;#define MASTER_LOCK  EnterCriticalSection(&masterLock)#define MASTER_UNLOCK  LeaveCriticalSection(&masterLock)/* * This is the master lock used to serialize initialization and finalization * of Tcl as a whole. */static CRITICAL_SECTION initLock;/* * allocLock is used by Tcl's version of malloc for synchronization. * For obvious reasons, cannot use any dyamically allocated storage. */static CRITICAL_SECTION allocLock;static Tcl_Mutex allocLockPtr = (Tcl_Mutex) &allocLock;/* * The joinLock serializes Create- and ExitThread. This is necessary to * prevent a race where a new joinable thread exits before the creating * thread had the time to create the necessary data structures in the * emulation layer. */static CRITICAL_SECTION joinLock;/* * Condition variables are implemented with a combination of a  * per-thread Windows Event and a per-condition waiting queue. * The idea is that each thread has its own Event that it waits * on when it is doing a ConditionWait; it uses the same event for * all condition variables because it only waits on one at a time. * Each condition variable has a queue of waiting threads, and a  * mutex used to serialize access to this queue. * * Special thanks to David Nichols and * Jim Davidson for advice on the Condition Variable implementation. *//* * The per-thread event and queue pointers. */typedef struct ThreadSpecificData {    HANDLE condEvent;			/* Per-thread condition event */    struct ThreadSpecificData *nextPtr;	/* Queue pointers */    struct ThreadSpecificData *prevPtr;    int flags;				/* See flags below */} ThreadSpecificData;static Tcl_ThreadDataKey dataKey;/* * State bits for the thread. * WIN_THREAD_UNINIT		Uninitialized.  Must be zero because *				of the way ThreadSpecificData is created. * WIN_THREAD_RUNNING		Running, not waiting. * WIN_THREAD_BLOCKED		Waiting, or trying to wait. * WIN_THREAD_DEAD		Dying - no per-thread event anymore. */ #define WIN_THREAD_UNINIT	0x0#define WIN_THREAD_RUNNING	0x1#define WIN_THREAD_BLOCKED	0x2#define WIN_THREAD_DEAD		0x4/* * The per condition queue pointers and the * Mutex used to serialize access to the queue. */typedef struct WinCondition {    CRITICAL_SECTION condLock;	/* Lock to serialize queuing on the condition */    struct ThreadSpecificData *firstPtr;	/* Queue pointers */    struct ThreadSpecificData *lastPtr;} WinCondition;/* *---------------------------------------------------------------------- * * 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 */{    HANDLE tHandle;    EnterCriticalSection(&joinLock);#if defined(__MSVCRT__) || defined(__BORLANDC__)    tHandle = (HANDLE) _beginthreadex(NULL, (unsigned) stackSize, proc,	clientData, 0, (unsigned *)idPtr);#else    tHandle = CreateThread(NULL, (DWORD) stackSize,	    (LPTHREAD_START_ROUTINE) proc, (LPVOID) clientData,	    (DWORD) 0, (LPDWORD)idPtr);#endif    if (tHandle == NULL) {        LeaveCriticalSection(&joinLock);	return TCL_ERROR;    } else {        if (flags & TCL_THREAD_JOINABLE) {	    TclRememberJoinableThread (*idPtr);	}	/*	 * The only purpose of this is to decrement the reference count so the	 * OS resources will be reaquired when the thread closes.	 */	CloseHandle(tHandle);	LeaveCriticalSection(&joinLock);	return TCL_OK;    }}/* *---------------------------------------------------------------------- * * 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, result)    Tcl_ThreadId id;	/* Id of the thread to wait upon */    int*     result;	/* Reference to the storage the result			 * of the thread we wait upon will be			 * written into. */{    return TclJoinThread (id, result);}/* *---------------------------------------------------------------------- * * TclpThreadExit -- * *	This procedure terminates the current thread. * * Results: *	None. * * Side effects: *	This procedure terminates the current thread. * *---------------------------------------------------------------------- */voidTclpThreadExit(status)    int status;{    EnterCriticalSection(&joinLock);    TclSignalExitThread (Tcl_GetCurrentThread (), status);    LeaveCriticalSection(&joinLock);#if defined(__MSVCRT__) || defined(__BORLANDC__)    _endthreadex((unsigned) status);#else    ExitThread((DWORD) status);#endif}/* *---------------------------------------------------------------------- * * Tcl_GetCurrentThread -- * *	This procedure returns the ID of the currently running thread. * * Results: *	A thread ID. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_ThreadIdTcl_GetCurrentThread(){    return (Tcl_ThreadId)GetCurrentThreadId();}/* *---------------------------------------------------------------------- * * 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(){    if (!init) {	/*	 * There is a fundamental race here that is solved by creating	 * the first Tcl interpreter in a single threaded environment.	 * Once the interpreter has been created, it is safe to create	 * more threads that create interpreters in parallel.	 */	init = 1;	InitializeCriticalSection(&joinLock);	InitializeCriticalSection(&initLock);	InitializeCriticalSection(&masterLock);    }    EnterCriticalSection(&initLock);}/* *---------------------------------------------------------------------- * * 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(){    LeaveCriticalSection(&initLock);}/* *---------------------------------------------------------------------- * * TclpMasterLock * *	This procedure is used to grab a lock that serializes creation *	of mutexes, condition variables, and thread local storage keys. * *	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(){    if (!init) {	/*	 * There is a fundamental race here that is solved by creating	 * the first Tcl interpreter in a single threaded environment.	 * Once the interpreter has been created, it is safe to create	 * more threads that create interpreters in parallel.	 */	init = 1;	InitializeCriticalSection(&joinLock);	InitializeCriticalSection(&initLock);	InitializeCriticalSection(&masterLock);    }    EnterCriticalSection(&masterLock);}/* *---------------------------------------------------------------------- * * 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    static int once = 0;    if (!once) {	InitializeCriticalSection(&allocLock);	once = 1;    }    return &allocLockPtr;#else    return NULL;#endif}#ifdef TCL_THREADS/* locally used prototype */static void FinalizeConditionEvent(ClientData data);/* *---------------------------------------------------------------------- * * TclpMasterUnlock * *	This procedure is used to release a lock that serializes creation *	and deletion of synchronization objects. * * Results: *	None. * * Side effects: *	Release the master mutex. * *---------------------------------------------------------------------- */voidTclpMasterUnlock(){    LeaveCriticalSection(&masterLock);}/* *---------------------------------------------------------------------- * * Tcl_MutexLock -- * *	This procedure is invoked to lock a mutex.  This is a self  *	initializing mutex that is automatically finalized during *	Tcl_Finalize. * * Results: *	None. * * Side effects: *	May block the current thread.  The mutex is aquired when *	this returns. * *---------------------------------------------------------------------- */voidTcl_MutexLock(mutexPtr)    Tcl_Mutex *mutexPtr;	/* The lock */{    CRITICAL_SECTION *csPtr;    if (*mutexPtr == NULL) {	MASTER_LOCK;	/* 	 * Double inside master lock check to avoid a race.	 */	if (*mutexPtr == NULL) {	    csPtr = (CRITICAL_SECTION *)ckalloc(sizeof(CRITICAL_SECTION));	    InitializeCriticalSection(csPtr);	    *mutexPtr = (Tcl_Mutex)csPtr;	    TclRememberMutex(mutexPtr);	}	MASTER_UNLOCK;    }    csPtr = *((CRITICAL_SECTION **)mutexPtr);    EnterCriticalSection(csPtr);}/* *---------------------------------------------------------------------- * * Tcl_MutexUnlock -- * *	This procedure is invoked to unlock a mutex. * * Results: *	None. * * Side effects: *	The mutex is released when this returns. * *---------------------------------------------------------------------- */voidTcl_MutexUnlock(mutexPtr)    Tcl_Mutex *mutexPtr;	/* The lock */{    CRITICAL_SECTION *csPtr = *((CRITICAL_SECTION **)mutexPtr);    LeaveCriticalSection(csPtr);}/* *---------------------------------------------------------------------- * * TclpFinalizeMutex -- * *	This procedure is invoked to clean up one mutex.  This is only *	safe to call at the end of time. * * Results: *	None. * * Side effects: *	The mutex list is deallocated. * *---------------------------------------------------------------------- */voidTclpFinalizeMutex(mutexPtr)    Tcl_Mutex *mutexPtr;{    CRITICAL_SECTION *csPtr = *(CRITICAL_SECTION **)mutexPtr;    if (csPtr != NULL) {	DeleteCriticalSection(csPtr);	ckfree((char *)csPtr);	*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.

⌨️ 快捷键说明

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