libgomp: bring early CPU affinity support from FSF GCC-4_3 branch.
This is not likely to make it into a release and is basically disabled but should still be useful for testing. Obtained from: GCC pre-4.3 (rev. 123494, 125542; LGPLv2.1+)
This commit is contained in:
parent
3f6cf39fb2
commit
70364ab4ff
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=282115
23
contrib/gcclibs/libgomp/ChangeLog.gcc43
Normal file
23
contrib/gcclibs/libgomp/ChangeLog.gcc43
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
2007-06-07 Jakub Jelinek <jakub@redhat.com> (r125542)
|
||||||
|
|
||||||
|
* team.c (gomp_team_start): Fix setting up thread_attr
|
||||||
|
stack size.
|
||||||
|
|
||||||
|
2007-04-04 Jakub Jelinek <jakub@redhat.com> (r123494)
|
||||||
|
|
||||||
|
* libgomp.h (gomp_cpu_affinity, gomp_cpu_affinity_len): New extern
|
||||||
|
decls.
|
||||||
|
(gomp_init_affinity, gomp_init_thread_affinity): New prototypes.
|
||||||
|
* env.c (gomp_cpu_affinity, gomp_cpu_affinity_len): New variables.
|
||||||
|
(parse_affinity): New function.
|
||||||
|
(initialize_env): Call it and gomp_init_affinity.
|
||||||
|
* team.c (gomp_team_start): If gomp_cpu_affinity != NULL,
|
||||||
|
create new pthread_attr_t and call gomp_init_thread_affinity
|
||||||
|
on it for each thread before passing the attribute to pthread_create.
|
||||||
|
* config/linux/affinity.c: New file.
|
||||||
|
* config/posix/affinity.c: New file.
|
||||||
|
* configure.ac (HAVE_PTHREAD_AFFINITY_NP): New test.
|
||||||
|
* configure: Rebuilt.
|
||||||
|
* config.h.in: Rebuilt.
|
||||||
|
* Makefile.am (libgomp_la_SOURCES): Add affinity.c.
|
||||||
|
* Makefile.in: Rebuilt.
|
@ -33,7 +33,7 @@ libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script)
|
|||||||
|
|
||||||
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
|
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
|
||||||
loop.c ordered.c parallel.c sections.c single.c team.c work.c \
|
loop.c ordered.c parallel.c sections.c single.c team.c work.c \
|
||||||
lock.c mutex.c proc.c sem.c bar.c time.c fortran.c
|
lock.c mutex.c proc.c sem.c bar.c time.c fortran.c affinity.c
|
||||||
|
|
||||||
nodist_noinst_HEADERS = libgomp_f.h
|
nodist_noinst_HEADERS = libgomp_f.h
|
||||||
nodist_libsubinclude_HEADERS = omp.h
|
nodist_libsubinclude_HEADERS = omp.h
|
||||||
|
@ -79,7 +79,7 @@ libgomp_la_LIBADD =
|
|||||||
am_libgomp_la_OBJECTS = alloc.lo barrier.lo critical.lo env.lo \
|
am_libgomp_la_OBJECTS = alloc.lo barrier.lo critical.lo env.lo \
|
||||||
error.lo iter.lo loop.lo ordered.lo parallel.lo sections.lo \
|
error.lo iter.lo loop.lo ordered.lo parallel.lo sections.lo \
|
||||||
single.lo team.lo work.lo lock.lo mutex.lo proc.lo sem.lo \
|
single.lo team.lo work.lo lock.lo mutex.lo proc.lo sem.lo \
|
||||||
bar.lo time.lo fortran.lo
|
bar.lo time.lo fortran.lo affinity.lo
|
||||||
libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
|
libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
|
||||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
|
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
|
||||||
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
||||||
@ -279,7 +279,7 @@ libgomp_version_info = -version-info $(libtool_VERSION)
|
|||||||
libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script)
|
libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script)
|
||||||
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
|
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
|
||||||
loop.c ordered.c parallel.c sections.c single.c team.c work.c \
|
loop.c ordered.c parallel.c sections.c single.c team.c work.c \
|
||||||
lock.c mutex.c proc.c sem.c bar.c time.c fortran.c
|
lock.c mutex.c proc.c sem.c bar.c time.c fortran.c affinity.c
|
||||||
|
|
||||||
nodist_noinst_HEADERS = libgomp_f.h
|
nodist_noinst_HEADERS = libgomp_f.h
|
||||||
nodist_libsubinclude_HEADERS = omp.h
|
nodist_libsubinclude_HEADERS = omp.h
|
||||||
@ -406,6 +406,7 @@ mostlyclean-compile:
|
|||||||
distclean-compile:
|
distclean-compile:
|
||||||
-rm -f *.tab.c
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affinity.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bar.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bar.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/barrier.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/barrier.Plo@am__quote@
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
/* Define to 1 if you have the <memory.h> header file. */
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
#undef HAVE_MEMORY_H
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define if pthread_{,attr_}{g,s}etaffinity_np is supported. */
|
||||||
|
#undef HAVE_PTHREAD_AFFINITY_NP
|
||||||
|
|
||||||
/* Define to 1 if you have the <semaphore.h> header file. */
|
/* Define to 1 if you have the <semaphore.h> header file. */
|
||||||
#undef HAVE_SEMAPHORE_H
|
#undef HAVE_SEMAPHORE_H
|
||||||
|
|
||||||
|
107
contrib/gcclibs/libgomp/config/linux/affinity.c
Normal file
107
contrib/gcclibs/libgomp/config/linux/affinity.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||||
|
Contributed 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 Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, 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 Lesser General Public License for
|
||||||
|
more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with libgomp; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* As a special exception, if you link this library with other files, some
|
||||||
|
of which are compiled with GCC, to produce an executable, this library
|
||||||
|
does not by itself cause the resulting executable to be covered by the
|
||||||
|
GNU General Public License. This exception does not however invalidate
|
||||||
|
any other reasons why the executable file might be covered by the GNU
|
||||||
|
General Public License. */
|
||||||
|
|
||||||
|
/* This is a Linux specific implementation of a CPU affinity setting. */
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE 1
|
||||||
|
#endif
|
||||||
|
#include "libgomp.h"
|
||||||
|
#include <sched.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_PTHREAD_AFFINITY_NP
|
||||||
|
|
||||||
|
static unsigned int affinity_counter;
|
||||||
|
#ifndef HAVE_SYNC_BUILTINS
|
||||||
|
static gomp_mutex_t affinity_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
gomp_init_affinity (void)
|
||||||
|
{
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
size_t idx, widx;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++)
|
||||||
|
if (gomp_cpu_affinity[idx] < CPU_SETSIZE
|
||||||
|
&& CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
|
||||||
|
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;
|
||||||
|
CPU_ZERO (&cpuset);
|
||||||
|
CPU_SET (gomp_cpu_affinity[0], &cpuset);
|
||||||
|
pthread_setaffinity_np (pthread_self (), sizeof (cpuset), &cpuset);
|
||||||
|
affinity_counter = 1;
|
||||||
|
#ifndef HAVE_SYNC_BUILTINS
|
||||||
|
gomp_mutex_init (&affinity_lock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gomp_init_thread_affinity (pthread_attr_t *attr)
|
||||||
|
{
|
||||||
|
unsigned int cpu;
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
|
||||||
|
#ifdef HAVE_SYNC_BUILTINS
|
||||||
|
cpu = __sync_fetch_and_add (&affinity_counter, 1);
|
||||||
|
#else
|
||||||
|
gomp_mutex_lock (&affinity_lock);
|
||||||
|
cpu = affinity_counter++;
|
||||||
|
gomp_mutex_unlock (&affinity_lock);
|
||||||
|
#endif
|
||||||
|
cpu %= gomp_cpu_affinity_len;
|
||||||
|
CPU_ZERO (&cpuset);
|
||||||
|
CPU_SET (gomp_cpu_affinity[cpu], &cpuset);
|
||||||
|
pthread_attr_setaffinity_np (attr, sizeof (cpu_set_t), &cpuset);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "../posix/affinity.c"
|
||||||
|
|
||||||
|
#endif
|
41
contrib/gcclibs/libgomp/config/posix/affinity.c
Normal file
41
contrib/gcclibs/libgomp/config/posix/affinity.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||||
|
Contributed 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 Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, 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 Lesser General Public License for
|
||||||
|
more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with libgomp; see the file COPYING.LIB. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* As a special exception, if you link this library with other files, some
|
||||||
|
of which are compiled with GCC, to produce an executable, this library
|
||||||
|
does not by itself cause the resulting executable to be covered by the
|
||||||
|
GNU General Public License. This exception does not however invalidate
|
||||||
|
any other reasons why the executable file might be covered by the GNU
|
||||||
|
General Public License. */
|
||||||
|
|
||||||
|
/* This is a generic stub implementation of a CPU affinity setting. */
|
||||||
|
|
||||||
|
#include "libgomp.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
gomp_init_affinity (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gomp_init_thread_affinity (pthread_attr_t *attr)
|
||||||
|
{
|
||||||
|
(void) attr;
|
||||||
|
}
|
62
contrib/gcclibs/libgomp/configure
vendored
62
contrib/gcclibs/libgomp/configure
vendored
@ -8851,6 +8851,68 @@ rm -f conftest.err conftest.$ac_objext \
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Check for pthread_{,attr_}[sg]etaffinity_np.
|
||||||
|
cat >conftest.$ac_ext <<_ACEOF
|
||||||
|
/* confdefs.h. */
|
||||||
|
_ACEOF
|
||||||
|
cat confdefs.h >>conftest.$ac_ext
|
||||||
|
cat >>conftest.$ac_ext <<_ACEOF
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <pthread.h>
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_getaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
|
||||||
|
if (CPU_ISSET (0, &cpuset))
|
||||||
|
CPU_SET (1, &cpuset);
|
||||||
|
else
|
||||||
|
CPU_ZERO (&cpuset);
|
||||||
|
pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
|
||||||
|
pthread_attr_init (&attr);
|
||||||
|
pthread_attr_getaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);
|
||||||
|
pthread_attr_setaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||||
|
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||||
|
(eval $ac_link) 2>conftest.er1
|
||||||
|
ac_status=$?
|
||||||
|
grep -v '^ *+' conftest.er1 >conftest.err
|
||||||
|
rm -f conftest.er1
|
||||||
|
cat conftest.err >&5
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); } &&
|
||||||
|
{ ac_try='test -z "$ac_c_werror_flag"
|
||||||
|
|| test ! -s conftest.err'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; } &&
|
||||||
|
{ ac_try='test -s conftest$ac_exeext'
|
||||||
|
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||||
|
(eval $ac_try) 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||||
|
(exit $ac_status); }; }; then
|
||||||
|
|
||||||
|
cat >>confdefs.h <<\_ACEOF
|
||||||
|
#define HAVE_PTHREAD_AFFINITY_NP 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "$as_me: failed program was:" >&5
|
||||||
|
sed 's/^/| /' conftest.$ac_ext >&5
|
||||||
|
|
||||||
|
fi
|
||||||
|
rm -f conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
|
||||||
# At least for glibc, clock_gettime is in librt. But don't pull that
|
# At least for glibc, clock_gettime is in librt. But don't pull that
|
||||||
# in if it still doesn't give us the function we want.
|
# in if it still doesn't give us the function we want.
|
||||||
if test $ac_cv_func_clock_gettime = no; then
|
if test $ac_cv_func_clock_gettime = no; then
|
||||||
|
@ -237,6 +237,25 @@ If so, please configure with --disable-linux-futex])
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Check for pthread_{,attr_}[sg]etaffinity_np.
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[#define _GNU_SOURCE
|
||||||
|
#include <pthread.h>],
|
||||||
|
[cpu_set_t cpuset;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_getaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
|
||||||
|
if (CPU_ISSET (0, &cpuset))
|
||||||
|
CPU_SET (1, &cpuset);
|
||||||
|
else
|
||||||
|
CPU_ZERO (&cpuset);
|
||||||
|
pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
|
||||||
|
pthread_attr_init (&attr);
|
||||||
|
pthread_attr_getaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);
|
||||||
|
pthread_attr_setaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);])],
|
||||||
|
AC_DEFINE(HAVE_PTHREAD_AFFINITY_NP, 1,
|
||||||
|
[ Define if pthread_{,attr_}{g,s}etaffinity_np is supported.]))
|
||||||
|
|
||||||
# At least for glibc, clock_gettime is in librt. But don't pull that
|
# At least for glibc, clock_gettime is in librt. But don't pull that
|
||||||
# in if it still doesn't give us the function we want.
|
# in if it still doesn't give us the function we want.
|
||||||
if test $ac_cv_func_clock_gettime = no; then
|
if test $ac_cv_func_clock_gettime = no; then
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
|
/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||||
Contributed by Richard Henderson <rth@redhat.com>.
|
Contributed by Richard Henderson <rth@redhat.com>.
|
||||||
|
|
||||||
This file is part of the GNU OpenMP Library (libgomp).
|
This file is part of the GNU OpenMP Library (libgomp).
|
||||||
@ -42,6 +42,8 @@ bool gomp_dyn_var = false;
|
|||||||
bool gomp_nest_var = false;
|
bool gomp_nest_var = false;
|
||||||
enum gomp_schedule_type gomp_run_sched_var = GFS_DYNAMIC;
|
enum gomp_schedule_type gomp_run_sched_var = GFS_DYNAMIC;
|
||||||
unsigned long gomp_run_sched_chunk = 1;
|
unsigned long gomp_run_sched_chunk = 1;
|
||||||
|
unsigned short *gomp_cpu_affinity;
|
||||||
|
size_t gomp_cpu_affinity_len;
|
||||||
|
|
||||||
/* Parse the OMP_SCHEDULE environment variable. */
|
/* Parse the OMP_SCHEDULE environment variable. */
|
||||||
|
|
||||||
@ -177,6 +179,97 @@ parse_boolean (const char *name, bool *value)
|
|||||||
gomp_error ("Invalid value for environment variable %s", name);
|
gomp_error ("Invalid value for environment variable %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
|
||||||
|
present and it was successfully parsed. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
parse_affinity (void)
|
||||||
|
{
|
||||||
|
char *env, *end;
|
||||||
|
unsigned long cpu_beg, cpu_end, cpu_stride;
|
||||||
|
unsigned short *cpus = NULL;
|
||||||
|
size_t allocated = 0, used = 0, needed;
|
||||||
|
|
||||||
|
env = getenv ("GOMP_CPU_AFFINITY");
|
||||||
|
if (env == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
while (*env == ' ' || *env == '\t')
|
||||||
|
env++;
|
||||||
|
|
||||||
|
cpu_beg = strtoul (env, &end, 0);
|
||||||
|
cpu_end = cpu_beg;
|
||||||
|
cpu_stride = 1;
|
||||||
|
if (env == end || cpu_beg >= 65536)
|
||||||
|
goto invalid;
|
||||||
|
|
||||||
|
env = end;
|
||||||
|
if (*env == '-')
|
||||||
|
{
|
||||||
|
cpu_end = strtoul (++env, &end, 0);
|
||||||
|
if (env == end || cpu_end >= 65536 || cpu_end < cpu_beg)
|
||||||
|
goto invalid;
|
||||||
|
|
||||||
|
env = end;
|
||||||
|
if (*env == ':')
|
||||||
|
{
|
||||||
|
cpu_stride = strtoul (++env, &end, 0);
|
||||||
|
if (env == end || cpu_stride == 0 || cpu_stride >= 65536)
|
||||||
|
goto invalid;
|
||||||
|
|
||||||
|
env = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
needed = (cpu_end - cpu_beg) / cpu_stride + 1;
|
||||||
|
if (used + needed >= allocated)
|
||||||
|
{
|
||||||
|
unsigned short *new_cpus;
|
||||||
|
|
||||||
|
if (allocated < 64)
|
||||||
|
allocated = 64;
|
||||||
|
if (allocated > needed)
|
||||||
|
allocated <<= 1;
|
||||||
|
else
|
||||||
|
allocated += 2 * needed;
|
||||||
|
new_cpus = realloc (cpus, allocated * sizeof (unsigned short));
|
||||||
|
if (new_cpus == NULL)
|
||||||
|
{
|
||||||
|
free (cpus);
|
||||||
|
gomp_error ("not enough memory to store GOMP_CPU_AFFINITY list");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpus = new_cpus;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (needed--)
|
||||||
|
{
|
||||||
|
cpus[used++] = cpu_beg;
|
||||||
|
cpu_beg += cpu_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*env == ' ' || *env == '\t')
|
||||||
|
env++;
|
||||||
|
|
||||||
|
if (*env == ',')
|
||||||
|
env++;
|
||||||
|
else if (*env == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
gomp_cpu_affinity = cpus;
|
||||||
|
gomp_cpu_affinity_len = used;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
invalid:
|
||||||
|
gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void __attribute__((constructor))
|
static void __attribute__((constructor))
|
||||||
initialize_env (void)
|
initialize_env (void)
|
||||||
{
|
{
|
||||||
@ -190,6 +283,8 @@ initialize_env (void)
|
|||||||
parse_boolean ("OMP_NESTED", &gomp_nest_var);
|
parse_boolean ("OMP_NESTED", &gomp_nest_var);
|
||||||
if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_nthreads_var))
|
if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_nthreads_var))
|
||||||
gomp_init_num_threads ();
|
gomp_init_num_threads ();
|
||||||
|
if (parse_affinity ())
|
||||||
|
gomp_init_affinity ();
|
||||||
|
|
||||||
/* Not strictly environment related, but ordering constructors is tricky. */
|
/* Not strictly environment related, but ordering constructors is tricky. */
|
||||||
pthread_attr_init (&gomp_thread_attr);
|
pthread_attr_init (&gomp_thread_attr);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
|
||||||
Contributed by Richard Henderson <rth@redhat.com>.
|
Contributed by Richard Henderson <rth@redhat.com>.
|
||||||
|
|
||||||
This file is part of the GNU OpenMP Library (libgomp).
|
This file is part of the GNU OpenMP Library (libgomp).
|
||||||
@ -246,8 +246,18 @@ extern unsigned long gomp_run_sched_chunk;
|
|||||||
/* The attributes to be used during thread creation. */
|
/* The attributes to be used during thread creation. */
|
||||||
extern pthread_attr_t gomp_thread_attr;
|
extern pthread_attr_t gomp_thread_attr;
|
||||||
|
|
||||||
|
/* Other variables. */
|
||||||
|
|
||||||
|
extern unsigned short *gomp_cpu_affinity;
|
||||||
|
extern size_t gomp_cpu_affinity_len;
|
||||||
|
|
||||||
/* Function prototypes. */
|
/* Function prototypes. */
|
||||||
|
|
||||||
|
/* affinity.c */
|
||||||
|
|
||||||
|
extern void gomp_init_affinity (void);
|
||||||
|
extern void gomp_init_thread_affinity (pthread_attr_t *);
|
||||||
|
|
||||||
/* alloc.c */
|
/* alloc.c */
|
||||||
|
|
||||||
extern void *gomp_malloc (size_t) __attribute__((malloc));
|
extern void *gomp_malloc (size_t) __attribute__((malloc));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2005 Free Software Foundation, Inc.
|
/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||||
Contributed by Richard Henderson <rth@redhat.com>.
|
Contributed by Richard Henderson <rth@redhat.com>.
|
||||||
|
|
||||||
This file is part of the GNU OpenMP Library (libgomp).
|
This file is part of the GNU OpenMP Library (libgomp).
|
||||||
@ -183,6 +183,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
|
|||||||
struct gomp_team *team;
|
struct gomp_team *team;
|
||||||
bool nested;
|
bool nested;
|
||||||
unsigned i, n, old_threads_used = 0;
|
unsigned i, n, old_threads_used = 0;
|
||||||
|
pthread_attr_t thread_attr, *attr;
|
||||||
|
|
||||||
thr = gomp_thread ();
|
thr = gomp_thread ();
|
||||||
nested = thr->ts.team != NULL;
|
nested = thr->ts.team != NULL;
|
||||||
@ -265,6 +266,17 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attr = &gomp_thread_attr;
|
||||||
|
if (gomp_cpu_affinity != NULL)
|
||||||
|
{
|
||||||
|
size_t stacksize;
|
||||||
|
pthread_attr_init (&thread_attr);
|
||||||
|
pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
|
||||||
|
pthread_attr_setstacksize (&thread_attr, stacksize);
|
||||||
|
attr = &thread_attr;
|
||||||
|
}
|
||||||
|
|
||||||
start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
|
start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
|
||||||
* (nthreads-i));
|
* (nthreads-i));
|
||||||
|
|
||||||
@ -283,12 +295,18 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
|
|||||||
start_data->fn_data = data;
|
start_data->fn_data = data;
|
||||||
start_data->nested = nested;
|
start_data->nested = nested;
|
||||||
|
|
||||||
err = pthread_create (&pt, &gomp_thread_attr,
|
if (gomp_cpu_affinity != NULL)
|
||||||
gomp_thread_start, start_data);
|
gomp_init_thread_affinity (attr);
|
||||||
|
|
||||||
|
err = pthread_create (&pt, attr, gomp_thread_start, start_data);
|
||||||
|
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
gomp_fatal ("Thread creation failed: %s", strerror (err));
|
gomp_fatal ("Thread creation failed: %s", strerror (err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gomp_cpu_affinity != NULL)
|
||||||
|
pthread_attr_destroy (&thread_attr);
|
||||||
|
|
||||||
do_release:
|
do_release:
|
||||||
gomp_barrier_wait (nested ? &team->barrier : &gomp_threads_dock);
|
gomp_barrier_wait (nested ? &team->barrier : &gomp_threads_dock);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ SHLIB_MAJOR= 1
|
|||||||
SRCS= alloc.c barrier.c critical.c env.c \
|
SRCS= alloc.c barrier.c critical.c env.c \
|
||||||
error.c iter.c loop.c ordered.c parallel.c sections.c \
|
error.c iter.c loop.c ordered.c parallel.c sections.c \
|
||||||
single.c team.c work.c lock.c mutex.c proc.c sem.c \
|
single.c team.c work.c lock.c mutex.c proc.c sem.c \
|
||||||
bar.c time.c fortran.c
|
bar.c time.c fortran.c affinity.c
|
||||||
SRCS+= gstdint.h libgomp_f.h omp.h omp_lib.h
|
SRCS+= gstdint.h libgomp_f.h omp.h omp_lib.h
|
||||||
|
|
||||||
INCS+= omp.h
|
INCS+= omp.h
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
/* Define to 1 if you have the <memory.h> header file. */
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
#define HAVE_MEMORY_H 1
|
#define HAVE_MEMORY_H 1
|
||||||
|
|
||||||
|
/* Define if pthread_{,attr_}{g,s}etaffinity_np is supported. */
|
||||||
|
#undef HAVE_PTHREAD_AFFINITY_NP
|
||||||
|
|
||||||
/* Define to 1 if you have the <semaphore.h> header file. */
|
/* Define to 1 if you have the <semaphore.h> header file. */
|
||||||
#define HAVE_SEMAPHORE_H 1
|
#define HAVE_SEMAPHORE_H 1
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user