📄 tlibvx.cxx
字号:
}
else
printf("::SetPriority> Operation on terminated thread\n");
}
PThread::Priority PThread::GetPriority() const
{
if (!IsTerminated()) {
int prio;
if (::taskPriorityGet(PX_threadId, &prio) == OK) {
switch (prio) {
case VX_LOWEST_PRIORITY :
return LowestPriority;
case VX_LOW_PRIORITY :
return LowPriority;
case VX_NORMAL_PRIORITY :
return NormalPriority;
case VX_DISPLAY_PRIORITY :
return HighPriority;
case VX_URGENT_DISPLAY_PRIORITY :
return HighestPriority;
default:
printf("::GetPriority> Priority %d not mapped\n", prio);
break;
}
}
else
printf("::GetPriority> ::taskPriorityGet failed, errno=0x%X\n", errno);
}
else
printf("::GetPriority> Operation on terminated thread\n");
return LowestPriority;
}
void PThread::Yield()
{
::taskDelay(NO_WAIT);
}
void PThread::Sleep( const PTimeInterval & delay ) // Time interval to sleep for in microsec.
{
::taskDelay(delay.GetInterval()*sysClkRateGet()/1000);
}
void PThread::InitialiseProcessThread()
{
originalStackSize = 0;
autoDelete = FALSE;
PX_threadId = ::taskIdSelf();
PAssertOS((PX_threadId != ERROR) && (PX_threadId != 0));
((PProcess *)this)->activeThreads.DisallowDeleteObjects();
((PProcess *)this)->activeThreads.SetAt(PX_threadId, this);
}
PThread * PThread::Current()
{
PProcess & process = PProcess::Current();
process.activeThreadMutex.Wait();
PThread * thread = process.activeThreads.GetAt(::taskIdSelf());
process.activeThreadMutex.Signal();
return thread;
}
int PThread::PXBlockOnChildTerminate(int pid, const PTimeInterval & /*timeout*/) // Fix timeout
{
while (!IsTerminated()) {
Current()->Sleep(100);
}
return TRUE;
}
int PThread::PXBlockOnIO(int handle, int type, const PTimeInterval & timeout)
{
// make sure we flush the buffer before doing a write
fd_set tmp_rfd, tmp_wfd, tmp_efd;
fd_set * read_fds = &tmp_rfd;
fd_set * write_fds = &tmp_wfd;
fd_set * exception_fds = &tmp_efd;
FD_ZERO (read_fds);
FD_ZERO (write_fds);
FD_ZERO (exception_fds);
switch (type) {
case PChannel::PXReadBlock:
case PChannel::PXAcceptBlock:
FD_SET (handle, read_fds);
break;
case PChannel::PXWriteBlock:
FD_SET (handle, write_fds);
break;
case PChannel::PXConnectBlock:
FD_SET (handle, write_fds);
FD_SET (handle, exception_fds);
break;
default:
PAssertAlways(PLogicError);
return 0;
}
P_timeval tval = timeout;
return ::select(handle+1, read_fds, write_fds, exception_fds, tval);
}
void PThread::PXAbortBlock() const
{
}
///////////////////////////////////////////////////////////////////////////////
// PProcess::HouseKeepingThread
void PProcess::Construct()
{
// hard coded value, change this to handle more sockets at once with the select call
maxHandles = 1024;
houseKeeper=NULL;
CommonConstruct();
}
PProcess::HouseKeepingThread::HouseKeepingThread()
: PThread(10000, NoAutoDeleteThread, HighPriority, PString("HKeeping"))
{
Resume();
}
void PProcess::HouseKeepingThread::Main()
{
PProcess & process = PProcess::Current();
while(1) {
process.deleteThreadMutex.Wait();
for (PINDEX i = 0; i < process.autoDeleteThreads.GetSize(); i++) {
PThread * pThread = (PThread *) process.autoDeleteThreads.GetAt(i);
if( pThread->IsTerminated() )
process.autoDeleteThreads.RemoveAt(i--);
}
process.deleteThreadMutex.Signal();
PTimeInterval nextTimer = process.timers.Process();
if (nextTimer != PMaxTimeInterval) {
if ( nextTimer.GetInterval() > 10000 )
nextTimer = 10000;
}
breakBlock.Wait( nextTimer );
}
}
void PProcess::SignalTimerChange()
{
if (houseKeeper == NULL) {
// Prevent reentrance before the following assignment is done
// Placed after above if-statement due to efficiency, and so
// requires an another NULL-test.
CCriticalSection section;
section.Lock();
if (houseKeeper == NULL)
houseKeeper = new HouseKeepingThread;
section.Unlock();
}
else
houseKeeper->breakBlock.Signal();
}
///////////////////////////////////////////////////////////////////////////////
// PProcess
PProcess::~PProcess()
{
PreShutdown();
Sleep(100); // Give threads time to die a natural death
delete houseKeeper;
// OK, if there are any left we get really insistent...
activeThreadMutex.Wait();
for (PINDEX i = 0; i < activeThreads.GetSize(); i++) {
PThread & thread = activeThreads.GetDataAt(i);
if (this != &thread && !thread.IsTerminated())
thread.Terminate(); // With extreme prejudice
}
activeThreadMutex.Signal();
deleteThreadMutex.Wait();
autoDeleteThreads.RemoveAll();
deleteThreadMutex.Signal();
delete configFiles;
}
///////////////////////////////////////////////////////////////////////////////
// PSemaphore
PSemaphore::PSemaphore(SEM_ID anId)
{
initialVar = 1;
maxCountVar = UINT_MAX;
semId = anId;
PAssertOS(semId != NULL);
}
PSemaphore::PSemaphore(unsigned initial, unsigned maxCount)
{
if (initial > maxCount)
initial = maxCount;
initialVar = initial;
maxCountVar = maxCount;
semId = ::semCCreate(SEM_Q_FIFO, initial);
PAssertOS(semId != NULL);
}
PSemaphore::PSemaphore(const PSemaphore & sem)
{
initialVar = sem.GetInitial();
maxCountVar = sem.GetMaxCount();
if (initialVar > maxCountVar)
initialVar = maxCountVar;
semId = ::semCCreate(SEM_Q_FIFO, initialVar);
PAssertOS(semId != NULL);
}
PSemaphore::~PSemaphore()
{
if (semId != NULL) {
if (::semDelete(semId) == OK)
semId = NULL;
else
printf("~PSemaphore> Error delete with ID=0x%X with errno: 0x%X\n",
(unsigned int)semId, errno);
}
}
void PSemaphore::Wait()
{
STATUS result = ::semTake(semId, WAIT_FOREVER);
if (result == OK) {
CCriticalSection section;
section.Lock();
initialVar--;
section.Unlock();
}
PAssertOS(result != ERROR);
}
BOOL PSemaphore::Wait(const PTimeInterval & timeout)
{
long wait;
if (timeout == PMaxTimeInterval) {
wait = WAIT_FOREVER;
}
else {
int ticks = sysClkRateGet();
wait = (timeout.GetInterval() * ticks);
wait = wait / 1000;
wait++; // wait at least one tick
}
STATUS result = ::semTake(semId, wait);
if (result == OK) {
CCriticalSection section;
section.Lock();
initialVar--;
section.Unlock();
}
PAssertOS((result != ERROR) || (errno == S_objLib_OBJ_TIMEOUT));
return result != ERROR;
}
void PSemaphore::Signal()
{
CCriticalSection section;
section.Lock();
if (initialVar < maxCountVar) {
section.Unlock();
STATUS result = ::semGive(semId);
section.Lock();
if (result == OK)
initialVar++;
PAssertOS(result != ERROR);
}
section.Unlock();
}
BOOL PSemaphore::WillBlock() const
{
return initialVar == 0;
}
///////////////////////////////////////////////////////////////////////////////
// PMutex
PMutex::PMutex()
: PSemaphore( ::semMCreate(SEM_Q_FIFO) )
{
}
PMutex::PMutex(const PMutex & mutex)
: PSemaphore(::semMCreate(SEM_Q_FIFO))
{
}
PMutex::~PMutex()
{
if (semId != NULL) {
if (::semDelete(semId) == OK)
semId = NULL;
else
printf("~PMutex> Error delete with ID=0x%X with errno: 0x%X\n",
(unsigned int)semId, errno);
}
}
void PMutex::Wait()
{
STATUS result = ::semTake(semId, WAIT_FOREVER);
PAssertOS(result == OK);
}
BOOL PMutex::Wait(const PTimeInterval & timeout)
{
long wait;
if (timeout == PMaxTimeInterval) {
wait = WAIT_FOREVER;
}
else {
int ticks = sysClkRateGet();
wait = (timeout.GetMilliSeconds() * ticks);
wait = wait / 1000;
wait++; // wait at least one tick
}
STATUS result = ::semTake(semId, wait);
PAssertOS((result != ERROR) || (errno == S_objLib_OBJ_TIMEOUT));
return result != ERROR;
}
void PMutex::Signal()
{
::semGive(semId);
}
BOOL PMutex::WillBlock() const
{
STATUS result = ::semTake(semId, NO_WAIT);
PAssertOS((result != ERROR) || (errno == S_objLib_OBJ_UNAVAILABLE));
if (result != ERROR)
::semGive(semId);
return result == ERROR;
}
///////////////////////////////////////////////////////////////////////////////
// PSyncPoint
PSyncPoint::PSyncPoint()
: PSemaphore(0, 1)
{
}
PSyncPoint::PSyncPoint(const PSyncPoint & syncPoint)
: PSemaphore(syncPoint)
{
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -