DLLEXPORT int jl_cpu_cores(void) { #if defined(__APPLE__) size_t len = 4; int32_t count; int nm[2] = {CTL_HW, HW_AVAILCPU}; sysctl(nm, 2, &count, &len, NULL, 0); if (count < 1) { nm[1] = HW_NCPU; sysctl(nm, 2, &count, &len, NULL, 0); if (count < 1) { count = 1; } } return count; #elif defined(__linux) return sysconf(_SC_NPROCESSORS_ONLN); #else // test for Windows? return GetActiveProcessorCount(__in WORD GroupNumber); #endif }
/*! 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 }
/*! 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 }
mlt_slices mlt_slices_init( int threads, int policy, int priority ) { pthread_attr_t tattr; struct sched_param param; mlt_slices ctx = (mlt_slices)calloc( 1, sizeof( struct mlt_slices_s ) ); char *env = getenv( ENV_SLICES ); #ifdef _WIN32 #if _WIN32_WINNT >= 0x0601 int cpus = GetActiveProcessorCount( ALL_PROCESSOR_GROUPS ); #else SYSTEM_INFO info; GetSystemInfo(&info); int cpus = info.dwNumberOfProcessors; #endif #else int cpus = sysconf( _SC_NPROCESSORS_ONLN ); #endif int i, env_val = env ? atoi(env) : 0; /* check given threads count */ if ( !env || !env_val ) { if ( threads < 0 ) threads = -threads * cpus; else if ( !threads ) threads = cpus; } else if ( env_val < 0 ) { if ( threads < 0 ) threads = env_val * threads * cpus; else if ( !threads ) threads = -env_val * cpus; else threads = -env_val * threads; } else // env_val > 0 { if ( threads < 0 ) threads = env_val * threads; else if ( !threads ) threads = env_val; } if ( threads > MAX_SLICES ) threads = MAX_SLICES; ctx->count = threads; /* init attributes */ pthread_mutex_init ( &ctx->cond_mutex, NULL ); pthread_cond_init ( &ctx->cond_var_job, NULL ); pthread_cond_init ( &ctx->cond_var_ready, NULL ); pthread_attr_init( &tattr ); if ( policy < 0 ) policy = SCHED_OTHER; if ( priority < 0 ) priority = sched_get_priority_max( policy ); pthread_attr_setschedpolicy( &tattr, policy ); param.sched_priority = priority; pthread_attr_setschedparam( &tattr, ¶m ); /* run worker threads */ for ( i = 0; i < ctx->count; i++ ) { pthread_create( &ctx->threads[i], &tattr, mlt_slices_worker, ctx ); pthread_setschedparam( ctx->threads[i], policy, ¶m); } pthread_attr_destroy( &tattr ); /* return context */ return ctx; }