Hi Robert,

the long promised patch to implement the sched_setaffinity in a way that 
matches the system it is compiled on.
That is there is a cmake configure test to make sure we use the version 
available on the system

There are also various improovements to other system specific methods for less 
common architectures.

The attached files arebased on rev 7491. The CMakeLists.txt file is the one in 
src/OpenThreads/pthreads/CMakeLists.txt

Please apply

     thanks

         Mathias

-- 
Dr. Mathias Fröhlich, science + computing ag, Software Solutions
Hagellocher Weg 71-75, D-72070 Tuebingen, Germany
Phone: +49 7071 9457-268, Fax: +49 7071 9457-511
-- 
Vorstand/Board of Management:
Dr. Bernd Finkbeiner, Dr. Florian Geyer,
Dr. Roland Niemeier, Dr. Arno Steitz, Dr. Ingrid Zech
Vorsitzender des Aufsichtsrats/
Chairman of the Supervisory Board:
Prof. Dr. Hanns Ruder
Sitz/Registered Office: Tuebingen
Registergericht/Registration Court: Stuttgart
Registernummer/Commercial Register No.: HRB 382196 

# This file should only be included when using Pthreads

INCLUDE (CheckFunctionExists)
INCLUDE (CheckLibraryExists)
INCLUDE (CheckSymbolExists)
INCLUDE (CheckCXXSourceCompiles)

SET(LIB_NAME OpenThreads)
SET(LIB_PUBLIC_HEADERS ${OpenThreads_PUBLIC_HEADERS})

ADD_LIBRARY(${LIB_NAME}
    ${OPENTHREADS_USER_DEFINED_DYNAMIC_OR_STATIC}
    ${LIB_PUBLIC_HEADERS}
        PThread.c++
        PThreadBarrier.c++
        PThreadBarrierPrivateData.h
        PThreadCondition.c++
        PThreadConditionPrivateData.h
        PThreadMutex.c++
        PThreadMutexPrivateData.h
        PThreadPrivateData.h
        ../common/Version.cpp
)

IF(OPENTHREADS_SONAMES)
  SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES VERSION ${OPENTHREADS_VERSION} 
SOVERSION ${OPENTHREADS_SOVERSION})
ENDIF(OPENTHREADS_SONAMES)

SET(CMAKE_REQUIRED_LIBRARIES_SAFE "${CMAKE_REQUIRED_LIBRARIES}")
SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES} 
${CMAKE_THREAD_LIBS_INIT}")

CHECK_FUNCTION_EXISTS(pthread_yield HAVE_PTHREAD_YIELD)
IF(HAVE_PTHREAD_YIELD)
  ADD_DEFINITIONS(-DHAVE_PTHREAD_YIELD)
ELSE(HAVE_PTHREAD_YIELD)
  # sched_yield appears not in libc, pthreads or whatever on some systems
  CHECK_FUNCTION_EXISTS(sched_yield HAVE_SCHED_YIELD)
  IF(NOT HAVE_SCHED_YIELD)
    CHECK_LIBRARY_EXISTS(rt sched_yield "" HAVE_SCHED_YIELD)
    IF(HAVE_SCHED_YIELD)
      SET(CMAKE_THREAD_LIBS_INIT "${CMAKE_THREAD_LIBS_INIT} -lrt")
    ENDIF(HAVE_SCHED_YIELD)
  ENDIF(NOT HAVE_SCHED_YIELD)
  IF(HAVE_SCHED_YIELD)
    ADD_DEFINITIONS(-DHAVE_SCHED_YIELD)
  ENDIF(HAVE_SCHED_YIELD)
ENDIF(HAVE_PTHREAD_YIELD)

IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
  # need to have that for pthread_setaffinity_np on linux
  ADD_DEFINITIONS(-D_GNU_SOURCE)
  SET(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE")
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")

CHECK_FUNCTION_EXISTS(pthread_setconcurrency HAVE_PTHREAD_SETCONCURRENCY)
IF(HAVE_PTHREAD_SETCONCURRENCY)
  ADD_DEFINITIONS(-DHAVE_PTHREAD_SETCONCURRENCY)
ENDIF(HAVE_PTHREAD_SETCONCURRENCY)

CHECK_FUNCTION_EXISTS(pthread_getconcurrency HAVE_PTHREAD_GETCONCURRENCY)
IF(HAVE_PTHREAD_GETCONCURRENCY)
  ADD_DEFINITIONS(-DHAVE_PTHREAD_GETCONCURRENCY)
ENDIF(HAVE_PTHREAD_GETCONCURRENCY)

CHECK_FUNCTION_EXISTS(pthread_setaffinity_np HAVE_PTHREAD_SETAFFINITY_NP)
IF(HAVE_PTHREAD_SETAFFINITY_NP)
  ADD_DEFINITIONS(-DHAVE_PTHREAD_SETAFFINITY_NP)
ELSE(HAVE_PTHREAD_SETAFFINITY_NP)
  CHECK_CXX_SOURCE_COMPILES("
#include <sched.h>
int main() {
  cpu_set_t cpumask;
  sched_setaffinity( 0, sizeof(cpumask), &cpumask );
  return 0;
}" HAVE_THREE_PARAM_SCHED_SETAFFINITY)
  IF(HAVE_THREE_PARAM_SCHED_SETAFFINITY)
    ADD_DEFINITIONS(-DHAVE_THREE_PARAM_SCHED_SETAFFINITY)
  ELSE(HAVE_THREE_PARAM_SCHED_SETAFFINITY)
    CHECK_CXX_SOURCE_COMPILES("
#include <sched.h>
int main() {
  cpu_set_t cpumask;
  sched_setaffinity( 0, &cpumask );
  return 0;
}" HAVE_TWO_PARAM_SCHED_SETAFFINITY)
    IF(HAVE_TWO_PARAM_SCHED_SETAFFINITY)
      ADD_DEFINITIONS(-DHAVE_TWO_PARAM_SCHED_SETAFFINITY)
    ENDIF(HAVE_TWO_PARAM_SCHED_SETAFFINITY)
  ENDIF(HAVE_THREE_PARAM_SCHED_SETAFFINITY)
ENDIF(HAVE_PTHREAD_SETAFFINITY_NP)

SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES_SAFE}")

TARGET_LINK_LIBRARIES(${LIB_NAME}
        ${CMAKE_THREAD_LIBS_INIT}
)

# 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}
        LIBRARY DESTINATION lib${LIB_POSTFIX}
        RUNTIME DESTINATION bin
)
INSTALL(
        FILES ${OpenThreads_PUBLIC_HEADERS}
        DESTINATION include/OpenThreads
)

#commented out# INCLUDE(ModuleInstall OPTIONAL)
/* -*-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.
*/


//
// PThread.c++ - C++ Thread class built on top of posix threads.
// ~~~~~~~~~~~

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

#if defined __linux || defined __sun || defined __APPLE__
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/unistd.h>
#endif
#if defined(__sgi)
#include <unistd.h>
#endif
#if defined(__hpux)
#include <sys/mpctl.h>
#endif

#if defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY) || defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)
#    include <sched.h>
#endif
#if defined (__FreeBSD__) || defined (__APPLE__) || defined (__MACH__)
	#include <sys/types.h>
	#include <sys/sysctl.h>
#endif

#include <OpenThreads/Thread>
#include "PThreadPrivateData.h"

#include <iostream>

using namespace OpenThreads;

extern int errno;
const char *OPENTHREAD_VERSION_STRING = "OpenThreads v1.2preAlpha, Posix Threads (Public Implementation)";

#ifdef DEBUG
# define DPRINTF(arg) printf arg
#else
# define DPRINTF(arg)
#endif

//-----------------------------------------------------------------------------
// Initialize the static unique ids.
//
int PThreadPrivateData::nextId = 0;

//-----------------------------------------------------------------------------
// Initialize thread master priority level
//
Thread::ThreadPriority Thread::s_masterThreadPriority =
                                          Thread::THREAD_PRIORITY_DEFAULT;

bool Thread::s_isInitialized = false;
pthread_key_t PThreadPrivateData::s_tls_key;

struct ThreadCleanupStruct {

    OpenThreads::Thread *thread;
    volatile bool *runflag;

};

//-----------------------------------------------------------------------------
// This cleanup handler is necessary to ensure that the thread will cleanup
// and set its isRunning flag properly.
//
void thread_cleanup_handler(void *arg) {

    ThreadCleanupStruct *tcs = static_cast<ThreadCleanupStruct *>(arg);

    tcs->thread->cancelCleanup();
    *(tcs->runflag) = false;

}

//-----------------------------------------------------------------------------
// Class to support some static methods necessary for pthread's to work
// correctly.
//

namespace OpenThreads {

class ThreadPrivateActions {

    //-------------------------------------------------------------------------
    // We're friendly to Thread, so it can issue the methods.
    //
    friend class Thread;

private:

    //-------------------------------------------------------------------------
    // pthreads standard start routine.
    //
    static void *StartThread(void *data) {

	Thread *thread = static_cast<Thread *>(data);

	PThreadPrivateData *pd =
	    static_cast<PThreadPrivateData *>(thread->_prvData);
            

        if (pd->cpunum>=0)
        {
#if defined(__sgi)
            pthread_setrunon_np( pd->cpunum );
#elif defined(HAVE_PTHREAD_SETAFFINITY_NP) || defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY) || defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)
            cpu_set_t cpumask;
            CPU_ZERO( &cpumask );
            CPU_SET( pd->cpunum, &cpumask );

#if defined(HAVE_PTHREAD_SETAFFINITY_NP)
            pthread_setaffinity_np( pthread_self(), sizeof(cpumask), &cpumask);
#elif defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY)
            sched_setaffinity( 0, sizeof(cpumask), &cpumask );
#elif defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)
            sched_setaffinity( 0, &cpumask );
#endif
#endif
        }
        

	ThreadCleanupStruct tcs;
	tcs.thread = thread;
	tcs.runflag = &pd->isRunning;

	// Set local storage so that Thread::CurrentThread() can return the right thing
	int status = pthread_setspecific(PThreadPrivateData::s_tls_key, thread);
	if (status)
        {
            printf("Error: pthread_setspecific(,) returned error status, status = %d\n",status);
        }

	pthread_cleanup_push(thread_cleanup_handler, &tcs);

#ifdef ALLOW_PRIORITY_SCHEDULING

	//---------------------------------------------------------------------
	// Set the proper scheduling priorities
	//
	SetThreadSchedulingParams(thread);

#endif // ] ALLOW_PRIORITY_SCHEDULING

        pd->isRunning = true;

        // release the thread that created this thread.
        pd->threadStartedBlock.release();

        thread->run();

        pd->isRunning = false;

	pthread_cleanup_pop(0);

        return 0;

    };

    //-------------------------------------------------------------------------
    // Print information related to thread schduling parameters.
    //
    static void PrintThreadSchedulingInfo(Thread *thread) {

#ifdef ALLOW_PRIORITY_SCHEDULING // [

	if(sysconf(_POSIX_THREAD_PRIORITY_SCHEDULING)) {

	    int status, my_policy, min_priority, max_priority;
	    struct sched_param my_param;

	    status = pthread_getschedparam(thread->getProcessId(),
					   &my_policy,
					   &my_param);

	    if(status != 0) {
		printf("THREAD INFO (%d) : Get sched: %s\n",
		       thread->getProcessId(),
		       strerror(status));
	    } else {
		printf(
		    "THREAD INFO (%d) : Thread running at %s / Priority: %d\n",
		    thread->getProcessId(),
		    (my_policy == SCHED_FIFO ? "SCHEDULE_FIFO"
		     : (my_policy == SCHED_RR ? "SCHEDULE_ROUND_ROBIN"
			: (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",
		    thread->getProcessId(),
		    max_priority, min_priority);

	    }

	} else {
	    printf(
		"THREAD INFO (%d) POSIX Priority scheduling not available\n",
		thread->getProcessId());
	}

	fflush(stdout);

#endif // ] ALLOW_PRIORITY_SCHEDULING

    }

    //--------------------------------------------------------------------------
    // Set thread scheduling parameters.  Unfortunately on Linux, there's no
    // good way to set this, as pthread_setschedparam is mostly a no-op.
    //
    static int SetThreadSchedulingParams(Thread *thread) {

	int status = 0;

#ifdef ALLOW_PRIORITY_SCHEDULING // [

	if(sysconf(_POSIX_THREAD_PRIORITY_SCHEDULING)) {

	    int th_policy;
	    int max_priority, nominal_priority, min_priority;
	    sched_param th_param;
	    pthread_getschedparam(thread->getProcessId(),
				  &th_policy, &th_param);

#ifndef __linux__

	    switch(thread->getSchedulePolicy()) {

	    case Thread::THREAD_SCHEDULE_FIFO:
		th_policy = SCHED_FIFO;
		break;

	    case Thread::THREAD_SCHEDULE_ROUND_ROBIN:
		th_policy = SCHED_RR;
		break;

	    case Thread::THREAD_SCHEDULE_TIME_SHARE:
		th_policy = SCHED_OTHER;
		break;

	    default:
#ifdef __sgi
		th_policy = SCHED_RR;
#else
		th_policy = SCHED_FIFO;
#endif
		break;
	    };

#else
	    th_policy = SCHED_OTHER;  // Must protect linux from realtime.
#endif

#ifdef __linux__

	    max_priority = 0;
	    min_priority = 20;
	    nominal_priority = (max_priority + min_priority)/2;

#else

	    max_priority = sched_get_priority_max(th_policy);
	    min_priority = sched_get_priority_min(th_policy);
	    nominal_priority = (max_priority + min_priority)/2;

#endif

	    switch(thread->getSchedulePriority()) {

	    case Thread::THREAD_PRIORITY_MAX:
		th_param.sched_priority = max_priority;
		break;

	    case Thread::THREAD_PRIORITY_HIGH:
		th_param.sched_priority = (max_priority + nominal_priority)/2;
		break;

	    case Thread::THREAD_PRIORITY_NOMINAL:
		th_param.sched_priority = nominal_priority;
		break;

	    case Thread::THREAD_PRIORITY_LOW:
		th_param.sched_priority = (min_priority + nominal_priority)/2;
		break;

	    case Thread::THREAD_PRIORITY_MIN:
		th_param.sched_priority = min_priority;
		break;

	    default:
		th_param.sched_priority = max_priority;
		break;

	    }

	    status = pthread_setschedparam(thread->getProcessId(),
					   th_policy,
					   &th_param);


	    if(getenv("OUTPUT_THREADLIB_SCHEDULING_INFO") != 0)
		PrintThreadSchedulingInfo(thread);

	}

#endif // ] ALLOW_PRIORITY_SCHEDULING

	return status;
    };
};

}

//----------------------------------------------------------------------------
//
// Description: Set the concurrency level (no-op)
//
// Use static public
//
int Thread::SetConcurrency(int concurrencyLevel) {

#if defined (HAVE_PTHREAD_SETCONCURRENCY)
    return pthread_setconcurrency(concurrencyLevel);
#else
    return -1;
#endif

}

//----------------------------------------------------------------------------
//
// Description: Get the concurrency level
//
// Use static public
//
int Thread::GetConcurrency() {

#if defined (HAVE_PTHREAD_GETCONCURRENCY)
    return pthread_getconcurrency();
#else
    return -1;
#endif

}

//----------------------------------------------------------------------------
//
// Decription: Constructor
//
// Use: public.
//
Thread::Thread() {

    if(!s_isInitialized) Init();

    PThreadPrivateData *pd = new PThreadPrivateData();
    pd->stackSize = 0;
    pd->stackSizeLocked = false;
    pd->idSet = false;
    pd->isRunning = false;
    pd->isCanceled = false;
    pd->uniqueId = pd->nextId;
    pd->nextId++;
    pd->threadPriority = Thread::THREAD_PRIORITY_DEFAULT;
    pd->threadPolicy = Thread::THREAD_SCHEDULE_DEFAULT;
    pd->cpunum = -1;

    _prvData = static_cast<void *>(pd);

}

//----------------------------------------------------------------------------
//
// Decription: Destructor
//
// Use: public.
//
Thread::~Thread()
{
    PThreadPrivateData *pd = static_cast<PThreadPrivateData *>(_prvData);

    if(pd->isRunning)
    {
        std::cout<<"Error: Thread "<<this<<" still running in destructor"<<std::endl;

	//---------------------------------------------------------------------
	// Kill the thread when it is destructed
	//
	cancel();
    }

    delete pd;
    
    _prvData = 0;
}

Thread *Thread::CurrentThread()
{

    Thread *thread =
	static_cast<Thread *>(pthread_getspecific(PThreadPrivateData::s_tls_key));

    return thread;

}

//-----------------------------------------------------------------------------
//
// Description: Initialize Threading
//
// Use: public.
//
void Thread::Init() {

    if(s_isInitialized) return;

    // Allocate a key to be used to access thread local storage
    int status = pthread_key_create(&PThreadPrivateData::s_tls_key, NULL);
    if (status)
    {
        printf("Error: pthread_key_create(,) returned error status, status = %d\n",status);
    }

#ifdef ALLOW_PRIORITY_SCHEDULING

    //--------------------------------------------------------------------------
    // If we've got priority scheduling, set things to nominal.
    //
    if(sysconf(_POSIX_THREAD_PRIORITY_SCHEDULING)) {

	int max_priority, nominal_priority, min_priority;

	int th_policy;
	sched_param th_param;
	pthread_getschedparam(pthread_self(),
			      &th_policy, &th_param);

	max_priority = sched_get_priority_max(th_policy);
	min_priority = sched_get_priority_min(th_policy);
	nominal_priority = (max_priority + min_priority)/2;

	th_param.sched_priority = nominal_priority;

	pthread_setschedparam(pthread_self(),
			      th_policy,
			      &th_param);

	s_masterThreadPriority = Thread::THREAD_PRIORITY_NOMINAL;

    } else {

	s_masterThreadPriority = Thread::THREAD_PRIORITY_DEFAULT;

    }

#endif // ] ALLOW_PRIORITY_SCHEDULING

    s_isInitialized = true;

}

//-----------------------------------------------------------------------------
//
// Description: Get a unique identifier for this thread.
//
// Use: public
//
int Thread::getThreadId() {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);
    return pd->uniqueId;
}

//-----------------------------------------------------------------------------
//
// Description: Get the thread's process id
//
// Use: public
//
size_t Thread::getProcessId() {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);

    if(pd->idSet == false) return (size_t)(pthread_self());

    return (size_t)(pd->tid);
}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's processor affinity
//
// Use: public
//
int Thread::setProcessorAffinity(unsigned int cpunum)
{
    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);
    pd->cpunum = cpunum;
    if (pd->cpunum<0) return -1;
    
#ifdef __sgi

    int status;
    pthread_attr_t thread_attr;

    status = pthread_attr_init( &thread_attr );
    if(status != 0) {
        return status;
     }

    status = pthread_attr_setscope( &thread_attr, PTHREAD_SCOPE_BOUND_NP );
    return status;

#elif defined(HAVE_PTHREAD_SETAFFINITY_NP) || defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY) || defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)

    if (pd->isRunning && Thread::CurrentThread()==this)
    {
        cpu_set_t cpumask;
        CPU_ZERO( &cpumask );
        CPU_SET( pd->cpunum, &cpumask );
#if defined(HAVE_PTHREAD_SETAFFINITY_NP)
        pthread_setaffinity_np (pthread_self(), sizeof(cpumask), &cpumask);
#elif defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY)
        sched_setaffinity( 0, sizeof(cpumask), &cpumask );
#elif defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)
        sched_setaffinity( 0, &cpumask );
#endif
    }

    return -1;
#else
    return -1;
#endif

}

//-----------------------------------------------------------------------------
//
// Description: Determine if the thread is running
//
// Use: public
//
bool Thread::isRunning() {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);
    return pd->isRunning;

}

//-----------------------------------------------------------------------------
//
// Description: Start the thread.
//
// Use: public
//
int Thread::start() {

    int status;
    pthread_attr_t thread_attr;

    status = pthread_attr_init( &thread_attr );
    if(status != 0) {
	return status;
    }

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);

    size_t defaultStackSize;
    pthread_attr_getstacksize( &thread_attr, &defaultStackSize);
    if(status != 0) {
	return status;
    }

    if(defaultStackSize < pd->stackSize) {

	pthread_attr_setstacksize( &thread_attr, pd->stackSize);
	if(status != 0) {
	    return status;
	}
    }

    //-------------------------------------------------------------------------
    // Now get what we actually have...
    //
    pthread_attr_getstacksize( &thread_attr, &defaultStackSize);
    if(status != 0) {
	return status;
    }

    pd->stackSize = defaultStackSize;

    //-------------------------------------------------------------------------
    // Prohibit the stack size from being changed.
    //
    pd->stackSizeLocked = true;

#ifdef ALLOW_PRIORITY_SCHEDULING

    status = pthread_attr_setinheritsched( &thread_attr,
					   PTHREAD_EXPLICIT_SCHED );

    pthread_attr_setscope(&thread_attr, PTHREAD_SCOPE_SYSTEM);

#endif // ] ALLOW_PRIORITY_SCHEDULING

    if(status != 0) {
	return status;
    }

    pd->threadStartedBlock.reset();

    status = pthread_create(&(pd->tid), &thread_attr,
                           ThreadPrivateActions::StartThread,
                           static_cast<void *>(this));
                           
    // wait till the thread has actually started.
    pd->threadStartedBlock.block();

    if(status != 0) {
	return status;
    }

    pd->idSet = true;

    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() {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);
    return pthread_detach(pd->tid);

}

//-----------------------------------------------------------------------------
//
// Description: Join the thread.
//
// Use: public
//
int Thread::join() {

    void *threadResult = 0; // Dummy var.
    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);
    return pthread_join(pd->tid, &threadResult);

}

//-----------------------------------------------------------------------------
//
// Description: test the cancel state of the thread.
//
// Use: public
//
int Thread::testCancel() {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);

    if(pthread_self() != pd->tid)
	return -1;

    pthread_testcancel();

    return 0;

}


//-----------------------------------------------------------------------------
//
// Description: Cancel the thread.
//
// Use: public
//
int Thread::cancel() {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);
    if (pd->isRunning)
    {
        pd->isCanceled = true;
        int status = pthread_cancel(pd->tid);
        return status;
    }
    return 0;
}

//-----------------------------------------------------------------------------
//
// Description: Disable cancelibility
//
// Use: public
//
int Thread::setCancelModeDisable() {

    return pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, 0 );

}

//-----------------------------------------------------------------------------
//
// Description: set the thread to cancel immediately
//
// Use: public
//
int Thread::setCancelModeAsynchronous() {

    int status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
    if(status != 0) return status;

    return pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, 0);
}

//-----------------------------------------------------------------------------
//
// Description: set the thread to cancel at the next convienent point.
//
// Use: public
//
int Thread::setCancelModeDeferred() {

    int status = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
    if(status != 0) return status;

    return pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, 0);

}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's schedule priority (if able)
//
// Use: public
//
int Thread::setSchedulePriority(ThreadPriority priority) {

#ifdef ALLOW_PRIORITY_SCHEDULING

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);

    pd->threadPriority = priority;

    if(pd->isRunning)
	return ThreadPrivateActions::SetThreadSchedulingParams(this);
    else
	return 0;

#else
    return -1;
#endif

}

//-----------------------------------------------------------------------------
//
// Description: Get the thread's schedule priority (if able)
//
// Use: public
//
int Thread::getSchedulePriority() {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);

    return pd->threadPriority;

}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's scheduling policy (if able)
//
// Use: public
//
int Thread::setSchedulePolicy(ThreadPolicy policy) {

#ifdef ALLOW_PRIORITY_SCHEDULING

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);

    pd->threadPolicy = policy;

    if(pd->isRunning)
	return ThreadPrivateActions::SetThreadSchedulingParams(this);
    else
	return 0;
#else
    return -1;
#endif

}

//-----------------------------------------------------------------------------
//
// Description: Set the thread's scheduling policy (if able)
//
// Use: public
//
int Thread::getSchedulePolicy() {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_prvData);

    return pd->threadPolicy;

}


//-----------------------------------------------------------------------------
//
// Description: Set the thread's desired stack size
//
// Use: public
//
int Thread::setStackSize(size_t stackSize) {

    PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_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() {

   PThreadPrivateData *pd = static_cast<PThreadPrivateData *> (_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()
{
#if defined(HAVE_PTHREAD_YIELD)
    return pthread_yield();
#elif defined(HAVE_SCHED_YIELD)
    return sched_yield();
#else
    return -1;
#endif
}

// Description:  sleep
//
// Use: public
//
int Thread::microSleep(unsigned int microsec)
{
    return ::usleep(microsec);
}



//-----------------------------------------------------------------------------
//
// Description:  Get the number of processors
//
int OpenThreads::GetNumberOfProcessors()
{
#if defined(__linux__)
   long ret = sysconf(_SC_NPROCESSORS_ONLN);
   if (ret == -1)
      return 0;
   return ret;
#elif defined(__sun__)
   long ret = sysconf(_SC_NPROCESSORS_ONLN);
   if (ret == -1)
      return 0;
   return ret;
#elif defined(__sgi)
   long ret = sysconf(_SC_NPROC_ONLN);
   if (ret == -1)
      return 0;
   return ret;
#elif defined(__hpux)
   int ret = mpctl(MPC_GETNUMSPUS, 0, NULL);
   if (ret == -1)
      return 0;
   return ret;
#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(__MACH__)
   uint64_t num_cpus = 0;
   size_t num_cpus_length = sizeof(num_cpus);
#if defined(__FreeBSD__)
   sysctlbyname("hw.ncpu", &num_cpus, &num_cpus_length, NULL, 0);			
#else
   sysctlbyname("hw.activecpu", &num_cpus, &num_cpus_length, NULL, 0);
#endif
   return num_cpus;
#else
   return 1;
#endif
}

int OpenThreads::SetProcessorAffinityOfCurrentThread(unsigned int cpunum)
{
    if (cpunum<0) return -1;
    
    Thread::Init();

    Thread* thread = Thread::CurrentThread();
    if (thread) 
    {
        return thread->setProcessorAffinity(cpunum);
    }
    else
    {
#if defined(HAVE_PTHREAD_SETAFFINITY_NP) || defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY) || defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)
        cpu_set_t cpumask;
        CPU_ZERO( &cpumask );
        CPU_SET( cpunum, &cpumask );

#if defined(HAVE_PTHREAD_SETAFFINITY_NP)
        pthread_setaffinity_np( pthread_self(), sizeof(cpumask), &cpumask);
#elif defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY)
        sched_setaffinity( 0, sizeof(cpumask), &cpumask );
#elif defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY)
        sched_setaffinity( 0, &cpumask );
#endif
#endif
    }
    
    return -1;
}
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to