+nat
+getNumberOfProcessors (void)
+{
+ static nat nproc = 0;
+
+ if (nproc == 0) {
+#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
+ nproc = sysconf(_SC_NPROCESSORS_ONLN);
+#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
+ nproc = sysconf(_SC_NPROCESSORS_CONF);
+#elif defined(darwin_HOST_OS)
+ size_t size = sizeof(nat);
+ if(0 != sysctlbyname("hw.ncpu",&nproc,&size,NULL,0))
+ nproc = 1;
+#else
+ nproc = 1;
+#endif
+ }
+
+ return nproc;
+}
+
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY)
+// Schedules the thread to run on CPU n of m. m may be less than the
+// number of physical CPUs, in which case, the thread will be allowed
+// to run on CPU n, n+m, n+2m etc.
+void
+setThreadAffinity (nat n, nat m)
+{
+ nat nproc;
+ cpu_set_t cs;
+ nat i;
+
+ nproc = getNumberOfProcessors();
+ CPU_ZERO(&cs);
+ for (i = n; i < nproc; i+=m) {
+ CPU_SET(i, &cs);
+ }
+ sched_setaffinity(0, sizeof(cpu_set_t), &cs);
+}
+
+#elif defined(darwin_HOST_OS) && defined(THREAD_AFFINITY_POLICY)
+// Schedules the current thread in the affinity set identified by tag n.
+void
+setThreadAffinity (nat n, nat m GNUC3_ATTRIBUTE(__unused__))
+{
+ thread_affinity_policy_data_t policy;
+
+ policy.affinity_tag = n;
+ thread_policy_set(mach_thread_self(),
+ THREAD_AFFINITY_POLICY,
+ (thread_policy_t) &policy,
+ THREAD_AFFINITY_POLICY_COUNT);
+}
+
+#else
+void
+setThreadAffinity (nat n GNUC3_ATTRIBUTE(__unused__),
+ nat m GNUC3_ATTRIBUTE(__unused__))
+{
+}
+#endif
+