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

📄 tclmacthrd.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 2 页
字号:
    Tcl_Mutex *mutexPtr;	/* Really (pthread_mutex_t **) */{/* There is nothing to do on the Mac */}/* *---------------------------------------------------------------------- * * 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;{/* There is nothing to do on the Mac */}/* *---------------------------------------------------------------------- * * 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. * *      There is no system-wide support for thread specific data on the  *	Mac.  So we implement this as an array of pointers.  The keys are *	allocated sequentially, and each key maps to a slot in the table. *      The table element points to a linked list of the instances of *	the data for each thread. * * Results: *	None. * * Side effects: *	Will bump the key counter if this is the first time this key *      has been initialized.  May grow the DataKeyArray if that is *	necessary. * *---------------------------------------------------------------------- */voidTclpThreadDataKeyInit(keyPtr)    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,				 * really (pthread_key_t **) */{                if (*keyPtr == NULL) {        keyCounter += 1;	*keyPtr = (Tcl_ThreadDataKey) keyCounter;	if (keyCounter > maxNumKeys) {	    TclMacThrdData **newArray;	    int i, oldMax = maxNumKeys;	     	    maxNumKeys = maxNumKeys + TCL_MAC_INITIAL_KEYSIZE;	     	    newArray = (TclMacThrdData **) 	            ckalloc(maxNumKeys * sizeof(TclMacThrdData *));	     	    for (i = 0; i < oldMax; i++) {	        newArray[i] = tclMacDataKeyArray[i];	    }	    for (i = oldMax; i < maxNumKeys; i++) {	        newArray[i] = NULL;	    }	     	    if (tclMacDataKeyArray != NULL) {		ckfree((char *) tclMacDataKeyArray);	    }	    tclMacDataKeyArray = newArray;	     	}             	/* TclRememberDataKey(keyPtr); */    }}/* *---------------------------------------------------------------------- * * 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 **) */{    TclMacThrdData *dataPtr;        dataPtr = GetThreadDataStruct(*keyPtr);        if (dataPtr == NULL) {        return NULL;    } else {        return dataPtr->data;    }}/* *---------------------------------------------------------------------- * * 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. * *---------------------------------------------------------------------- */voidTclpThreadDataKeySet(keyPtr, data)    Tcl_ThreadDataKey *keyPtr;	/* Identifier for the data chunk,				 * really (pthread_key_t **) */    VOID *data;			/* Thread local storage */{    TclMacThrdData *dataPtr;    ThreadID curThread;        dataPtr = GetThreadDataStruct(*keyPtr);        /*      * Is it legal to reset the thread data like this?     * And if so, who owns the memory?     */         if (dataPtr != NULL) {        dataPtr->data = data;    } else {        dataPtr = (TclMacThrdData *) ckalloc(sizeof(TclMacThrdData));        GetCurrentThread(&curThread);        dataPtr->threadID = curThread;        dataPtr->data = data;        dataPtr->next = tclMacDataKeyArray[(int) *keyPtr - 1];        tclMacDataKeyArray[(int) *keyPtr - 1] = dataPtr;   }}/* *---------------------------------------------------------------------- * * 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. * *---------------------------------------------------------------------- */voidTclpFinalizeThreadData(keyPtr)    Tcl_ThreadDataKey *keyPtr;{    TclMacThrdData *dataPtr;        if (*keyPtr != NULL) {        dataPtr = RemoveThreadDataStruct(*keyPtr);        	if ((dataPtr != NULL) && (dataPtr->data != NULL)) {	    ckfree((char *) dataPtr->data);	    ckfree((char *) dataPtr);	}    }}/* *---------------------------------------------------------------------- * * 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. * *      On the Mac, there is really nothing to do here, since the key *      is just an array index.  But we set the key to 0 just in case *	someone else is relying on that. * * Results: *	None. * * Side effects: *	The keyPtr value is set to 0. * *---------------------------------------------------------------------- */voidTclpFinalizeThreadDataKey(keyPtr)    Tcl_ThreadDataKey *keyPtr;{    ckfree((char *) tclMacDataKeyArray[(int) *keyPtr - 1]);    tclMacDataKeyArray[(int) *keyPtr - 1] = NULL;    *keyPtr = NULL;}/* *---------------------------------------------------------------------- * * GetThreadDataStruct -- * *	This procedure gets the data structure corresponding to *      keyVal for the current process. * * Results: *	The requested key data. * * Side effects: *	None. * *---------------------------------------------------------------------- */TclMacThrdData *GetThreadDataStruct(keyVal)    Tcl_ThreadDataKey keyVal;{    ThreadID curThread;    TclMacThrdData *dataPtr;        /*     * The keyPtr will only be greater than keyCounter is someone     * has passed us a key without getting the value from      * TclpInitDataKey.     */         if ((int) keyVal <= 0)  {        return NULL;    } else if ((int) keyVal > keyCounter) {        panic("illegal data key value");    }        GetCurrentThread(&curThread);        for (dataPtr = tclMacDataKeyArray[(int) keyVal - 1]; dataPtr != NULL;            dataPtr = dataPtr->next) {        if (dataPtr->threadID ==  curThread) {            break;        }    }        return dataPtr;}/* *---------------------------------------------------------------------- * * RemoveThreadDataStruct -- * *	This procedure removes the data structure corresponding to *      keyVal for the current process from the list kept for keyVal. * * Results: *	The requested key data is removed from the list, and a pointer  *      to it is returned. * * Side effects: *	None. * *---------------------------------------------------------------------- */TclMacThrdData *RemoveThreadDataStruct(keyVal)    Tcl_ThreadDataKey keyVal;{    ThreadID curThread;    TclMacThrdData *dataPtr, *prevPtr;             if ((int) keyVal <= 0)  {        return NULL;    } else if ((int) keyVal > keyCounter) {        panic("illegal data key value");    }        GetCurrentThread(&curThread);        for (dataPtr = tclMacDataKeyArray[(int) keyVal - 1], prevPtr = NULL;             dataPtr != NULL;            prevPtr = dataPtr, dataPtr = dataPtr->next) {        if (dataPtr->threadID == curThread) {            break;        }    }        if (dataPtr == NULL) {        /* No body */    } else if ( prevPtr == NULL) {        tclMacDataKeyArray[(int) keyVal - 1] = dataPtr->next;    } else {        prevPtr->next = dataPtr->next;    }        return dataPtr; }/* *---------------------------------------------------------------------- * * Tcl_ConditionWait -- * *	This procedure is invoked to wait on a condition variable. *	On the Mac, mutexes are no-ops, and we just yield.  After *	all, it is the application's job to loop till the condition  *	variable is changed... * * * Results: *	None. * * Side effects: *	Will block the current thread till someone else yields. * *---------------------------------------------------------------------- */voidTcl_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 */{    if (TclMacHaveThreads()) {        YieldToAnyThread();    }}/* *---------------------------------------------------------------------- * * Tcl_ConditionNotify -- * *	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. * * Results: *	None. * * Side effects: *	May unblock another thread. * *---------------------------------------------------------------------- */voidTcl_ConditionNotify(condPtr)    Tcl_Condition *condPtr;{    if (TclMacHaveThreads()) {         YieldToAnyThread();    }}/* *---------------------------------------------------------------------- * * TclpFinalizeCondition -- * *	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. * * Results: *	None. * * Side effects: *	The condition variable is deallocated. * *---------------------------------------------------------------------- */voidTclpFinalizeCondition(condPtr)    Tcl_Condition *condPtr;{    /* Nothing to do on the Mac */}#endif /* TCL_THREADS */

⌨️ 快捷键说明

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