void ThreadPosix::setRunOn(const int cpu) { if ( ThreadPosix::self() == this ) { if ( cpu < 0 ) { std::ostringstream msg_stream; msg_stream << "Illegal CPU identifier " << cpu << " is less than 0"; throw vpr::IllegalArgumentException(msg_stream.str(), VPR_LOCATION); } #if defined(VPR_OS_IRIX) if ( mScope == VPR_GLOBAL_THREAD ) { pthread_setrunon_np(cpu); } else { throw vpr::IllegalArgumentException( "This thread is not a system-scope thread", VPR_LOCATION ); } #elif defined(VPR_OS_Linux) if ( sysconf(_SC_NPROCESSORS_CONF) > cpu ) { const pid_t thread_id(syscall(__NR_gettid)); if ( thread_id ) { cpu_set_t cpu_mask; CPU_ZERO(&cpu_mask); CPU_SET(cpu, &cpu_mask); const int result = sched_setaffinity(thread_id, sizeof(cpu_mask), &cpu_mask); if ( result != 0 ) { std::ostringstream msg_stream; msg_stream << "Failed to set CPU affinity: " << vpr::Error::getCurrentErrorMsg(); throw vpr::Exception(msg_stream.str(), VPR_LOCATION); } } } #else boost::ignore_unused_variable_warning(cpu); std::cerr << "vpr::ThreadPosix::setRunOn(): Not available on this " << "operating system!\n"; #endif } else { throw vpr::IllegalArgumentException( "CPU affinity can only be set for a thread object from its thread", VPR_LOCATION ); } }
static int ATL_setmyaffinity() /* * Attempts to sets the affinity of an already-running thread. The * aff_set flag is set to true whether we succeed or not (no point in * trying multiple times). * RETURNS: 0 on success, non-zero error code on error */ { int bindID; bindID = omp_get_thread_num(); #ifdef ATL_RANK_IS_PROCESSORID bindID = bindID % ATL_AFF_NUMID; #else bindID = ATL_affinityIDs[bindID%ATL_AFF_NUMID]; #endif #ifdef ATL_PAFF_PLPA plpa_cpu_set_t cpuset; PLPA_CPU_ZERO(&cpuset); PLPA_CPU_SET(bindID, &cpuset); if (me->paff_set) return(0); me->paff_set = 1; return(plpa_sched_setaffinity((pid_t)0, sizeof(cpuset), &cpuset)); #elif defined(ATL_PAFF_PBIND) return(processor_bind(P_LWPID, P_MYID, bindID, NULL)); #elif defined(ATL_PAFF_SCHED) cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(bindID, &cpuset); if (me->paff_set) return(0); me->paff_set = 1; return(sched_setaffinity(0, sizeof(cpuset), &cpuset)); #elif defined (ATL_PAFF_RUNON) if (me->paff_set) return(0); me->paff_set = 1; return(pthread_setrunon_np(bindID)); #elif defined(ATL_PAFF_BINDP) if (me->paff_set) return(0); me->paff_set = 1; return(bindprocessor(BINDTHREAD, thread_self(), bindID)); #elif defined(ATL_PAFF_CPUSET) /* untried FreeBSD code */ cpuset_t mycpuset; CPU_ZERO(&mycpuset); /* no manpage, so guess works like linux */ CPU_SET(bindID, &mycpuset); if (me->paff_set) return(0); me->paff_set = 1; return(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mycpuset), &mycpuset)); #endif return(0); }
//------------------------------------------------------------------------- // 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 } #if defined(HAVE_PTHREAD_SETAFFINITY_NP) || defined(HAVE_THREE_PARAM_SCHED_SETAFFINITY) || defined(HAVE_TWO_PARAM_SCHED_SETAFFINITY) else { // BUG-fix for linux: // Each thread inherits the processor affinity mask from its parent thread. // We need to explicitly set it to all CPUs, if no affinity was specified. cpu_set_t cpumask; CPU_ZERO( &cpumask ); for (int i = 0; i < OpenThreads::GetNumberOfProcessors(); ++i) { CPU_SET( i, &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->setRunning(true); // release the thread that created this thread. pd->threadStartedBlock.release(); thread->run(); pd->setRunning(false); pthread_cleanup_pop(0); return 0; };
//------------------------------------------------------------------------- // 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; };