From 13346da217137e4efb6cf14657960c75a23251ad Mon Sep 17 00:00:00 2001
From: Gabor Pali <pgj@FreeBSD.org>
Date: Tue, 20 Jul 2010 00:14:09 +0000
Subject: Add thread affinity support for FreeBSD - Implement missing functions
 for setting thread affinity and getting real   number of processors. - It is
 available starting from 7.1-RELEASE, which includes a native support   for
 managing CPU sets. - Add __BSD_VISIBLE, since it is required for certain
 types to be visible in   addition to POSIX & C99.

---
 configure.ac          |  2 +-
 rts/posix/OSThreads.c | 33 +++++++++++++++++++++++++++++++--
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2be74e64e9..f277367289 100644
--- a/configure.ac
+++ b/configure.ac
@@ -668,7 +668,7 @@ dnl    off_t, because it will affect the result of that test.
 AC_SYS_LARGEFILE
 
 dnl ** check for specific header (.h) files that we are interested in
-AC_CHECK_HEADERS([bfd.h ctype.h dirent.h dlfcn.h errno.h fcntl.h grp.h limits.h locale.h nlist.h pthread.h pwd.h signal.h sys/mman.h sys/resource.h sys/select.h sys/time.h sys/timeb.h sys/timers.h sys/times.h sys/utsname.h sys/wait.h termios.h time.h utime.h windows.h winsock.h sched.h])
+AC_CHECK_HEADERS([bfd.h ctype.h dirent.h dlfcn.h errno.h fcntl.h grp.h limits.h locale.h nlist.h pthread.h pwd.h signal.h sys/cpuset.h sys/mman.h sys/resource.h sys/select.h sys/time.h sys/timeb.h sys/timers.h sys/times.h sys/utsname.h sys/wait.h termios.h time.h utime.h windows.h winsock.h sched.h])
 
 dnl ** check if it is safe to include both <time.h> and <sys/time.h>
 AC_HEADER_TIME
diff --git a/rts/posix/OSThreads.c b/rts/posix/OSThreads.c
index a813eebf9e..343536e063 100644
--- a/rts/posix/OSThreads.c
+++ b/rts/posix/OSThreads.c
@@ -14,6 +14,13 @@
 #endif
 
 #include "PosixSource.h"
+
+#if defined(freebsd_HOST_OS)
+/* Inclusion of system headers usually requires __BSD_VISIBLE on FreeBSD,
+ * because of some specific types, like u_char, u_int, etc. */
+#define __BSD_VISIBLE	1
+#endif
+
 #include "Rts.h"
 
 #if defined(THREADED_RTS)
@@ -24,7 +31,7 @@
 #include <string.h>
 #endif
 
-#if defined(darwin_HOST_OS)
+#if defined(darwin_HOST_OS) || defined(freebsd_HOST_OS)
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #endif
@@ -37,6 +44,11 @@
 #include <sched.h>
 #endif
 
+#if defined(HAVE_SYS_CPUSET_H)
+#include <sys/param.h>
+#include <sys/cpuset.h>
+#endif
+
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -208,7 +220,7 @@ getNumberOfProcessors (void)
         nproc = sysconf(_SC_NPROCESSORS_ONLN);
 #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
         nproc = sysconf(_SC_NPROCESSORS_CONF);
-#elif defined(darwin_HOST_OS)
+#elif defined(darwin_HOST_OS) || defined(freebsd_HOST_OS)
         size_t size = sizeof(nat);
         if(0 != sysctlbyname("hw.ncpu",&nproc,&size,NULL,0))
             nproc = 1;
@@ -253,6 +265,23 @@ setThreadAffinity (nat n, nat m GNUC3_ATTRIBUTE(__unused__))
 		      THREAD_AFFINITY_POLICY_COUNT);
 }
 
+#elif defined(HAVE_SYS_CPUSET_H) /* FreeBSD 7.1+ */
+void
+setThreadAffinity(nat n, nat m)
+{
+	nat nproc;
+	cpuset_t cs;
+	nat i;
+
+	nproc = getNumberOfProcessors();
+	CPU_ZERO(&cs);
+
+	for (i = n; i < nproc; i += m)
+		CPU_SET(i, &cs);
+
+	cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), &cs);
+}
+
 #else
 void
 setThreadAffinity (nat n GNUC3_ATTRIBUTE(__unused__), 
-- 
cgit v1.2.1