📄 krnlsync.cpp
字号:
iPhysicalPriority = schedParam.sched_priority;
if ( iRet )
{
PIOSERR;
return PITHREAD_PRIORITY_INVALID;
}
#elif defined(CONFIG_MT_SOLARIS)
int iRet = ::thr_getprio( tThread, &iPhysicalPriority );
if ( iRet )
{
PIRETERR( iRet );
return PITHREAD_PRIORITY_INVALID;
}
#elif defined(CONFIG_MT_WIN32)
iPhysicalPriority =
::GetThreadPriority( tThread );
if ( iPhysicalPriority == THREAD_PRIORITY_ERROR_RETURN )
{
PIOSERR;
return PITHREAD_PRIORITY_INVALID;
}
#else
# error Unsupported!
#endif
else if ( iPhysicalPriority <= THREAD_PRIORITY_LOWEST )
return PITHREAD_PRIORITY_LOWEST;
else if ( iPhysicalPriority <= THREAD_PRIORITY_BELOW_NORMAL )
return PITHREAD_PRIORITY_LOW;
else if ( iPhysicalPriority <= THREAD_PRIORITY_NORMAL )
return PITHREAD_PRIORITY_MED;
else if ( iPhysicalPriority <= THREAD_PRIORITY_ABOVE_NORMAL )
return PITHREAD_PRIORITY_HIGH;
else if ( iPhysicalPriority <= THREAD_PRIORITY_HIGHEST )
return PITHREAD_PRIORITY_HIGHEST;
else
{
#if !defined(NDEBUG)
cerr << "Unknown priority #" << iPhysicalPriority << endl;
assert( 0 );
#endif
return PITHREAD_PRIORITY_INVALID;
};
};
virtual bool SetPriority( int iPriority );
virtual bool SetData( int iKey, void *pData )
{ return Internal_SetData( iKey, pData ); };
virtual bool GetData( int iKey, void **ppData )
{ return Internal_GetData( iKey, ppData ); };
virtual void *GetSystemHandle()
{
return (void *)tThread;
};
/* --- new functions --- */
unsigned long ThreadFunction();
void Cleanup()
{
#if defined(CONFIG_MT_SOLARIS) || defined(CONFIG_MT_PTHREAD)
tThread = BAD_THREAD;
#elif defined(CONFIG_MT_WIN32)
if ( tThread!=BAD_THREAD )
{
if ( !::CloseHandle( tThread ) )
{
PIOSERR;
assert( 0 );
};
tThread = BAD_THREAD;
};
#endif
};
/* --- friends --- */
friend class Platform;
};
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
static POSIXThread *___pTheMainThread = 0;
void Internal_InitThreads()
{
int iTmp;
iTmp = Platform::AllocThreadKey();
PIMUSTBETRUE( iTmp >=0 );
tTlsAllocatorKey = iTmp;
iTmp = Platform::AllocThreadKey();
PIMUSTBETRUE( iTmp >=0 );
tThreadObjectKey = iTmp;
if ( tTlsAllocatorKey==tThreadObjectKey )
{
cerr << "##" << endl << "## Error in native threads library." << endl;
cerr << "##" << endl << "## thr_keycreate() may not be implemented \
correctly." << endl;
cerr << "##" << endl << "## Please check ld library configuration."
<< endl;
cerr << "##" << endl;
abort();
};
assert( tTlsAllocatorKey!=tThreadObjectKey );
PIMUSTBETRUE(
Internal_SetData( tTlsAllocatorKey, Platform::GetGlobalAllocator() ) );
assert( !___pTheMainThread );
___pTheMainThread = PI_NEW( POSIXThread() );
PIMUSTBETRUE( Internal_SetData( tThreadObjectKey, ___pTheMainThread ) );
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
void Internal_CleanupThreads()
{
void *pMainThread = 0;
PIMUSTBETRUE( Internal_GetData( tThreadObjectKey, &pMainThread ) );
assert( ___pTheMainThread==pMainThread );
PIMUSTBETRUE( Platform::DeleteThreadKey( tTlsAllocatorKey ) );
PIMUSTBETRUE( Platform::DeleteThreadKey( tThreadObjectKey ) );
PI_DELETE( (POSIXThread *)pMainThread );
___pTheMainThread = 0;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
void Platform::Internal_EnterThreads( void (* fn)(void) )
{
Internal_InitThreads();
Platform::CatchExceptions( (void(*)(void*))fn, 0 );
Internal_CleanupThreads();
}
#if !defined(CONFIG_MT_PTHREAD)
/*____________________________________________________________________________*\
*
Function:
Synopsis: public constructor
Description:
\*____________________________________________________________________________*/
POSIXLocalSemaphore::POSIXLocalSemaphore( int iInitialCount, int iMaxCount )
: bError( true )
{
#if defined(CONFIG_MT_SOLARIS)
int iRet = ::sema_init(
&tSemaphore,
iMaxCount,
USYNC_THREAD,
0 );
bError = ( iRet!=0 );
if ( bError ) { PIRETERR(iRet); return; };
int iSemaphoresToLock=iMaxCount-iInitialCount;
assert( iSemaphoresToLock >= 0 );
while( iSemaphoresToLock-- )
{ PIMUSTBETRUE(!::sema_trywait( &tSemaphore ));};
#elif defined(CONFIG_MT_WIN32)
hSemaphore = ::CreateSemaphore( 0, iInitialCount, iMaxCount, 0 );
bError = !hSemaphore;
if ( bError )
{ PIOSERR; return; };
#else
# error Unsupported!
#endif
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
POSIXLocalSemaphore::~POSIXLocalSemaphore()
{
#if defined(CONFIG_MT_SOLARIS)
int iRet = ::sema_destroy( &tSemaphore );
if ( iRet )
{ PIRETERR(iRet); };
#elif defined(CONFIG_MT_WIN32)
if ( !::CloseHandle( hSemaphore ) ) { PIOSERR; };
#else
# error Unsupported!
#endif
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int POSIXLocalSemaphore::Lock()
{
#if defined(CONFIG_MT_SOLARIS)
for(;;)
{
int iRet = ::sema_wait( &tSemaphore );
if ( iRet == EINTR )
{ continue; };
if ( iRet != 0 )
{ PIRETERR(iRet); bError = true; };
return iRet;
};
#elif defined(CONFIG_MT_WIN32)
if ( ::WaitForSingleObject( hSemaphore, INFINITE ) == WAIT_FAILED )
{ PIOSERR; bError = true; };
return bError ? -1 : 0;
#else
# error Unsupported!
#endif
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int POSIXLocalSemaphore::TryLock()
{
#if defined(CONFIG_MT_SOLARIS)
int iRet = ::sema_trywait( &tSemaphore );
if ( iRet == EBUSY )
{ return PISYNC_EBUSY; }
else if ( iRet == 0 )
{ return 0; }
else
{ PIRETERR(iRet); bError = true; return -1; };
#elif defined(CONFIG_MT_WIN32)
DWORD dwResult = ::WaitForSingleObject( hSemaphore, 0 );
if ( dwResult == WAIT_TIMEOUT )
{ return PISYNC_EBUSY; }
else if ( dwResult != WAIT_FAILED )
{ return 0; }
else
{ PIOSERR; bError = true; return -1; };
#else
# error Unsupported!
#endif
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
int POSIXLocalSemaphore::UnLock()
{
#if defined(CONFIG_MT_SOLARIS)
int iRet = ::sema_post( &tSemaphore );
if ( iRet )
{ PIRETERR(iRet); bError = true; };
return iRet;
#elif defined(CONFIG_MT_WIN32)
bError = ( ::ReleaseSemaphore( hSemaphore, 1, 0 ) != TRUE );
if ( bError ) { PIOSERR; };
return bError ? -1 : 0;
#else
# error Unsupported!
#endif
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
bool POSIXLocalSemaphore::IsOK() const
{
return !bError;
}
#endif /* CONFIG_MT_PTHREAD */
/*____________________________________________________________________________*\
*
Function:
Synopsis: standalone function
Description:
Entry point for threads
\*____________________________________________________________________________*/
unsigned long PIPOSIXThreadFunction( unsigned long ulThread )
{
#if defined(CONFIG_MT_PTHREAD)
#elif defined(CONFIG_MT_SOLARIS)
#if 0
/*
** NOTE:
** This is not right yet
**
*/
/* --- block some signals from this thread --- */
sigset_t tSet;
sigemptyset( &tSet );
thr_sigsetmask( SIG_BLOCK, &tSet, NULL );
#endif
#elif defined(CONFIG_MT_WIN32)
#else
# error Unsupported!
#endif
POSIXThread *pThread=(POSIXThread *)ulThread;
assert( pThread );
Internal_SetData( tThreadObjectKey, pThread );
unsigned long ulRet=pThread->ThreadFunction();
return ulRet;
}
/*____________________________________________________________________________*\
*
Function:
Synopsis: public, constructor
Description:
Constructor.
\*____________________________________________________________________________*/
POSIXThread::POSIXThread(
Allocator *pTheAllocator,
int iTheStackSize )
:
tThread( BAD_THREAD ),
fnThread( 0 ),
pAllocator( pTheAllocator ),
ulData( 0 ),
iStackSize( iTheStackSize )
{
}
/*____________________________________________________________________________*\
*
Function:
Synopsis: public, constructor
Description:
Special constructor for main thread.
\*____________________________________________________________________________*/
POSIXThread::POSIXThread()
:
#if defined(CONFIG_MT_PTHREAD)
tThread( ::pthread_self() )
#elif defined(CONFIG_MT_SOLARIS)
tThread( ::thr_self() )
#elif defined(CONFIG_MT_WIN32)
tThread( ::GetCurrentThread() )
#else
# error Unsupported!
#endif
, fnThread( 0 ),
pAllocator( 0 ),
ulData( 0 ),
iStackSize( 0 )
{
}
/*____________________________________________________________________________*\
*
Function:
Synopsis:
Description:
\*____________________________________________________________________________*/
bool POSIXThread::IsTerminated()
{
#if defined(CONFIG_MT_PTHREAD)
return ::pthread_kill( tThread, 0 )!=0;
#elif defined(CONFIG_MT_SOLARIS)
return ::thr_kill( tThread, 0 )!=0; /* --- checks if thread exists --- */
#elif defined(CONFIG_MT_WIN32)
if ( tThread==BAD_THREAD )
{ return true; };
DWORD dwExitCode;
if ( ::GetExitCodeThread( tThread, &dwExitCode ) )
{
return dwExitCode!=STILL_ACTIVE;
}
else
{
PIOSERR;
assert( 0 );
return true;
};
#else
# error Unsupported!
#endif
}
/*____________________________________________________________________________*\
*
Function:
Synopsis: public, constructor
Description:
Constructor.
\*____________________________________________________________________________*/
bool POSIXThread::Begin(
ThreadFn fnEntry,
unsigned long ulTheData,
int iPriority,
int iTheFlags )
{
if ( !IsTerminated() )
{ return false; };
if ( !fnEntry )
{ return false; };
Cleanup();
fnThread = fnEntry;
ulData = ulTheData;
#if defined(CONFIG_MT_PTHREAD)
pthread_attr_t tAttr;
::pthread_attr_init( &tAttr );
(void)iTheFlags;
int iRet = ::pthread_create(
&tThread,
&tAttr,
(void*(*)(void*))PIPOSIXThreadFunction,
(void *)this );
::pthread_attr_destroy( &tAttr );
if ( iRet )
{
PIRETERR(iRet);
return false;
};
#elif defined(CONFIG_MT_SOLARIS)
int iFlags = THR_NEW_LWP; /* for kernel threads */
if ( iTheFlags & PITHREAD_FLAGS_SUSPENDED )
{ iFlags |= THR_SUSPENDED; };
int iRet = ::thr_create(
0,
iStackSize,
(void*(*)(void*))PIPOSIXThreadFunction,
(void *)this,
iFlags,
&tThread );
if ( iRet )
{ PIRETERR(iRet); return false; };
#elif defined(CONFIG_MT_WIN32)
int iFlags = 0;
if ( iTheFlags & PITHREAD_FLAGS_SUSPENDED )
{ iFlags |= CREATE_SUSPENDED; };
unsigned int uiThreadId;
if ( (tThread = (THREAD_T)::_beginthreadex(
NULL, /* no security attributes */
iStackSize, /* default stack size */
(unsigned int (__stdcall *)(void *))PIPOSIXThreadFunction,
(LPVOID)this, /* pass this pointer to ThreadFn */
iFlags, /* creation flags */
&uiThreadId ) )==BAD_THREAD )
{ PIOSERR; return false; };
#else
# error Unsupported!
#endif
/* --- set the priority --- */
if ( !InternalSetPriority( iPriority ) )
{
#if defined(CONFIG_MT_PTHREAD)
::pthread_kill( tThread, SIGTERM );
#elif defined(CONFIG_MT_SOLARIS)
::thr_kill( tThread, SIGTERM );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -