📄 tlibvx.cxx
字号:
/* * tlibvx.cxx * * Thread library implementation for VxWorks * * Portable Windows Library * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: tlibvx.cxx,v $ * Revision 1.4 2004/07/11 07:56:36 csoutheren * Applied jumbo VxWorks patch, thanks to Eize Slange * * * Revision 1.3 2003/05/21 00:49:16 csoutheren * Added PreShutdown to ~PProcess * * Revision 1.2 2003/02/26 01:14:27 robertj * Fixed race condition where thread can terminatebefore an IsSuspeded() call * occurs and cause an assert, thanks Sebastian Meyer * * Revision 1.1 2002/11/05 01:43:39 robertj * Added missing VxWorks files. Thanks Andreas Sikkema * * Revision 1.0 ?????????????*/class PProcess;class PSemaphore;#include <ptlib.h>#include <ptlib/socket.h>#include <trclib.h>#include <usrlib.h>// Forward to undocumented system callextern "C" void dbgPrintCall(INSTR * callAdrs, int funcAdrs, int nargs, UINT32 * pArgs);#define VX_LOWEST_PRIORITY 250#define VX_LOW_PRIORITY 200#define VX_NORMAL_PRIORITY 150#define VX_DISPLAY_PRIORITY 100#define VX_URGENT_DISPLAY_PRIORITY 50 ///////////////////////////////////////////////////////////////////////////////// Critical Section Implementation// -------------------------------class CCriticalSection {public: CCriticalSection(); ~CCriticalSection(); void Lock(); void Unlock();private: int intLevel; STATUS taskLocked; bool locked;};CCriticalSection::CCriticalSection(){ intLevel = 0; taskLocked = ERROR; locked = false;}CCriticalSection::~CCriticalSection(){ // Unlock anyway when someone forgot to call Unlock after Lock if (locked == true) Unlock();}void CCriticalSection::Lock(){ if (locked == false) { if (::intContext() == FALSE) taskLocked = ::taskLock(); else taskLocked = ERROR; intLevel = ::intLock(); locked = true; }}void CCriticalSection::Unlock(){ if (locked == true) { ::intUnlock(intLevel); if (taskLocked == OK) ::taskUnlock(); locked = false; }}///////////////////////////////////////////////////////////////////////////////// Threadsstatic int const priorities[] = { VX_LOWEST_PRIORITY, VX_LOW_PRIORITY, VX_NORMAL_PRIORITY, VX_DISPLAY_PRIORITY, VX_URGENT_DISPLAY_PRIORITY};int PThread::ThreadFunction(void *threadPtr){ PAssertNULL(threadPtr); PThread * thread = (PThread *)threadPtr; PProcess & process = PProcess::Current(); process.activeThreadMutex.Wait(); process.activeThreads.SetAt(thread->PX_threadId, thread); process.activeThreadMutex.Signal(); process.SignalTimerChange(); if (::semTake(thread->syncPoint, WAIT_FOREVER) == OK) { if (::semDelete(thread->syncPoint) == OK) thread->syncPoint = NULL; thread->Main(); } else printf("::ThreadFunction> ::semTake failed, errno=0x%X\n",errno); // And delete from administration process.activeThreadMutex.Wait(); process.activeThreads.SetAt(thread->PX_threadId, NULL); process.activeThreadMutex.Signal(); thread->PX_threadId = 0; return 0;}void PThread::Trace(PThreadIdentifer threadId){ if (threadId == 0) threadId = PThread::GetCurrentThreadId(); printf("Task name=%s\n", ::taskName(threadId)); ::taskRegsShow(threadId); REG_SET regSet; if (::taskRegsGet(threadId, ®Set) != ERROR) ::trcStack(®Set, (FUNCPTR)dbgPrintCall, threadId); else printf("::Terminate> ::taskRegsGet failed, errno=0x%X\n", errno); ::taskShow(0, 2); printf("\n"); ::checkStack(0);}PThread::PThread() : PX_threadId(ERROR), priority(VX_NORMAL_PRIORITY), originalStackSize(0){}PThread::PThread(PINDEX stackSize, AutoDeleteFlag deletion, Priority priorityLevel, const PString & name){ PAssert(stackSize > 0, PInvalidParameter); autoDelete = (deletion == AutoDeleteThread); originalStackSize = stackSize; priority = priorities[priorityLevel]; syncPoint = ::semMCreate(SEM_Q_FIFO); if (syncPoint != NULL) { if (::semTake(syncPoint, NO_WAIT) == OK) { STATUS taskLocked; taskLocked = ::taskLock(); PX_threadId = ::taskSpawn(name, // Name priority, // Priority 0, // options stackSize, // stacksize (FUNCPTR)ThreadFunction, // entrypoint (int)this,0,0,0,0,0,0,0,0,0); // arg 1 --- arg 10 if (PX_threadId != ERROR) { // threads are created suspended Suspend(); ::semGive(syncPoint); if (taskLocked == OK) ::taskUnlock(); if (autoDelete) { PProcess & process = PProcess::Current(); process.deleteThreadMutex.Wait(); process.autoDeleteThreads.Append(this); process.deleteThreadMutex.Signal(); } } else { if (taskLocked == OK) ::taskUnlock(); printf("::PThread> ::taskSpawn failed, errno=0x%X\n", errno); PX_threadId = 0; ::semDelete(syncPoint); syncPoint = NULL; } } else { printf("::PThread> ::semTake failed, errno=0x%X\n", errno); ::semDelete(syncPoint); syncPoint = NULL; } }}PThread::~PThread(){ if (originalStackSize <= 0) return; if (!IsTerminated()) Terminate();}void PThread::Restart(){ if (IsTerminated()) { PX_threadId = ::taskSpawn(NULL, // Auto name tn priority, // Priority 0, // options originalStackSize, // stacksize (FUNCPTR)ThreadFunction, // entrypoint (int)this,0,0,0,0,0,0,0,0,0); // arg 1 --- arg 10 if (PX_threadId == ERROR) { printf("::Restart> ::taskSpawn failed, errno=0x%X\n", errno); PX_threadId = 0; } } else printf("::Restart> Cannot restart running thread\n");}void PThread::Terminate(){ if (originalStackSize <= 0) return; if (!IsTerminated()) { if (::taskDelete(PX_threadId) == ERROR) printf("::Terminate> ::taskDelete failed, errno=0x%X\n", errno); // And delete from administration PProcess & process = PProcess::Current(); process.activeThreadMutex.Wait(); process.activeThreads.SetAt(PX_threadId, NULL); process.activeThreadMutex.Signal(); PX_threadId = 0; }}BOOL PThread::IsTerminated() const{ STATUS stat = ERROR; if (PX_threadId != 0) stat = ::taskIdVerify(PX_threadId); return stat == ERROR;}void PThread::WaitForTermination() const{ while (!IsTerminated()) { Current()->Sleep(100); }}BOOL PThread::WaitForTermination(const PTimeInterval & maxWait) const{ if (PX_threadId == 0) return TRUE; PTimer timeout = maxWait; while (!IsTerminated()) { if (timeout == 0) return FALSE; Current()->Sleep(100); } return TRUE;}void PThread::Suspend(BOOL susp){ if (!IsTerminated()) { if (susp) { if (::taskSuspend(PX_threadId) == ERROR) printf("::Suspend> Thread doesn't want to suspend, errno=0x%X\n", errno); } else { if (::taskResume(PX_threadId) == ERROR) printf("::Suspend> Thread doesn't want to resume, errno=0x%X\n", errno); } } else printf("::Suspend> Operation on terminated thread\n");}void PThread::Resume(){ if (!IsTerminated()) { if (::taskResume(PX_threadId) == ERROR) printf("::Resume> Thread doesn't want to resume, errno=0x%X\n", errno); } else printf("::Resume> Operation on terminated thread\n");}BOOL PThread::IsSuspended() const{ BOOL isSuspended = FALSE; if (!IsTerminated()) isSuspended = ::taskIsSuspended(PX_threadId); else printf("::IsSuspended> Operation on terminated thread\n"); return isSuspended;}void PThread::SetAutoDelete(AutoDeleteFlag deletion){ PAssert(deletion != AutoDeleteThread || this != &PProcess::Current(), PLogicError); autoDelete = deletion == AutoDeleteThread;}void PThread::SetPriority(Priority priorityLevel){ if (!IsTerminated()) { priority = priorities[priorityLevel]; if (::taskPrioritySet(PX_threadId, priority ) == ERROR) printf("::SetPriority> ::taskPrioritySet failed, errno: 0x%X\n", errno); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -