Removed IRIX Sproc threading support form OpenThreads as IRIX is long dead.
This commit is contained in:
@@ -1,51 +0,0 @@
|
||||
# This file should only be included when using Sproc
|
||||
|
||||
SET(LIB_NAME OpenThreads)
|
||||
SET(LIB_PUBLIC_HEADERS ${OpenThreads_PUBLIC_HEADERS})
|
||||
|
||||
ADD_LIBRARY(${LIB_NAME}
|
||||
${OPENTHREADS_USER_DEFINED_DYNAMIC_OR_STATIC}
|
||||
${LIB_PUBLIC_HEADERS}
|
||||
SharedArena.c++
|
||||
SharedArena.h
|
||||
SprocBarrier.c++
|
||||
SprocBarrierPrivateData.h
|
||||
SprocCondition.c++
|
||||
SprocConditionPrivateData.h
|
||||
SprocMutex.c++
|
||||
SprocMutexPrivateData.h
|
||||
SprocThread.c++
|
||||
SprocThreadPrivateActions.h
|
||||
SprocThreadPrivateData.h
|
||||
../common/Version.cpp
|
||||
../common/Atomic.cpp
|
||||
)
|
||||
|
||||
IF(OPENTHREADS_SONAMES)
|
||||
SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES VERSION ${OPENTHREADS_VERSION} SOVERSION ${OPENTHREADS_SOVERSION})
|
||||
ENDIF()
|
||||
|
||||
# Do we need to link against anything for Sproc?
|
||||
#TARGET_LINK_LIBRARIES(${LIB_NAME}
|
||||
#)
|
||||
|
||||
# Since we're building different platforms binaries in
|
||||
# their respective directories, we need to set the
|
||||
# link directory so it can find this location.
|
||||
LINK_DIRECTORIES(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
TARGETS OpenThreads
|
||||
ARCHIVE DESTINATION lib${LIB_POSTFIX} COMPONENT libopenthreads-dev
|
||||
LIBRARY DESTINATION lib${LIB_POSTFIX} COMPONENT libopenthreads
|
||||
RUNTIME DESTINATION bin COMPONENT libopenthreads
|
||||
)
|
||||
INSTALL(
|
||||
FILES ${OpenThreads_PUBLIC_HEADERS}
|
||||
DESTINATION include/OpenThreads
|
||||
COMPONENT libopenthreads-dev
|
||||
)
|
||||
|
||||
#commented out# INCLUDE(ModuleInstall OPTIONAL)
|
||||
@@ -1,256 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// SharedArena.c++ - Facilities for creating/destroying shared arenas
|
||||
// ~~~~~~~~~~~~~~~
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <poll.h>
|
||||
#include <bstring.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "SharedArena.h"
|
||||
|
||||
using namespace OpenThreads;
|
||||
|
||||
#ifdef DEBUG
|
||||
# define DPRINTF(arg) printf arg
|
||||
#else
|
||||
# define DPRINTF(arg)
|
||||
#endif
|
||||
|
||||
#define MAX_PROCS 1024
|
||||
|
||||
#define SEMAPHORE_ARENA_SIZE 500000
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Static arena initialization
|
||||
//
|
||||
usptr_t *SharedArena::_arena = 0;
|
||||
|
||||
int SharedArena::_numLocks = 0;
|
||||
|
||||
char *SharedArena::_arenaName = 0;
|
||||
|
||||
|
||||
void SharedArena::initArena() {
|
||||
|
||||
_arenaName = tmpnam(0);
|
||||
DPRINTF(("Creating arena: %s\n", _arenaName));
|
||||
|
||||
if (unlink(_arenaName) < 0) {
|
||||
if (errno != ENOENT) {
|
||||
perror("unlink");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (usconfig(CONF_INITUSERS, MAX_PROCS) < 0) {
|
||||
perror("usconfig1");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef OT_USESHAREDONLY
|
||||
if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) {
|
||||
perror("usconfig2");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
char *sema_arena_size_string = getenv("OPENTHREADS_SEMAPHORE_ARENA_SIZE");
|
||||
unsigned long int sema_arena_size;
|
||||
if(sema_arena_size_string != 0L) {
|
||||
sema_arena_size = atol(sema_arena_size_string);
|
||||
} else {
|
||||
sema_arena_size = SEMAPHORE_ARENA_SIZE;
|
||||
}
|
||||
|
||||
if (usconfig(CONF_INITSIZE,sema_arena_size) < 0) {
|
||||
perror("usconfig3");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if ((_arena = usinit(_arenaName)) == 0) {
|
||||
perror("usinit");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void SharedArena::removeArena() {
|
||||
|
||||
DPRINTF(("Removing arena: %s\n", _arenaName));
|
||||
#ifndef OT_USESHAREDONLY
|
||||
|
||||
if (unlink(_arenaName) < 0) {
|
||||
perror("unlink");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ulock_t SharedArena::allocLock() {
|
||||
|
||||
if(_numLocks == 0) initArena();
|
||||
|
||||
assert(_arena != 0);
|
||||
|
||||
ulock_t lock;
|
||||
if ((lock = usnewlock(_arena)) == 0) {
|
||||
perror("usnewlock");
|
||||
printf("Num Locks: %d\n", _numLocks);
|
||||
exit(1);
|
||||
}
|
||||
++_numLocks;
|
||||
return lock;
|
||||
}
|
||||
|
||||
barrier_t *SharedArena::allocBarrier() {
|
||||
|
||||
if(_numLocks == 0) initArena();
|
||||
|
||||
assert(_arena != 0);
|
||||
barrier_t *bar;
|
||||
if ((bar= new_barrier(_arena)) == 0) {
|
||||
perror("new_barrier");
|
||||
exit(1);
|
||||
}
|
||||
++_numLocks;
|
||||
return bar;
|
||||
|
||||
}
|
||||
|
||||
int SharedArena::lock(ulock_t lock) {
|
||||
|
||||
return ussetlock(lock);
|
||||
}
|
||||
|
||||
int SharedArena::unlock(ulock_t lock) {
|
||||
|
||||
return usunsetlock(lock);
|
||||
}
|
||||
|
||||
int SharedArena::trylock(ulock_t lock) {
|
||||
|
||||
return ustestlock(lock);
|
||||
}
|
||||
|
||||
void SharedArena::deleteLock(ulock_t lock) {
|
||||
|
||||
assert(_arena != 0);
|
||||
usfreelock(lock, _arena);
|
||||
--_numLocks;
|
||||
if(_numLocks == 0) {
|
||||
removeArena();
|
||||
}
|
||||
}
|
||||
|
||||
void SharedArena::initBarrier(barrier_t *b) {
|
||||
init_barrier(b);
|
||||
}
|
||||
|
||||
void SharedArena::freeBarrier(barrier_t *b) {
|
||||
assert(_arena != 0);
|
||||
free_barrier(b);
|
||||
b = 0;
|
||||
--_numLocks;
|
||||
if(_numLocks == 0) {
|
||||
removeArena();
|
||||
}
|
||||
}
|
||||
|
||||
void SharedArena::block(barrier_t *b, unsigned int n) {
|
||||
barrier(b, n);
|
||||
}
|
||||
|
||||
usema_t *SharedArena::allocSema() {
|
||||
|
||||
if(_numLocks == 0) initArena();
|
||||
assert(_arena != 0);
|
||||
|
||||
usema_t *sema;
|
||||
sema = usnewpollsema(_arena, 0);
|
||||
if(sema == 0) {
|
||||
perror("usnewpollsema");
|
||||
printf("NUM SEMAS: %d\n", _numLocks);
|
||||
exit(1);
|
||||
}
|
||||
++_numLocks;
|
||||
return sema;
|
||||
|
||||
}
|
||||
|
||||
int SharedArena::getSemaFd(usema_t *sema) {
|
||||
|
||||
int returnval;
|
||||
returnval = usopenpollsema(sema, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
if(0 > returnval) {
|
||||
perror("usopenpollsema");
|
||||
exit(1);
|
||||
}
|
||||
return returnval;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SharedArena::pSema(usema_t *sema) {
|
||||
|
||||
return uspsema(sema);
|
||||
|
||||
}
|
||||
|
||||
int SharedArena::vSema(usema_t *sema) {
|
||||
|
||||
return usvsema(sema);
|
||||
|
||||
}
|
||||
|
||||
int SharedArena::testSema(usema_t *sema) {
|
||||
|
||||
return ustestsema(sema);
|
||||
|
||||
}
|
||||
|
||||
int SharedArena::closeSemaFd(usema_t *sema) {
|
||||
|
||||
int returnval;
|
||||
returnval = usclosepollsema(sema);
|
||||
if(returnval != 0) {
|
||||
perror("usclosepollsema");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return returnval;
|
||||
|
||||
}
|
||||
|
||||
int SharedArena::freeSema(usema_t *sema) {
|
||||
|
||||
assert(_arena != 0);
|
||||
usfreepollsema(sema, _arena);
|
||||
--_numLocks;
|
||||
if(_numLocks == 0) {
|
||||
removeArena();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef OT_USESHAREDONLY
|
||||
@@ -1,87 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
// SharedArena.h - Facilities for creating/destroying shared arenas
|
||||
// ~~~~~~~~~~~~~
|
||||
|
||||
#ifndef _SHAREDARENA_H_
|
||||
#define _SHAREDARENA_H_
|
||||
|
||||
#include <unistd.h>
|
||||
#include <ulocks.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace OpenThreads {
|
||||
|
||||
#define OT_USESHAREDONLY
|
||||
|
||||
class SharedArena {
|
||||
|
||||
friend class Mutex;
|
||||
|
||||
friend class Barrier;
|
||||
|
||||
friend class Condition;
|
||||
|
||||
private:
|
||||
|
||||
static void initArena();
|
||||
|
||||
static void removeArena();
|
||||
|
||||
static ulock_t allocLock();
|
||||
|
||||
static barrier_t *allocBarrier();
|
||||
|
||||
static usema_t *allocSema();
|
||||
|
||||
static int getSemaFd(usema_t *sema);
|
||||
|
||||
static int pSema(usema_t *sema);
|
||||
|
||||
static int vSema(usema_t *sema);
|
||||
|
||||
static int testSema(usema_t *sema);
|
||||
|
||||
static int closeSemaFd(usema_t *sema);
|
||||
|
||||
static int freeSema(usema_t *sema);
|
||||
|
||||
static int lock(ulock_t lock);
|
||||
|
||||
static int unlock(ulock_t lock);
|
||||
|
||||
static int trylock(ulock_t lock);
|
||||
|
||||
static void deleteLock(ulock_t lock);
|
||||
|
||||
static void initBarrier(barrier_t *b);
|
||||
|
||||
static void freeBarrier(barrier_t *b);
|
||||
|
||||
static void block(barrier_t *b, unsigned int n);
|
||||
|
||||
private:
|
||||
|
||||
static usptr_t *_arena;
|
||||
|
||||
static int _numLocks;
|
||||
|
||||
static char *_arenaName;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !_SHAREDARENA_H_
|
||||
@@ -1,229 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// SprocBarrier.c++ - C++ Barrier class built on top of IRIX process threads.
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
|
||||
#include <ulocks.h>
|
||||
#include <OpenThreads/Barrier>
|
||||
#include "SprocBarrierPrivateData.h"
|
||||
#include "SharedArena.h"
|
||||
#include "SprocThreadPrivateActions.h"
|
||||
|
||||
#ifndef USE_IRIX_NATIVE_BARRIER
|
||||
|
||||
#include <OpenThreads/Condition>
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(arg) printf arg; fflush(stdout);
|
||||
#else
|
||||
#define DPRINTF(arg)
|
||||
#endif
|
||||
|
||||
using namespace OpenThreads;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// This cancel cleanup handler is necessary to ensure that the barrier's
|
||||
// mutex gets unlocked on cancel. Otherwise deadlocks could occur with
|
||||
// later joins.
|
||||
//
|
||||
void barrier_cleanup_handler(void *arg) {
|
||||
|
||||
DPRINTF(("(SPROC BARRIER) cleanup handler called on pid %d\n", getpid()));
|
||||
|
||||
Mutex *mutex = static_cast<Mutex *>(arg);
|
||||
|
||||
if(mutex->trylock() == 1)
|
||||
mutex->unlock();
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Constructor
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
Barrier::Barrier(int numThreads) {
|
||||
|
||||
SprocBarrierPrivateData *pd = new SprocBarrierPrivateData();
|
||||
|
||||
#ifdef USE_IRIX_NATIVE_BARRIER
|
||||
|
||||
pd->barrier = SharedArena::allocBarrier();
|
||||
pd->numThreads = numThreads;
|
||||
|
||||
#else
|
||||
|
||||
pd->cnt = 0;
|
||||
pd->phase = 0;
|
||||
pd->maxcnt = numThreads;
|
||||
|
||||
#endif
|
||||
|
||||
_prvData = static_cast<void *>(pd);
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Destructor
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
Barrier::~Barrier() {
|
||||
|
||||
SprocBarrierPrivateData *pd =
|
||||
static_cast<SprocBarrierPrivateData*>(_prvData);
|
||||
|
||||
#ifdef USE_IRIX_NATIVE_BARRIER
|
||||
|
||||
SharedArena::freeBarrier(pd->barrier);
|
||||
|
||||
#endif
|
||||
|
||||
delete pd;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Reset the barrier to its original state
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
void Barrier::reset() {
|
||||
|
||||
SprocBarrierPrivateData *pd =
|
||||
static_cast<SprocBarrierPrivateData*>(_prvData);
|
||||
|
||||
#ifdef USE_IRIX_NATIVE_BARRIER
|
||||
|
||||
SharedArena::initBarrier(pd->barrier);
|
||||
|
||||
#else
|
||||
|
||||
pd->cnt = 0;
|
||||
pd->phase = 0;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Block until numThreads threads have entered the barrier.
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
void Barrier::block(unsigned int numThreads) {
|
||||
|
||||
SprocBarrierPrivateData *pd =
|
||||
static_cast<SprocBarrierPrivateData*>(_prvData);
|
||||
|
||||
#ifdef USE_IRIX_NATIVE_BARRIER
|
||||
|
||||
if(numThreads == 0) {
|
||||
SharedArena::block(pd->barrier, pd->numThreads);
|
||||
} else {
|
||||
SharedArena::block(pd->barrier, numThreads);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
pd->_mutex.lock();
|
||||
|
||||
if(numThreads != 0) pd->maxcnt = numThreads;
|
||||
|
||||
int my_phase;
|
||||
|
||||
my_phase = pd->phase;
|
||||
++pd->cnt;
|
||||
|
||||
DPRINTF(("(SPROC BARRIER %d) block, count=%d, maxThreads=%d, phase=%d\n",
|
||||
getpid(), pd->cnt, pd->maxcnt, pd->phase));
|
||||
|
||||
if(pd->cnt == pd->maxcnt) { // I am the last one
|
||||
pd->cnt = 0; // reset for next use
|
||||
pd->phase = 1 - my_phase; // toggle phase
|
||||
pd->_cond.broadcast();
|
||||
}
|
||||
|
||||
while (pd->phase == my_phase) {
|
||||
ThreadPrivateActions::PushCancelFunction(barrier_cleanup_handler,
|
||||
&pd->_mutex);
|
||||
pd->_cond.wait(&pd->_mutex);
|
||||
|
||||
ThreadPrivateActions::PopCancelFunction();
|
||||
}
|
||||
|
||||
pd->_mutex.unlock();
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Release the barrier, now.
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
void Barrier::release() {
|
||||
|
||||
SprocBarrierPrivateData *pd =
|
||||
static_cast<SprocBarrierPrivateData*>(_prvData);
|
||||
|
||||
#ifdef USE_IRIX_NATIVE_BARRIER
|
||||
|
||||
printf("ERROR >>>>> Barrier::release() cannot be implemented using native IRIX Barriers !!!\n");
|
||||
|
||||
#else
|
||||
|
||||
int my_phase;
|
||||
pd->_mutex.lock();
|
||||
|
||||
my_phase = pd->phase;
|
||||
|
||||
pd->cnt = 0; // reset for next use
|
||||
pd->phase = 1 - my_phase; // toggle phase
|
||||
pd->_cond.broadcast();
|
||||
|
||||
pd->_mutex.unlock();
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Return the number of threads currently blocked in the barrier
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Barrier::numThreadsCurrentlyBlocked() {
|
||||
|
||||
SprocBarrierPrivateData *pd =
|
||||
static_cast<SprocBarrierPrivateData*>(_prvData);
|
||||
|
||||
int numBlocked = -1;
|
||||
pd->_mutex.lock();
|
||||
numBlocked = pd->cnt;
|
||||
pd->_cond.broadcast();
|
||||
return numBlocked;
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
// SprocBarrierPrivateData.h - private data structure for barrier
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#ifndef _SPROCBARRIERPRIVATEDATA_H_
|
||||
#define _SPROCBARRIERPRIVATEDATA_H_
|
||||
|
||||
#include <ulocks.h>
|
||||
#include <OpenThreads/Barrier>
|
||||
|
||||
#ifndef USE_IRIX_NATIVE_BARRIER
|
||||
|
||||
#include <OpenThreads/Condition>
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
#endif
|
||||
|
||||
namespace OpenThreads {
|
||||
|
||||
class SprocBarrierPrivateData {
|
||||
|
||||
friend class Barrier;
|
||||
|
||||
private:
|
||||
|
||||
SprocBarrierPrivateData() {};
|
||||
|
||||
virtual ~SprocBarrierPrivateData() {};
|
||||
|
||||
#ifdef USE_IRIX_NATIVE_BARRIER
|
||||
|
||||
barrier_t *barrier;
|
||||
|
||||
unsigned int numThreads;
|
||||
|
||||
#else
|
||||
|
||||
OpenThreads::Condition _cond;
|
||||
|
||||
OpenThreads::Mutex _mutex;
|
||||
|
||||
volatile int maxcnt;
|
||||
|
||||
volatile int cnt;
|
||||
|
||||
volatile int phase;
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //_SPROCBARRIERPRIVATEDATA_H_
|
||||
@@ -1,306 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// SprocCondition.c++ - C++ Condition class built on sprocs.
|
||||
// ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#include <OpenThreads/Condition>
|
||||
#include "SprocConditionPrivateData.h"
|
||||
#include <OpenThreads/Mutex>
|
||||
#include "SharedArena.h"
|
||||
#include "SprocThreadPrivateActions.h"
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
using namespace OpenThreads;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define DPRINTF(arg) printf arg; fflush(stdout);
|
||||
#define DPRINTLIST(arg) ConditionDebug::printList arg; fflush(stdout);
|
||||
|
||||
namespace OpenThreads {
|
||||
|
||||
class ConditionDebug {
|
||||
|
||||
friend class Condition;
|
||||
|
||||
private:
|
||||
|
||||
static void printList(std::list<pid_t> &pid_list) {
|
||||
|
||||
std::list<pid_t>::iterator iter;
|
||||
int counter = 0;
|
||||
printf("(SPROC CONDITION %d) ", getpid());
|
||||
for(iter=pid_list.begin(); iter!=pid_list.end();++iter) {
|
||||
printf("Pid [%d]=%d, ", counter, *iter);
|
||||
++counter;
|
||||
}
|
||||
printf("\b\n");
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define DPRINTF(arg)
|
||||
#define DPRINTLIST(arg)
|
||||
|
||||
#endif
|
||||
|
||||
void condition_alarm_handler(int signal) {
|
||||
|
||||
//DPRINTF(("(SPROC CONDITION) signal alarm handler called.\n"));
|
||||
|
||||
sigset(SIGALRM, SIG_DFL);
|
||||
|
||||
unblockproc(getpid());
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Constructor
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
Condition::Condition() {
|
||||
|
||||
SprocConditionPrivateData *pd =
|
||||
new SprocConditionPrivateData();
|
||||
|
||||
_prvData = static_cast<void *>(pd);
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Destructor
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
Condition::~Condition() {
|
||||
|
||||
SprocConditionPrivateData *pd =
|
||||
static_cast<SprocConditionPrivateData *>(_prvData);
|
||||
|
||||
pd->mutex.lock();
|
||||
DPRINTF(("(SPROC CONDITION) : In destructor\n"));
|
||||
DPRINTLIST((pd->pid_list));
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Destroy all remaining in the linked-list of waiters (pids).
|
||||
//
|
||||
pd->pid_list.clear();
|
||||
|
||||
delete pd;
|
||||
_prvData = 0;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: wait on a condition
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
int Condition::wait(Mutex *mutex) {
|
||||
|
||||
return wait(mutex, 0);
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: wait on a condition
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
int Condition::wait(Mutex *mutex, unsigned long int ms) {
|
||||
|
||||
unsigned int sec;
|
||||
unsigned int usec;
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
pid_t mypid = getpid();
|
||||
|
||||
SprocConditionPrivateData *pd =
|
||||
static_cast<SprocConditionPrivateData *>(_prvData);
|
||||
|
||||
if(ms != 0) {
|
||||
|
||||
// Wait for ms milliseconds
|
||||
sec = ms / 1000;
|
||||
usec = (ms % 1000) * 1000;
|
||||
tv.tv_sec = sec;
|
||||
tv.tv_usec = usec;
|
||||
|
||||
DPRINTF(("(SPROC CONDITION) : PID %d timeout values [%d | %d]\n",
|
||||
mypid, tv.tv_sec, tv.tv_usec));
|
||||
|
||||
}
|
||||
|
||||
pd->mutex.lock();
|
||||
|
||||
pd->pid_list.push_front(mypid);
|
||||
|
||||
pd->mutex.unlock();
|
||||
|
||||
DPRINTF(("(SPROC CONDITION) : PID %d going to blockproc\n",
|
||||
mypid));
|
||||
|
||||
int status = 0;
|
||||
|
||||
status = setblockproccnt(mypid, 0);
|
||||
|
||||
// If we're doing a timout, setup the signal handler to deal with it.
|
||||
if(tv.tv_sec != 0 || tv.tv_usec != 0) {
|
||||
|
||||
DPRINTF(("(SPROC CONDITION) : PID %d setting timeout condition\n",
|
||||
mypid));
|
||||
|
||||
sigset(SIGALRM, condition_alarm_handler);
|
||||
|
||||
struct timeval recur;
|
||||
recur.tv_sec = 0;
|
||||
recur.tv_usec = 0;
|
||||
|
||||
itimerval itv;
|
||||
itv.it_interval = recur;
|
||||
itv.it_value = tv;
|
||||
|
||||
setitimer(ITIMER_REAL, &itv, NULL);
|
||||
|
||||
}
|
||||
|
||||
mutex->unlock();
|
||||
|
||||
ThreadPrivateActions::ThreadCancelTest();
|
||||
|
||||
status = blockproc(mypid);
|
||||
|
||||
ThreadPrivateActions::ThreadCancelTest();
|
||||
|
||||
mutex->lock();
|
||||
|
||||
DPRINTF(("(SPROC CONDITION) : PID %d, returned from blockproc %d\n",
|
||||
mypid, status));
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Pull the pid from the list
|
||||
//
|
||||
pd->mutex.lock();
|
||||
|
||||
DPRINTLIST((pd->pid_list));
|
||||
|
||||
#ifndef DEBUG
|
||||
|
||||
// KLUDGE - can optimized this by just doing -remove()-
|
||||
std::list<pid_t>::iterator iter;
|
||||
iter = pd->pid_list.begin();
|
||||
while(iter != pd->pid_list.end()) {
|
||||
|
||||
if(*iter == mypid) {
|
||||
DPRINTF(("(SPROC CONDITION) : PID %d removed itself from the list\n",
|
||||
mypid));
|
||||
|
||||
pd->pid_list.remove(mypid);
|
||||
iter = pd->pid_list.begin();
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
pd->pid_list.remove(mypid);
|
||||
#endif
|
||||
|
||||
DPRINTLIST((pd->pid_list));
|
||||
|
||||
pd->mutex.unlock();
|
||||
|
||||
if(status == -1) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: signal a thread to wake up.
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
int Condition::signal() {
|
||||
|
||||
ThreadPrivateActions::ThreadCancelTest();
|
||||
|
||||
SprocConditionPrivateData *pd =
|
||||
static_cast<SprocConditionPrivateData *>(_prvData);
|
||||
|
||||
pd->mutex.lock();
|
||||
if(pd->pid_list.empty()) {
|
||||
DPRINTF(("(SPROC CONDITION) : No threads to signal\n"));
|
||||
pd->mutex.unlock(); // Remember to release the mutex.
|
||||
return 0;
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
// Perform an unblockproc on the first pid in the list.
|
||||
//
|
||||
DPRINTF(("(SPROC CONDITION) : PID %d signaling pid %d\n",
|
||||
getpid(), pd->pid_list.front()));
|
||||
int status = unblockproc(pd->pid_list.front());
|
||||
pd->mutex.unlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: signal all threads to wake up.
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
int Condition::broadcast() {
|
||||
|
||||
|
||||
ThreadPrivateActions::ThreadCancelTest();
|
||||
|
||||
SprocConditionPrivateData *pd =
|
||||
static_cast<SprocConditionPrivateData *>(_prvData);
|
||||
|
||||
pd->mutex.lock();
|
||||
|
||||
std::list<pid_t>::iterator iter;
|
||||
for(iter = pd->pid_list.begin();
|
||||
iter != pd->pid_list.end();
|
||||
++iter) {
|
||||
|
||||
DPRINTF(("(SPROC CONDITION) Broadcast to pid[%d]\n", *iter));
|
||||
unblockproc(*iter);
|
||||
}
|
||||
|
||||
pd->mutex.unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// SprocConditionPrivateData.h - Private data structure for Condition
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#ifndef _SPROCCONDITIONPRIVATEDATA_H_
|
||||
#define _SPROCCONDITIONPRIVATEDATA_H_
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <bstring.h>
|
||||
#include <sys/time.h>
|
||||
#include <ulocks.h>
|
||||
#include <list>
|
||||
|
||||
#include <OpenThreads/Mutex>
|
||||
#include <OpenThreads/Condition>
|
||||
|
||||
namespace OpenThreads {
|
||||
|
||||
class SemaLink {
|
||||
|
||||
friend class SprocConditionPrivatedata;
|
||||
|
||||
friend class Condition;
|
||||
|
||||
friend class ConditionDebug;
|
||||
|
||||
private:
|
||||
|
||||
SemaLink() {};
|
||||
|
||||
virtual ~SemaLink() {};
|
||||
|
||||
SemaLink *next;
|
||||
|
||||
usema_t *sema;
|
||||
|
||||
int select_cond; // 0=pre-select, 1=in-select, 2=post-select
|
||||
|
||||
};
|
||||
|
||||
class SprocConditionPrivateData {
|
||||
|
||||
friend class Condition;
|
||||
|
||||
private:
|
||||
|
||||
SprocConditionPrivateData() {
|
||||
|
||||
pid_list.clear();
|
||||
|
||||
};
|
||||
|
||||
virtual ~SprocConditionPrivateData() {
|
||||
|
||||
pid_list.clear();
|
||||
|
||||
};
|
||||
|
||||
std::list<pid_t> pid_list;
|
||||
|
||||
Mutex mutex;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !_SPROCCONDITIONPRIVATEDATA_H_
|
||||
@@ -1,128 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// SprocMutex.c++ - C++ Mutex class built on top of posix threads.
|
||||
// ~~~~~~~~~~~~~~
|
||||
|
||||
#include <unistd.h>
|
||||
#include <ulocks.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <OpenThreads/Mutex>
|
||||
#include "SharedArena.h"
|
||||
#include "SprocMutexPrivateData.h"
|
||||
#include "SprocThreadPrivateActions.h"
|
||||
|
||||
using namespace OpenThreads;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Constructor
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
Mutex::Mutex(MutexType type):
|
||||
_mutexType(type)
|
||||
{
|
||||
|
||||
SprocMutexPrivateData *pd = new SprocMutexPrivateData();
|
||||
|
||||
pd->mutex = SharedArena::allocLock();
|
||||
|
||||
_prvData = static_cast<void *>(pd);
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Destructor
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
Mutex::~Mutex() {
|
||||
|
||||
SprocMutexPrivateData *pd =
|
||||
static_cast<SprocMutexPrivateData*>(_prvData);
|
||||
|
||||
SharedArena::deleteLock(pd->mutex);
|
||||
|
||||
delete pd;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: lock the mutex
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
int Mutex::lock() {
|
||||
|
||||
ThreadPrivateActions::ThreadCancelTest();
|
||||
|
||||
SprocMutexPrivateData *pd =
|
||||
static_cast<SprocMutexPrivateData*>(_prvData);
|
||||
|
||||
int status = SharedArena::lock(pd->mutex);
|
||||
|
||||
if(status == -1) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if(status == 1) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: unlock the mutex
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
int Mutex::unlock() {
|
||||
|
||||
SprocMutexPrivateData *pd =
|
||||
static_cast<SprocMutexPrivateData*>(_prvData);
|
||||
|
||||
int status = SharedArena::unlock(pd->mutex);
|
||||
|
||||
ThreadPrivateActions::ThreadCancelTest();
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: test if the mutex may be locked
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
int Mutex::trylock() {
|
||||
|
||||
SprocMutexPrivateData *pd =
|
||||
static_cast<SprocMutexPrivateData*>(_prvData);
|
||||
|
||||
int status = SharedArena::trylock(pd->mutex);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// SprocMutexPrivateData.h - Private data structure for Mutex
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#ifndef _SPROCMUTEXPRIVATEDATA_H_
|
||||
#define _SPROCMUTEXPRIVATEDATA_H_
|
||||
|
||||
#include <ulocks.h>
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
namespace OpenThreads {
|
||||
|
||||
class SprocMutexPrivateData {
|
||||
|
||||
friend class SprocThreadPrivateActions;
|
||||
|
||||
friend class Mutex;
|
||||
|
||||
private:
|
||||
|
||||
SprocMutexPrivateData() {};
|
||||
|
||||
virtual ~SprocMutexPrivateData() {};
|
||||
|
||||
ulock_t mutex;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _SPROCMUTEXPRIVATEDATA_H_
|
||||
@@ -1,818 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// SprocThread.c++ - C++ Thread class built on top of IRIX sproc.
|
||||
// ~~~~~~~~~~~~~~~
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/sysmp.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <list>
|
||||
#include <OpenThreads/Thread>
|
||||
#include "SprocMutexPrivateData.h"
|
||||
#include "SprocThreadPrivateData.h"
|
||||
#include "SprocThreadPrivateActions.h"
|
||||
|
||||
using namespace OpenThreads;
|
||||
|
||||
extern int errno;
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(arg) printf arg; fflush(stdout);
|
||||
#else
|
||||
#define DPRINTF(ARG)
|
||||
#endif
|
||||
|
||||
static void sproc_dead_child_sig_handler(int sigid);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialize the static unique ids.
|
||||
//
|
||||
int SprocThreadPrivateData::nextId = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialize thread master priority level
|
||||
//
|
||||
Thread::ThreadPriority Thread::s_masterThreadPriority =
|
||||
Thread::THREAD_PRIORITY_MAX;
|
||||
|
||||
bool Thread::s_isInitialized = false;
|
||||
|
||||
std::list<Thread *> ThreadPrivateActions::s_threadList;
|
||||
|
||||
void ThreadPrivateActions::ThreadCancelTest() {
|
||||
|
||||
OpenThreads::Thread *t = GetThread(getpid());
|
||||
|
||||
if(t != 0L) {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *>(t->_prvData);
|
||||
|
||||
bool *dieflag = GetDeathFlag(t);
|
||||
|
||||
if(*dieflag==false) return;
|
||||
|
||||
DPRINTF(("(SPROC THREAD) Thread Cancel Test Passed for %d\n",
|
||||
getpid()));
|
||||
|
||||
if(!pd->cancelFuncStack.empty())
|
||||
pd->cancelFuncStack.top().routine(pd->cancelFuncStack.top().arg);
|
||||
|
||||
t->cancelCleanup();
|
||||
pd->isRunning = false;
|
||||
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool *ThreadPrivateActions::GetDeathFlag(Thread *thread) {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *>(thread->_prvData);
|
||||
|
||||
return (bool *)(&(pd->dieFlag));
|
||||
}
|
||||
|
||||
Thread *ThreadPrivateActions::GetThread(pid_t thread_id) {
|
||||
|
||||
std::list<Thread *>::iterator iter;
|
||||
for(iter = s_threadList.begin();
|
||||
iter != s_threadList.end();
|
||||
++iter) {
|
||||
|
||||
Thread *t = *iter;
|
||||
if(t->getProcessId() == thread_id) return t;
|
||||
|
||||
}
|
||||
|
||||
return 0L; // no thread found;
|
||||
|
||||
};
|
||||
|
||||
void ThreadPrivateActions::ThreadCancelHandler(int sigid) {
|
||||
|
||||
Thread *t = GetThread(getpid());
|
||||
|
||||
if(t != 0L) {
|
||||
|
||||
bool * dieflag = GetDeathFlag(t);
|
||||
|
||||
*dieflag = true;
|
||||
|
||||
sigset(SIGINT, SIG_DFL);
|
||||
unblockproc(getpid());
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// standard start routine.
|
||||
//
|
||||
void ThreadPrivateActions::StartThread(void *data)
|
||||
{
|
||||
|
||||
Thread *thread = static_cast<Thread *>(data);
|
||||
|
||||
if (thread->_prvData==0) return;
|
||||
|
||||
AddThread(thread);
|
||||
|
||||
*((Thread **)&PRDA->usr_prda) = (Thread *)thread;
|
||||
|
||||
SetThreadSchedulingParams(thread);
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *>(thread->_prvData);
|
||||
|
||||
sigset(SIGINT, ThreadCancelHandler);
|
||||
|
||||
size_t defaultStackSize;
|
||||
prctl(PR_GETSTACKSIZE, &defaultStackSize);
|
||||
|
||||
if(defaultStackSize < pd->stackSize) {
|
||||
prctl(PR_SETSTACKSIZE, pd->stackSize);
|
||||
}
|
||||
|
||||
prctl(PR_GETSTACKSIZE, &pd->stackSize);
|
||||
|
||||
pd->stackSizeLocked = true;
|
||||
|
||||
pd->isRunning = true;
|
||||
|
||||
// release the thread that created this thread.
|
||||
pd->threadStartedBlock.release();
|
||||
|
||||
thread->run();
|
||||
|
||||
pd->isRunning = false;
|
||||
|
||||
RemoveThread(thread);
|
||||
|
||||
if(pd->detached == true ) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
};
|
||||
|
||||
void ThreadPrivateActions::AddThread(Thread *thread) {
|
||||
|
||||
s_threadList.push_front(thread);
|
||||
|
||||
};
|
||||
|
||||
void ThreadPrivateActions::RemoveThread(Thread *thread) {
|
||||
s_threadList.remove(thread);
|
||||
};
|
||||
|
||||
void ThreadPrivateActions::PrintThreadSchedulingInfo(Thread *thread) {
|
||||
|
||||
int status, my_policy, min_priority, max_priority;
|
||||
struct sched_param my_param;
|
||||
|
||||
status = sched_getparam(thread->getProcessId(),
|
||||
&my_param);
|
||||
|
||||
my_policy = sched_getscheduler(thread->getProcessId());
|
||||
|
||||
if(status != 0 || my_policy == -1) {
|
||||
|
||||
printf("THREAD INFO (%d) : Get sched param: %s/%s\n",
|
||||
(unsigned int)(thread->getProcessId()),
|
||||
strerror(status),
|
||||
strerror(errno));
|
||||
} else {
|
||||
printf(
|
||||
"THREAD INFO (%d) : Thread running at %s / Priority: %d\n",
|
||||
(unsigned int)(thread->getProcessId()),
|
||||
(my_policy == SCHED_FIFO ? "SCHEDULE_FIFO"
|
||||
: (my_policy == SCHED_RR ? "SCHEDULE_ROUND_ROBIN"
|
||||
: (my_policy == SCHED_TS ? "SCHEDULE_TIME_SHARE"
|
||||
: (my_policy == SCHED_OTHER ? "SCHEDULE_OTHER"
|
||||
: "UNKNOWN")))),
|
||||
my_param.sched_priority);
|
||||
|
||||
max_priority = sched_get_priority_max(my_policy);
|
||||
min_priority = sched_get_priority_min(my_policy);
|
||||
|
||||
printf(
|
||||
"THREAD INFO (%d) : Max priority: %d, Min priority: %d\n",
|
||||
(unsigned int)(thread->getProcessId()),
|
||||
max_priority, min_priority);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int ThreadPrivateActions::SetThreadSchedulingParams(Thread *thread) {
|
||||
|
||||
int status;
|
||||
|
||||
int th_priority;
|
||||
int max_priority, nominal_priority, min_priority;
|
||||
|
||||
max_priority = 0; // This is as high as we can regularly go.
|
||||
min_priority = 20;
|
||||
nominal_priority = (max_priority + min_priority)/2;
|
||||
|
||||
switch(thread->getSchedulePriority()) {
|
||||
|
||||
case Thread::THREAD_PRIORITY_MAX:
|
||||
th_priority = max_priority;
|
||||
break;
|
||||
|
||||
case Thread::THREAD_PRIORITY_HIGH:
|
||||
th_priority = (max_priority + nominal_priority)/2;
|
||||
break;
|
||||
|
||||
case Thread::THREAD_PRIORITY_NOMINAL:
|
||||
th_priority = nominal_priority;
|
||||
break;
|
||||
|
||||
case Thread::THREAD_PRIORITY_LOW:
|
||||
th_priority = (min_priority + nominal_priority)/2;
|
||||
break;
|
||||
|
||||
case Thread::THREAD_PRIORITY_MIN:
|
||||
th_priority = min_priority;
|
||||
break;
|
||||
|
||||
default:
|
||||
th_priority = max_priority;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
status = setpriority(PRIO_PROCESS, thread->getProcessId(),
|
||||
th_priority);
|
||||
|
||||
if(getenv("OUTPUT_THREADLIB_SCHEDULING_INFO") != 0)
|
||||
PrintThreadSchedulingInfo(thread);
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
void ThreadPrivateActions::PushCancelFunction(void (*routine)(void *), void *arg) {
|
||||
|
||||
Thread *thread = GetThread(getpid());
|
||||
|
||||
if(thread != 0L) {
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *>(thread->_prvData);
|
||||
|
||||
SprocThreadPrivateData::CancelFuncStruct c;
|
||||
|
||||
pd->cancelFuncStack.push(c);
|
||||
|
||||
SprocThreadPrivateData::CancelFuncStruct *cft = &(pd->cancelFuncStack.top());
|
||||
|
||||
cft->routine = routine;
|
||||
cft->arg = arg;
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadPrivateActions::PopCancelFunction() {
|
||||
|
||||
Thread *thread = GetThread(getpid());
|
||||
|
||||
if(thread != 0L) {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *>(thread->_prvData);
|
||||
|
||||
if(!pd->cancelFuncStack.empty())
|
||||
pd->cancelFuncStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Set the concurrency level (no-op)
|
||||
//
|
||||
// Use static public
|
||||
//
|
||||
int Thread::SetConcurrency(int concurrencyLevel) {
|
||||
|
||||
return -1;
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Get the concurrency level
|
||||
//
|
||||
// Use static public
|
||||
//
|
||||
int Thread::GetConcurrency() {
|
||||
|
||||
return -1;
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Constructor
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
Thread::Thread() {
|
||||
|
||||
if(!s_isInitialized) Init();
|
||||
|
||||
SprocThreadPrivateData *pd = new SprocThreadPrivateData();
|
||||
pd->stackSize = 128*1024; // Set a minimum of 128K bytes if possible.
|
||||
pd->stackSizeLocked = false;
|
||||
pd->isRunning = false;
|
||||
pd->isCanceled = false;
|
||||
pd->idSet = false;
|
||||
pd->cancelActive = true;
|
||||
pd->detached = false;
|
||||
pd->uniqueId = pd->nextId;
|
||||
pd->nextId++;
|
||||
pd->threadPriority = Thread::THREAD_PRIORITY_DEFAULT;
|
||||
pd->threadPolicy = Thread::THREAD_SCHEDULE_DEFAULT;
|
||||
|
||||
_prvData = static_cast<void *>(pd);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Decription: Destructor
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
Thread::~Thread()
|
||||
{
|
||||
DPRINTF(("(SPROC THREAD) %s:%d, In OpenThreads::Thread destructor\n",
|
||||
__FILE__, __LINE__));
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *>(_prvData);
|
||||
|
||||
if(pd->isRunning)
|
||||
{
|
||||
|
||||
DPRINTF(("(SPROC THREAD) %s:%d, about to kill OpenThreads::Thread\n",
|
||||
__FILE__, __LINE__));
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Kill the process when the thread is destroyed.
|
||||
//
|
||||
cancel();
|
||||
|
||||
join();
|
||||
|
||||
}
|
||||
|
||||
|
||||
DPRINTF(("(SPROC THREAD) %s:%d, Thread destroying private data.\n",
|
||||
__FILE__, __LINE__));
|
||||
|
||||
|
||||
delete pd;
|
||||
|
||||
_prvData = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Initialize Threading
|
||||
//
|
||||
// Use: public.
|
||||
//
|
||||
void Thread::Init() {
|
||||
|
||||
if(s_isInitialized) return;
|
||||
|
||||
#ifdef GP_DEBUG
|
||||
fprintf(stderr, "%s\n", OPENTHREAD_VERSION_STRING);
|
||||
#endif
|
||||
|
||||
s_masterThreadPriority = Thread::THREAD_PRIORITY_MAX;
|
||||
|
||||
s_isInitialized = true;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Return a pointer to the currently executing thread
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
Thread *Thread::CurrentThread() {
|
||||
|
||||
return (*(Thread **)&PRDA->usr_prda);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Get a unique identifier for this thread.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::getThreadId() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
return pd->uniqueId;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Get the thread's process id
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
size_t Thread::getProcessId() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
if(pd->idSet == false) return getpid();
|
||||
|
||||
return (size_t)(pd->pid);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Determine if the thread is running
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
bool Thread::isRunning() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
return pd->isRunning;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Start the thread.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::start() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
pd->threadStartedBlock.reset();
|
||||
|
||||
int pid = sproc(ThreadPrivateActions::StartThread,
|
||||
PR_SALL,
|
||||
static_cast<void *>(this));
|
||||
|
||||
// PR_SADDR | PR_SDIR | PR_SUMASK | PR_SULIMIT | PR_SID,
|
||||
|
||||
if(pid < 0) {
|
||||
perror("sproc encountered an error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Make the thread runnable anywhere.
|
||||
//
|
||||
sysmp(MP_RUNANYWHERE_PID, pid);
|
||||
|
||||
pd->pid = pid;
|
||||
pd->idSet = true;
|
||||
|
||||
// wait till the thread has actually started.
|
||||
pd->threadStartedBlock.block();
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Alternate thread start routine.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::startThread()
|
||||
{
|
||||
if (_prvData) return start();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Join the thread.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::detach() {
|
||||
|
||||
int status = 0;
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
pd->detached=true;
|
||||
sigset(SIGCLD, sproc_dead_child_sig_handler);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Join the thread.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::join() {
|
||||
|
||||
int status;
|
||||
|
||||
return waitpid((pid_t)getProcessId(), &status, 0);
|
||||
//return status;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: test the cancel state of the thread.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::testCancel() {
|
||||
|
||||
if(getpid() != getProcessId()) return -1;
|
||||
|
||||
ThreadPrivateActions::ThreadCancelTest();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Cancel the thread.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::cancel() {
|
||||
|
||||
int status = 0;
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
if(pd->cancelActive) {
|
||||
|
||||
status = kill((pid_t)getProcessId(), SIGINT);
|
||||
};
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Disable cancelibility
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::setCancelModeDisable() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
pd->cancelActive = false;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: set the thread to cancel immediately
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::setCancelModeAsynchronous() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
pd->cancelActive = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: set the thread to cancel at the next convienent point.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::setCancelModeDeferred() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
pd->cancelActive = true;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Set the thread's schedule priority (if able)
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::setSchedulePriority(ThreadPriority priority) {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
pd->threadPriority = priority;
|
||||
|
||||
if(pd->isRunning)
|
||||
return ThreadPrivateActions::SetThreadSchedulingParams(this);
|
||||
else
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Get the thread's schedule priority (if able)
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::getSchedulePriority() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
return pd->threadPriority;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Set the thread's scheduling policy (if able)
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::setSchedulePolicy(ThreadPolicy policy) {
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Set the thread's scheduling policy (if able)
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::getSchedulePolicy() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
return pd->threadPolicy;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Set the thread's desired stack size
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::setStackSize(size_t stackSize) {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
if(pd->stackSizeLocked == true) return 13; // EACESS
|
||||
|
||||
pd->stackSize = stackSize;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Get the thread's stack size.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
size_t Thread::getStackSize() {
|
||||
|
||||
SprocThreadPrivateData *pd =
|
||||
static_cast<SprocThreadPrivateData *> (_prvData);
|
||||
|
||||
return pd->stackSize;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Print the thread's scheduling information to stdout.
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
void Thread::printSchedulingInfo() {
|
||||
|
||||
ThreadPrivateActions::PrintThreadSchedulingInfo(this);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Yield the processor
|
||||
//
|
||||
// Use: protected
|
||||
//
|
||||
int Thread::YieldCurrentThread() {
|
||||
|
||||
return sched_yield();
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Description: sleep
|
||||
//
|
||||
// Use: public
|
||||
//
|
||||
int Thread::microSleep(unsigned int microsec)
|
||||
{
|
||||
return ::usleep(microsec);
|
||||
}
|
||||
|
||||
static void sproc_dead_child_sig_handler(int sigid) {
|
||||
|
||||
#ifdef DEBUG
|
||||
int pid, status;
|
||||
pid = wait(&status);
|
||||
DPRINTF(("(SPROC THREAD) Dead Child Handler Caught Signal, Reaped %d\n",
|
||||
pid));
|
||||
#endif
|
||||
|
||||
sigset(SIGCLD, sproc_dead_child_sig_handler);
|
||||
|
||||
}
|
||||
|
||||
int Thread::setProcessorAffinity( unsigned int cpunum )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Description: Get the number of processors
|
||||
//
|
||||
int OpenThreads::GetNumberOfProcessors()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OpenThreads::SetProcessorAffinityOfCurrentThread(unsigned int cpunum)
|
||||
{
|
||||
Thread::Init();
|
||||
|
||||
Thread* thread = Thread::CurrentThread();
|
||||
if (thread)
|
||||
{
|
||||
return thread->setProcessorAffinity(cpunum);
|
||||
}
|
||||
else
|
||||
{
|
||||
// non op right now, needs implementation.
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// SprocThreadPrivateActions.c++ - Thread private actions for sprocs
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#include <OpenThreads/Thread>
|
||||
#include <list>
|
||||
|
||||
#ifndef SPROC_THREAD_PRIVATE_ACTIONS
|
||||
#define SPROC_THREAD_PRIVATE_ACTIONS
|
||||
|
||||
namespace OpenThreads {
|
||||
|
||||
class ThreadPrivateActions {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// We're friendly to Thread, so it can issue the methods.
|
||||
//
|
||||
friend class Thread;
|
||||
|
||||
public:
|
||||
|
||||
static void ThreadCancelTest();
|
||||
|
||||
static void PushCancelFunction(void (*routine)(void *), void *arg);
|
||||
|
||||
static void PopCancelFunction();
|
||||
|
||||
private:
|
||||
|
||||
static bool *GetDeathFlag(Thread *thread);
|
||||
|
||||
static Thread *GetThread(pid_t thread_id);
|
||||
|
||||
static void ThreadCancelHandler(int sigid);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// standard start routine.
|
||||
//
|
||||
static void StartThread(void *data);
|
||||
|
||||
static void AddThread(Thread *thread);
|
||||
|
||||
static void RemoveThread(Thread *thread);
|
||||
|
||||
static void PrintThreadSchedulingInfo(Thread *thread);
|
||||
|
||||
static int SetThreadSchedulingParams(Thread *thread);
|
||||
|
||||
private:
|
||||
|
||||
static std::list<Thread *> s_threadList;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !SPROC_THREAD_PRIVATE_ACTIONS
|
||||
@@ -1,84 +0,0 @@
|
||||
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
//
|
||||
//
|
||||
// SprocThreadPrivateData.h - private data for sproc thread
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#ifndef _SPROCTHREADPRIVATEDATA_H_
|
||||
#define _SPROCTHREADPRIVATEDATA_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ulocks.h>
|
||||
#include <stack>
|
||||
|
||||
#include <OpenThreads/Thread>
|
||||
#include <OpenThreads/Block>
|
||||
#include "SprocThreadPrivateActions.h"
|
||||
|
||||
namespace OpenThreads {
|
||||
|
||||
class SprocThreadPrivateData {
|
||||
|
||||
friend class Thread;
|
||||
|
||||
friend class ThreadPrivateActions;
|
||||
|
||||
private:
|
||||
|
||||
struct CancelFuncStruct {
|
||||
|
||||
void (*routine)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
SprocThreadPrivateData() {};
|
||||
|
||||
virtual ~SprocThreadPrivateData() {};
|
||||
|
||||
volatile unsigned int stackSize;
|
||||
|
||||
volatile bool stackSizeLocked;
|
||||
|
||||
volatile bool isRunning;
|
||||
|
||||
Block threadStartedBlock;
|
||||
|
||||
volatile bool isCanceled;
|
||||
|
||||
volatile bool idSet;
|
||||
|
||||
volatile bool cancelActive;
|
||||
|
||||
volatile bool detached;
|
||||
|
||||
volatile bool dieFlag;
|
||||
|
||||
volatile Thread::ThreadPriority threadPriority;
|
||||
|
||||
volatile Thread::ThreadPolicy threadPolicy;
|
||||
|
||||
volatile pid_t pid;
|
||||
|
||||
volatile int uniqueId;
|
||||
|
||||
std::stack<CancelFuncStruct> cancelFuncStack;
|
||||
|
||||
static int nextId;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !_SPROCTHREADPRIVATEDATA_H_
|
||||
Reference in New Issue
Block a user