*
* --------------------------------------------------------------------------*/
-#if defined(DEBUG) && defined(__linux__)
+#if defined(__linux__)
/* We want GNU extensions in DEBUG mode for mutex error checking */
+/* We also want the affinity API, which requires _GNU_SOURCE */
#define _GNU_SOURCE
#endif
#error pthreads.h is required for the threaded RTS on Posix platforms
#endif
+#if defined(HAVE_SCHED_H)
+#include <sched.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
/*
* This (allegedly) OS threads independent layer was initially
* abstracted away from code that used Pthreads, so the functions
#if defined(DEBUG)
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
-#if defined(linux_HOST_OS)
- pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK_NP);
-#else
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK);
-#endif
pthread_mutex_init(pMut,&attr);
#else
pthread_mutex_init(pMut,NULL);
return result;
}
+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);
+#else
+ nproc = 1;
+#endif
+ }
+
+ return nproc;
+}
+
+// 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)
+{
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY)
+ nat nproc;
+ cpu_set_t cs;
+ nat i;
+
+ nproc = getNumberOfProcessors();
+ CPU_ZERO(&cs);
+ for (i = n; i < nproc; i+=m) {
+ CPU_SET(n, &cs);
+ }
+ sched_setaffinity(0, sizeof(cpu_set_t), &cs);
+#endif
+}
+
#else /* !defined(THREADED_RTS) */
int