Beispiel #1
0
void CPUID::Go()
{
    CoreAssert(this != NULL);
#ifdef TARGET_OS_WINDOWS
    DWORD dThread = NULL;
    SYSTEM_INFO siSystem;
    int iCount = 0;
    struct GoThreadProc_Params params;

    params.cpuid_class = this;
    GetSystemInfo(&siSystem);

    iCount = siSystem.dwNumberOfProcessors;

    if (iCount > MAX_PROCESSORS) {
        iCount = MAX_PROCESSORS;
    }

    for (params.processor = 0; params.processor < iCount;
            params.processor++) {
        HANDLE hThread =
            CreateThread(NULL, 0, ( LPTHREAD_START_ROUTINE )s_GoThreadProc,
                         &params, CREATE_SUSPENDED, &dThread);
        SetThreadAffinityMask(hThread,
                              ( DWORD )pow(( double )2,
                                           ( double )params.
                                           processor));
        Sleep(0);                    /* Wait for affinity switch. */
        SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
        ResumeThread(hThread);
        WaitForSingleObject(hThread, INFINITE);
    }

#elif defined (TARGET_OS_LINUX)
    int NUM_PROCS = sysconf(_SC_NPROCESSORS_CONF), i;
    cpu_set_t mask;
    cpu_set_t originalmask;

    sched_getaffinity(0, sizeof(originalmask), &originalmask);
    for (i = 0; i < NUM_PROCS; i++) {
        CPU_ZERO(&mask);
        CPU_SET(( int )pow(2, i), &mask);
        sched_setaffinity(0, sizeof(mask), &mask);
        GoThread(i);
    }

    sched_setaffinity(0, sizeof(originalmask), &originalmask);
#elif defined (TARGET_OS_MACOSX)
    int NUM_PROCS = chudProcessorCount();
    for (int i = 0; i < NUM_PROCS; i++) {
        utilUnbindThreadFromCPU();
        utilBindThreadToCPU(i);
        GoThread(i);
    }
    utilUnbindThreadFromCPU();
#endif
}
Beispiel #2
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
}
Beispiel #3
0
int thread_bind_native(__unused_variable struct cpuid_state_t *state, uint32_t id)
{
#ifdef TARGET_OS_WINDOWS

	BOOL ret = FALSE;
	HANDLE hThread = GetCurrentThread();

#if _WIN32_WINNT < 0x0601
	if (is_windows7_or_greater()) {
#endif
		DWORD threadsInGroup = 0;
		WORD groupId, groupCount;
		GROUP_AFFINITY affinity;
		ZeroMemory(&affinity, sizeof(GROUP_AFFINITY));

		groupCount = GetActiveProcessorGroupCount();

		for (groupId = 0; groupId < groupCount; groupId++) {
			threadsInGroup = GetActiveProcessorCount(groupId);
			if (id < threadsInGroup)
				break;
			id -= threadsInGroup;
		}

		if (groupId < groupCount && id < threadsInGroup) {
			affinity.Group = groupId;
			affinity.Mask = 1ULL << id;

			ret = SetThreadGroupAffinity(hThread, &affinity, NULL);
		}
#if _WIN32_WINNT < 0x0601
	} else {
		DWORD mask;

		if (id > 32)
			return 1;

		mask = (1 << id);

		ret = SetThreadAffinityMask(hThread, mask);
	}
#endif

	if (state && ret != FALSE)
		state->cpu_bound_index = id;

	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

	if (state && ret == 0)
		state->cpu_bound_index = id;

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

#elif defined(TARGET_OS_SOLARIS)

	/*
	 * This requires permissions, so can easily fail.
	 */
	if (processor_bind(P_LWPID, P_MYID, id, NULL) != 0) {
		fprintf(stderr, "warning: failed to bind to CPU%u: %s\n",
			id, strerror(errno));
		return 1;
	}

	if (state)
		state->cpu_bound_index = id;
	return 0;
#elif defined(TARGET_OS_MACOSX)
	int ret = 1;

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

	if (state && ret == 0)
		state->cpu_bound_index = id;

	return ret == 0 ? 0 : 1;
#else
#error "thread_bind_native() not defined for this platform"
#endif
}