aboutsummaryrefslogtreecommitdiffstats
path: root/lang
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2015-04-27 12:08:01 +0800
committeradrian <adrian@FreeBSD.org>2015-04-27 12:08:01 +0800
commit3b27bd8f5e8255b609c0398a025a19a4ec105b6f (patch)
tree5d424d635c28623c343d98368803b8ffed5097bd /lang
parent3ec358471783aaf8b78cb8d12442ae127398ef9d (diff)
downloadfreebsd-ports-gnome-3b27bd8f5e8255b609c0398a025a19a4ec105b6f.tar.gz
freebsd-ports-gnome-3b27bd8f5e8255b609c0398a025a19a4ec105b6f.tar.zst
freebsd-ports-gnome-3b27bd8f5e8255b609c0398a025a19a4ec105b6f.zip
Implement the FreeBSD specific pieces for thread affinity for OpenMP.
Upstream gcc 4.8 doesn't have support for this - it'll create threads, but it won't do any of the thread affinity stuff for FreeBSD. This allows for OMP_PROC_BIND=true to bind threads to their initial CPUs, leading to some pretty drastic improvements in performance for certain NUMA workloads. Approved by: gerald
Diffstat (limited to 'lang')
-rw-r--r--lang/gcc/Makefile2
-rw-r--r--lang/gcc/files/patch-libgomp-freebsd-affinity117
-rw-r--r--lang/gcc/files/patch-libgomp-posix-affinity18
3 files changed, 136 insertions, 1 deletions
diff --git a/lang/gcc/Makefile b/lang/gcc/Makefile
index 7010f76b5f05..ee6791899bf5 100644
--- a/lang/gcc/Makefile
+++ b/lang/gcc/Makefile
@@ -3,7 +3,7 @@
PORTNAME= gcc
PORTVERSION= 4.8.4
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= lang java
MASTER_SITES= ${MASTER_SITE_GCC}
MASTER_SITE_SUBDIR= releases/gcc-${DISTVERSION}
diff --git a/lang/gcc/files/patch-libgomp-freebsd-affinity b/lang/gcc/files/patch-libgomp-freebsd-affinity
new file mode 100644
index 000000000000..7b35399a66a2
--- /dev/null
+++ b/lang/gcc/files/patch-libgomp-freebsd-affinity
@@ -0,0 +1,117 @@
+--- libgomp/config/bsd/freebsd_affinity.c.orig 2015-04-26 05:29:16.795040000 -0700
++++ libgomp/config/bsd/freebsd_affinity.c 2015-04-26 05:29:03.462728000 -0700
+@@ -0,0 +1,114 @@
++/* Copyright (C) 2015 Free Software Foundation, Inc.
++ Contributed by Adrian Chadd <adrian@FreeBSD.org>.
++ Based on work by Jakub Jelinek <jakub@redhat.com>.
++
++ This file is part of the GNU OpenMP Library (libgomp).
++
++ Libgomp is free software; you can redistribute it and/or modify it
++ under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 3, or (at your option)
++ any later version.
++
++ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
++ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ more details.
++
++ Under Section 7 of GPL version 3, you are granted additional
++ permissions described in the GCC Runtime Library Exception, version
++ 3.1, as published by the Free Software Foundation.
++
++ You should have received a copy of the GNU General Public License and
++ a copy of the GCC Runtime Library Exception along with this program;
++ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
++ <http://www.gnu.org/licenses/>. */
++
++/* This is a FreeBSD specific implementation of a CPU affinity setting. */
++
++#include "libgomp.h"
++
++#include <stdlib.h>
++#include <unistd.h>
++#include <pthread.h>
++#include <pthread_np.h>
++
++static unsigned int affinity_counter;
++
++void
++gomp_init_affinity (void)
++{
++ cpuset_t cpuset, cpusetnew;
++ size_t idx, widx;
++ unsigned long cpus = 0;
++
++ if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset))
++ {
++ gomp_error ("could not get CPU affinity set");
++ free (gomp_cpu_affinity);
++ gomp_cpu_affinity = NULL;
++ gomp_cpu_affinity_len = 0;
++ return;
++ }
++
++ CPU_ZERO (&cpusetnew);
++ if (gomp_cpu_affinity_len == 0)
++ {
++ unsigned long count = CPU_COUNT(&cpuset);
++ if (count >= 65536)
++ count = 65536;
++ gomp_cpu_affinity = malloc (count * sizeof (unsigned short));
++ if (gomp_cpu_affinity == NULL)
++ {
++ gomp_error ("not enough memory to store CPU affinity list");
++ return;
++ }
++ for (widx = idx = 0; widx < count && idx < 65536; idx++)
++ if (CPU_ISSET (idx, &cpuset))
++ {
++ cpus++;
++ gomp_cpu_affinity[widx++] = idx;
++ }
++ }
++ else
++ for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++)
++ if (gomp_cpu_affinity[idx] < CPU_SETSIZE
++ && CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
++ {
++ if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpusetnew))
++ {
++ cpus++;
++ CPU_SET (gomp_cpu_affinity[idx], &cpusetnew);
++ }
++ gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx];
++ }
++
++ if (widx == 0)
++ {
++ gomp_error ("no CPUs left for affinity setting");
++ free (gomp_cpu_affinity);
++ gomp_cpu_affinity = NULL;
++ gomp_cpu_affinity_len = 0;
++ return;
++ }
++
++ gomp_cpu_affinity_len = widx;
++ if (cpus < gomp_available_cpus)
++ gomp_available_cpus = cpus;
++ CPU_ZERO (&cpuset);
++ CPU_SET (gomp_cpu_affinity[0], &cpuset);
++ pthread_setaffinity_np (pthread_self (), sizeof (cpuset), &cpuset);
++ affinity_counter = 1;
++}
++
++void
++gomp_init_thread_affinity (pthread_attr_t *attr)
++{
++ unsigned int cpu;
++ cpuset_t cpuset;
++
++ cpu = __atomic_fetch_add (&affinity_counter, 1, MEMMODEL_RELAXED);
++ cpu %= gomp_cpu_affinity_len;
++ CPU_ZERO (&cpuset);
++ CPU_SET (gomp_cpu_affinity[cpu], &cpuset);
++ pthread_attr_setaffinity_np (attr, sizeof (cpuset_t), &cpuset);
++}
diff --git a/lang/gcc/files/patch-libgomp-posix-affinity b/lang/gcc/files/patch-libgomp-posix-affinity
new file mode 100644
index 000000000000..c4ab742f061b
--- /dev/null
+++ b/lang/gcc/files/patch-libgomp-posix-affinity
@@ -0,0 +1,18 @@
+--- libgomp/config/posix/affinity.c.orig 2015-04-26 05:29:27.925344000 -0700
++++ libgomp/config/posix/affinity.c 2015-04-26 05:29:44.449277000 -0700
+@@ -26,6 +26,10 @@
+
+ #include "libgomp.h"
+
++#ifdef __FreeBSD__
++#include "../bsd/freebsd_affinity.c"
++#else
++
+ void
+ gomp_init_affinity (void)
+ {
+@@ -36,3 +40,4 @@
+ {
+ (void) attr;
+ }
++#endif