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
      );
   }
}
Exemple #2
0
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);
}
Exemple #3
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;

    };
Exemple #4
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;

    };