#define _GNU_SOURCE #include "pixie-threads.h" #if defined(WIN32) #include #include #endif #if defined(__GNUC__) && !defined(WIN32) #include #include #include #include #endif #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #include #endif #ifndef UNUSEDPARM #ifdef _MSC_VER #define UNUSEDPARM(x) x #else #define UNUSEDPARM(x) #endif #endif /**************************************************************************** ****************************************************************************/ void pixie_cpu_raise_priority(void) { #if defined WIN32 DWORD_PTR result; result = SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); if (result == 0) { fprintf(stderr, "set_priority: returned error win32:%u\n", (unsigned)GetLastError()); } #elif defined(__linux__) && defined(__GNUC__) pthread_t thread = pthread_self(); pthread_attr_t thAttr; int policy = 0; int max_prio_for_policy = 0; pthread_attr_init(&thAttr); pthread_attr_getschedpolicy(&thAttr, &policy); max_prio_for_policy = sched_get_priority_max(policy); pthread_setschedprio(thread, max_prio_for_policy); pthread_attr_destroy(&thAttr); return; #endif } /**************************************************************************** * Set the current thread (implicit) to run exclusively on the explicit * process. * http://en.wikipedia.org/wiki/Processor_affinity ****************************************************************************/ void pixie_cpu_set_affinity(unsigned processor) { #if defined WIN32 DWORD_PTR mask; DWORD_PTR result; if (processor > 0) processor--; mask = ((size_t)1)<>= 1; } if (count == 0) return 1; else return count; #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* BSD - use sysctl() function */ int x; int mib[2]; size_t ncpu_length; int ncpu = 1; mib[0] = CTL_HW; mib[1] = HW_NCPU; ncpu_length = sizeof(ncpu); x = sysctl(mib, 2, &ncpu, &ncpu_length, NULL, 0); if (x == -1) { perror("sysctl(HW_NCPU) failed"); return 1; } else return (unsigned)ncpu; #elif defined linux /* http://linux.die.net/man/2/sched_getaffinity */ { pid_t pid; cpu_set_t mask; int err; /* Gegret our process ID */ pid = getpid(); /* Get list of available CPUs for our system */ err = sched_getaffinity(pid, sizeof(mask), &mask); if (err) { perror("sched_getaffinity"); return 1; } else { #ifndef CPU_COUNT return 1; #else return CPU_COUNT(&mask); #endif } } #elif defined(_SC_NPROCESSORS_ONLN) /* Linux, Solaris, Mac OS>=10.4 */ return sysconf(_SC_NPROCESSORS_ONLN); #elif defined(_SC_NPROC_ONLN) /* Irix */ return sysconf(_SC_NPROC_ONLN); #elif defined(MPC_GETNUMSPUS) return mpctl(MPC_GETNUMSPUS, 0, 0); #else #error need to find CPU count /* UNKNOWN - Well, we don't know the type of system which means we won't * be able to start multiple threads anyway, so just return '1' */ return 1; #endif } /**************************************************************************** ****************************************************************************/ size_t pixie_begin_thread( void (*worker_thread)(void*), unsigned flags, void *worker_data) { #if defined(WIN32) UNUSEDPARM(flags); return _beginthread(worker_thread, 0, worker_data); #else typedef void *(*PTHREADFUNC)(void*); pthread_t thread_id = 0; pthread_create( &thread_id, NULL, (PTHREADFUNC)worker_thread, worker_data); return (size_t)thread_id; #endif } /**************************************************************************** ****************************************************************************/ void pixie_thread_join(size_t thread_handle) { #if defined(WIN32) WaitForSingleObject((HANDLE)thread_handle, INFINITE); #else void *p; pthread_join((pthread_t)thread_handle, &p); #endif }