Ejemplo n.º 1
0
void bindThread(uint32_t threadId, uint32_t procGroupId = 0)
{
#if defined(_WIN32)
    {
        GROUP_AFFINITY affinity = {};
        affinity.Group = procGroupId;

#if !defined(_WIN64)
        if (threadId >= 32)
        {
            // In a 32-bit process on Windows it is impossible to bind
            // to logical processors 32-63 within a processor group.
            // In this case set the mask to 0 and let the system assign
            // the processor.  Hopefully it will make smart choices.
            affinity.Mask = 0;
        }
        else
#endif
        {
            affinity.Mask = KAFFINITY(1) << threadId;
        }

        SetThreadGroupAffinity(GetCurrentThread(), &affinity, nullptr);
    }
#else
    cpu_set_t cpuset;
    pthread_t thread = pthread_self();
    CPU_ZERO(&cpuset);
    CPU_SET(threadId, &cpuset);

    pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
#endif
}
Ejemplo n.º 2
0
void bindThread(SWR_CONTEXT* pContext, uint32_t threadId, uint32_t procGroupId = 0, bool bindProcGroup=false)
{
    // Only bind threads when MAX_WORKER_THREADS isn't set.
    if (pContext->threadInfo.SINGLE_THREADED || (pContext->threadInfo.MAX_WORKER_THREADS && bindProcGroup == false))
    {
        return;
    }

#if defined(_WIN32)

    GROUP_AFFINITY affinity = {};
    affinity.Group = procGroupId;

#if !defined(_WIN64)
    if (threadId >= 32)
    {
        // Hopefully we don't get here.  Logic in CreateThreadPool should prevent this.
        SWR_INVALID("Shouldn't get here");

        // In a 32-bit process on Windows it is impossible to bind
        // to logical processors 32-63 within a processor group.
        // In this case set the mask to 0 and let the system assign
        // the processor.  Hopefully it will make smart choices.
        affinity.Mask = 0;
    }
    else
#endif
    {
        // If MAX_WORKER_THREADS is set, only bind to the proc group,
        // Not the individual HW thread.
        if (!bindProcGroup  && !pContext->threadInfo.MAX_WORKER_THREADS)
        {
            affinity.Mask = KAFFINITY(1) << threadId;
        }
        else
        {
            affinity.Mask = KAFFINITY(0);
        }
    }

    if (!SetThreadGroupAffinity(GetCurrentThread(), &affinity, nullptr))
    {
        SWR_INVALID("Failed to set Thread Affinity");
    }

#elif defined(__linux__) || defined(__gnu_linux__)

    cpu_set_t cpuset;
    pthread_t thread = pthread_self();
    CPU_ZERO(&cpuset);
    CPU_SET(threadId, &cpuset);

    int err = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
    if (err != 0)
    {
        fprintf(stderr, "pthread_setaffinity_np failure for tid %u: %s\n", threadId, strerror(err));
    }

#endif
}
Ejemplo n.º 3
0
// Sets the calling thread's affinity to only run on the processor specified
// in the GCThreadAffinity structure.
// Parameters:
//  affinity - The requested affinity for the calling thread. At most one processor
//             can be provided.
// Return:
//  true if setting the affinity was successful, false otherwise.
bool GCToOSInterface::SetThreadAffinity(GCThreadAffinity* affinity)
{
    LIMITED_METHOD_CONTRACT;

    assert(affinity != nullptr);
    if (affinity->Group != GCThreadAffinity::None)
    {
        assert(affinity->Processor != GCThreadAffinity::None);
        
        GROUP_AFFINITY ga;
        ga.Group = (WORD)affinity->Group;
        ga.Reserved[0] = 0; // reserve must be filled with zero
        ga.Reserved[1] = 0; // otherwise call may fail
        ga.Reserved[2] = 0;
        ga.Mask = (size_t)1 << affinity->Processor;
        return !!SetThreadGroupAffinity(GetCurrentThread(), &ga, nullptr);
    }
    else if (affinity->Processor != GCThreadAffinity::None)
    {
        return !!SetThreadAffinityMask(GetCurrentThread(), (DWORD_PTR)1 << affinity->Processor);
    }

    // Given affinity must specify at least one processor to use.
    return false;
}
Ejemplo n.º 4
0
void bindThread(SWR_CONTEXT* pContext, uint32_t threadId, uint32_t procGroupId = 0, bool bindProcGroup=false)
{
    // Only bind threads when MAX_WORKER_THREADS isn't set.
    if (pContext->threadInfo.MAX_WORKER_THREADS && bindProcGroup == false)
    {
        return;
    }

#if defined(_WIN32)

    GROUP_AFFINITY affinity = {};
    affinity.Group = procGroupId;

#if !defined(_WIN64)
    if (threadId >= 32)
    {
        // Hopefully we don't get here.  Logic in CreateThreadPool should prevent this.
        SWR_REL_ASSERT(false, "Shouldn't get here");

        // In a 32-bit process on Windows it is impossible to bind
        // to logical processors 32-63 within a processor group.
        // In this case set the mask to 0 and let the system assign
        // the processor.  Hopefully it will make smart choices.
        affinity.Mask = 0;
    }
    else
#endif
    {
        // If MAX_WORKER_THREADS is set, only bind to the proc group,
        // Not the individual HW thread.
        if (!pContext->threadInfo.MAX_WORKER_THREADS)
        {
            affinity.Mask = KAFFINITY(1) << threadId;
        }
    }

    SetThreadGroupAffinity(GetCurrentThread(), &affinity, nullptr);

#else

    cpu_set_t cpuset;
    pthread_t thread = pthread_self();
    CPU_ZERO(&cpuset);
    CPU_SET(threadId, &cpuset);

    pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);

#endif
}
Ejemplo n.º 5
0
	ThreadGroupTempAffinity(uint32 core_id)
	{
		GROUP_AFFINITY NewGroupAffinity;
		memset(&NewGroupAffinity, 0, sizeof(GROUP_AFFINITY));
		memset(&PreviousGroupAffinity, 0, sizeof(GROUP_AFFINITY));
		uint32 currentGroupSize = 0;

		while (core_id >= (currentGroupSize = GetMaximumProcessorCount(NewGroupAffinity.Group)))
		{
			core_id -= currentGroupSize;
			++NewGroupAffinity.Group;
		}
		NewGroupAffinity.Mask = 1ULL << core_id;
		SetThreadGroupAffinity(GetCurrentThread(),&NewGroupAffinity,&PreviousGroupAffinity);
	}
Ejemplo n.º 6
0
void bindThread(uint32_t threadId, uint32_t procGroupId = 0, bool bindProcGroup=false)
{
    // Only bind threads when MAX_WORKER_THREADS isn't set.
    if (KNOB_MAX_WORKER_THREADS && bindProcGroup == false)
    {
        return;
    }

#if defined(_WIN32)
    {
        GROUP_AFFINITY affinity = {};
        affinity.Group = procGroupId;

#if !defined(_WIN64)
        if (threadId >= 32)
        {
            // In a 32-bit process on Windows it is impossible to bind
            // to logical processors 32-63 within a processor group.
            // In this case set the mask to 0 and let the system assign
            // the processor.  Hopefully it will make smart choices.
            affinity.Mask = 0;
        }
        else
#endif
        {
            // If KNOB_MAX_WORKER_THREADS is set, only bind to the proc group,
            // Not the individual HW thread.
            if (!KNOB_MAX_WORKER_THREADS)
            {
                affinity.Mask = KAFFINITY(1) << threadId;
            }
        }

        SetThreadGroupAffinity(GetCurrentThread(), &affinity, nullptr);
    }
#else
    cpu_set_t cpuset;
    pthread_t thread = pthread_self();
    CPU_ZERO(&cpuset);
    CPU_SET(threadId, &cpuset);

    pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
#endif
}
Ejemplo n.º 7
0
tt_result_t __thread_bind_numa(IN HANDLE hThread, IN USHORT Node)
{
    GROUP_AFFINITY ProcessorMask;

    // how to handle the arch in which a numa node includes more than
    // 64 cpus??

    if (!GetNumaNodeProcessorMaskEx(Node, &ProcessorMask)) {
        TT_ERROR("fail to get numa node processor mask");
        return TT_FAIL;
    }

    if (!SetThreadGroupAffinity(hThread, &ProcessorMask, NULL)) {
        TT_ERROR("fail to bind thread to numa node[%d]", Node);
        return TT_FAIL;
    }

    return TT_SUCCESS;
}
Ejemplo n.º 8
0
  /*! set the affinity of a given thread */
  void setAffinity(HANDLE thread, ssize_t affinity)
  {
#if (_WIN32_WINNT >= 0x0601) // FIXME: use getProcAddress to activate this feature only if supported by Windows
    int groups = GetActiveProcessorGroupCount();
    int totalProcessors = 0, group = 0, number = 0;
    for (int i = 0; i<groups; i++) {
      int processors = GetActiveProcessorCount(i);
      if (totalProcessors + processors > affinity) {
        group = i;
        number = (int)affinity - totalProcessors;
        break;
      }
      totalProcessors += processors;
    }

    GROUP_AFFINITY groupAffinity;
    groupAffinity.Group = (WORD)group;
    groupAffinity.Mask = (KAFFINITY)(uint64(1) << number);
    groupAffinity.Reserved[0] = 0;
    groupAffinity.Reserved[1] = 0;
    groupAffinity.Reserved[2] = 0;
    if (!SetThreadGroupAffinity(thread, &groupAffinity, NULL))
      THROW_RUNTIME_ERROR("cannot set thread group affinity");

    PROCESSOR_NUMBER processorNumber;
    processorNumber.Group = group;
    processorNumber.Number = number;
    processorNumber.Reserved = 0;
    if (!SetThreadIdealProcessorEx(thread, &processorNumber, NULL))
      THROW_RUNTIME_ERROR("cannot set ideal processor");
#else
    if (!SetThreadAffinityMask(thread, DWORD_PTR(uint64(1) << affinity)))
      THROW_RUNTIME_ERROR("cannot set thread affinity mask");
    if (SetThreadIdealProcessor(thread, (DWORD)affinity) == (DWORD)-1)
      THROW_RUNTIME_ERROR("cannot set ideal processor");
#endif
  }
Ejemplo n.º 9
0
  /*! set the affinity of a given thread */
  void setAffinity(HANDLE thread, ssize_t affinity)
  {
#if (_WIN32_WINNT >= 0x0601)
    int groups = GetActiveProcessorGroupCount();
    int totalProcessors = 0, group = 0, number = 0;
    for (int i = 0; i<groups; i++) {
      int processors = GetActiveProcessorCount(i);
      if (totalProcessors + processors > affinity) {
        group = i;
        number = (int)affinity - totalProcessors;
        break;
      }
      totalProcessors += processors;
    }

    GROUP_AFFINITY groupAffinity;
    groupAffinity.Group = (WORD)group;
    groupAffinity.Mask = (KAFFINITY)(uint64(1) << number);
    groupAffinity.Reserved[0] = 0;
    groupAffinity.Reserved[1] = 0;
    groupAffinity.Reserved[2] = 0;
    if (!SetThreadGroupAffinity(thread, &groupAffinity, NULL))
      throw std::runtime_error("cannot set thread group affinity");

    PROCESSOR_NUMBER processorNumber;
    processorNumber.Group = group;
    processorNumber.Number = number;
    processorNumber.Reserved = 0;
    if (!SetThreadIdealProcessorEx(thread, &processorNumber, NULL))
      throw std::runtime_error("cannot set thread ideal processor");
#else
    if (!SetThreadAffinityMask(thread, DWORD_PTR(uint64(1) << affinity)))
      throw std::runtime_error("cannot set thread affinity mask");
    if (SetThreadIdealProcessor(thread, (DWORD)affinity) == (DWORD)-1)
      throw std::runtime_error("cannot set thread ideal processor");
#endif
  }
Ejemplo n.º 10
0
int thread_bind_native(__unused_variable struct cpuid_state_t *state, __unused_variable uint32_t id)
{
#ifdef TARGET_OS_WINDOWS

	BOOL ret;
	HANDLE hThread = GetCurrentThread();
#if _WIN32_WINNT >= 0x0601
	GROUP_AFFINITY affinity;

	ZeroMemory(&affinity, sizeof(GROUP_AFFINITY));

	affinity.Group = id / 64;
	affinity.Mask = 1 << (id % 64);

	ret = SetThreadGroupAffinity(hThread, &affinity, NULL);
#else
	DWORD mask;

	if (id > 32)
		return 1;

	mask = (1 << id);

	ret = SetThreadAffinityMask(hThread, mask);
#endif

	return (ret != FALSE) ? 0 : 1;

#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_FREEBSD)

	int ret;

#ifdef CPU_SET_S
	size_t setsize = CPU_ALLOC_SIZE(MAX_CPUS);
	CPUSET_T *set = CPU_ALLOC(MAX_CPUS);
	pthread_t pth;

	pth = pthread_self();

	CPU_ZERO_S(setsize, set);
	CPU_SET_S(id, setsize, set);
	ret = pthread_setaffinity_np(pth, setsize, set);
	CPU_FREE(set);
#else
	size_t bits_per_set = sizeof(CPUSET_T) * 8;
	size_t bits_per_subset = sizeof(CPUSET_MASK_T) * 8;
	size_t setsize = sizeof(CPUSET_T) * (MAX_CPUS / bits_per_set);
	size_t set_id, subset_id;
	unsigned long long mask;
	CPUSET_T *set = malloc(setsize);
	pthread_t pth;

	pth = pthread_self();

	for (set_id = 0; set_id < (MAX_CPUS / bits_per_set); set_id++)
		CPU_ZERO(&set[set_id]);

	set_id = id / bits_per_set;
	id %= bits_per_set;

	subset_id = id / bits_per_subset;
	id %= bits_per_subset;

	mask = 1ULL << (unsigned long long)id;

	((unsigned long *)set[set_id].__bits)[subset_id] |= mask;
	ret = pthread_setaffinity_np(pth, setsize, set);
	free(set);
#endif

	return (ret == 0) ? 0 : 1;

#elif defined(TARGET_OS_MACOSX)

#ifdef USE_CHUD
	return (utilBindThreadToCPU(id) == 0) ? 0 : 1;
#else
	return 1;
#endif

#else
#error "thread_bind_native() not defined for this platform"
#endif
}
Ejemplo n.º 11
0
	~ThreadGroupTempAffinity()
	{
		SetThreadGroupAffinity(GetCurrentThread(),&PreviousGroupAffinity,NULL);
	}