This commit is contained in:
Jakub Jelinek 2008-03-27 14:32:22 +00:00
parent 63fa8769db
commit c358f1d2d3
3 changed files with 152 additions and 23 deletions

61
gcc43-i386-libgomp.patch Normal file
View File

@ -0,0 +1,61 @@
Build i386.rpm libgomp and libsupc++.a(guard.o) as i486+, pre-i486
hardware isn't supported because NPTL doesn't support it anyway.
--- libgomp/configure.tgt.jj 2008-01-10 20:53:48.000000000 +0100
+++ libgomp/configure.tgt 2008-03-27 12:44:51.000000000 +0100
@@ -44,14 +44,14 @@ if test $enable_linux_futex = yes; then
;;
# Note that bare i386 is not included here. We need cmpxchg.
- i[456]86-*-linux*)
+ i[3456]86-*-linux*)
config_path="linux/x86 linux posix"
case " ${CC} ${CFLAGS} " in
*" -m64 "*)
;;
*)
if test -z "$with_arch"; then
- XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}"
+ XCFLAGS="${XCFLAGS} -march=i486 -mtune=generic"
fi
esac
;;
@@ -63,7 +63,7 @@ if test $enable_linux_futex = yes; then
config_path="linux/x86 linux posix"
case " ${CC} ${CFLAGS} " in
*" -m32 "*)
- XCFLAGS="${XCFLAGS} -march=i486 -mtune=i686"
+ XCFLAGS="${XCFLAGS} -march=i486 -mtune=generic"
;;
esac
;;
--- libstdc++-v3/libsupc++/guard.cc.jj 2008-03-01 00:58:24.000000000 +0100
+++ libstdc++-v3/libsupc++/guard.cc 2008-03-27 14:08:44.000000000 +0100
@@ -35,6 +35,27 @@
#include <new>
#include <ext/atomicity.h>
#include <ext/concurrence.h>
+#if defined __i386__ && !defined _GLIBCXX_ATOMIC_BUILTINS
+# define _GLIBCXX_ATOMIC_BUILTINS 1
+# define __sync_val_compare_and_swap(a, b, c) \
+ ({ \
+ typedef char sltast[sizeof (*a) == sizeof (int) ? 1 : -1]; \
+ int sltas; \
+ __asm __volatile ("lock; cmpxchgl %3, (%1)" \
+ : "=a" (sltas) \
+ : "r" (a), "0" (b), "r" (c) : "memory"); \
+ sltas; \
+ })
+# define __sync_lock_test_and_set(a, b) \
+ ({ \
+ typedef char sltast[sizeof (*a) == sizeof (int) ? 1 : -1]; \
+ int sltas; \
+ __asm __volatile ("xchgl (%1), %0" \
+ : "=r" (sltas) \
+ : "r" (a), "0" (b) : "memory"); \
+ sltas; \
+ })
+#endif
#if defined(__GTHREADS) && defined(__GTHREAD_HAS_COND) \
&& defined(_GLIBCXX_ATOMIC_BUILTINS) && defined(_GLIBCXX_HAVE_LINUX_FUTEX)
# include <climits>

View File

@ -1,3 +1,20 @@
2008-03-27 Jakub Jelinek <jakub@redhat.com>
* libgomp.h (struct gomp_team_state): Remove single_count field
ifndef HAVE_SYNC_BUILTINS.
(struct gomp_team): Likewise. Add work_share_list_free_lock
ifndef HAVE_SYNC_BUILTINS.
* team.c (gomp_new_team): If HAVE_SYNC_BUILTINS is not defined,
don't initialize single_count, but instead initialize
work_share_list_free_lock.
(free_team): Destroy work_share_list_free_lock ifndef
HAVE_SYNC_BUILTINS.
(gomp_team_start): Don't initialize ts.single_count ifndef
HAVE_SYNC_BUILTINS.
* work.c (alloc_work_share, free_work_share): Use
work_share_list_free_lock instead of atomic chaining ifndef
HAVE_SYNC_BUILTINS.
2008-03-26 Jakub Jelinek <jakub@redhat.com> 2008-03-26 Jakub Jelinek <jakub@redhat.com>
* loop.c (gomp_loop_init): Fix GFS_DYNAMIC ws->mode setting. * loop.c (gomp_loop_init): Fix GFS_DYNAMIC ws->mode setting.
@ -444,7 +461,7 @@
/* 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);
--- libgomp/libgomp.h.jj 2007-12-07 14:41:01.000000000 +0100 --- libgomp/libgomp.h.jj 2007-12-07 14:41:01.000000000 +0100
+++ libgomp/libgomp.h 2008-03-26 16:33:57.000000000 +0100 +++ libgomp/libgomp.h 2008-03-27 12:21:51.000000000 +0100
@@ -50,6 +50,7 @@ @@ -50,6 +50,7 @@
#include "sem.h" #include "sem.h"
#include "mutex.h" #include "mutex.h"
@ -557,7 +574,7 @@
}; };
/* This structure contains all of the thread-local data associated with /* This structure contains all of the thread-local data associated with
@@ -133,21 +158,22 @@ struct gomp_team_state @@ -133,21 +158,24 @@ struct gomp_team_state
/* This is the work share construct which this thread is currently /* This is the work share construct which this thread is currently
processing. Recall that with NOWAIT, not all threads may be processing. Recall that with NOWAIT, not all threads may be
@ -583,12 +600,14 @@
- when encountering it for the first time. This particular number - when encountering it for the first time. This particular number
- reflects the generation of the work_share member of this struct. */ - reflects the generation of the work_share member of this struct. */
- unsigned work_share_generation; - unsigned work_share_generation;
+#ifdef HAVE_SYNC_BUILTINS
+ /* Number of single stmts encountered. */ + /* Number of single stmts encountered. */
+ unsigned long single_count; + unsigned long single_count;
+#endif
/* For GFS_RUNTIME loops that resolved to GFS_STATIC, this is the /* For GFS_RUNTIME loops that resolved to GFS_STATIC, this is the
trip number through the loop. So first time a particular loop trip number through the loop. So first time a particular loop
@@ -163,41 +189,48 @@ struct gomp_team_state @@ -163,41 +191,53 @@ struct gomp_team_state
struct gomp_team struct gomp_team
{ {
@ -644,9 +663,14 @@
+ with alloc_work_share. */ + with alloc_work_share. */
+ struct gomp_work_share *work_share_list_free; + struct gomp_work_share *work_share_list_free;
+ +
+#ifdef HAVE_SYNC_BUILTINS
+ /* Number of simple single regions encountered by threads in this + /* Number of simple single regions encountered by threads in this
+ team. */ + team. */
+ unsigned long single_count; + unsigned long single_count;
+#else
+ /* Mutex protecting addition of workshares to work_share_list_free. */
+ gomp_mutex_t work_share_list_free_lock;
+#endif
+ +
+ /* This barrier is used for most synchronization of the team. */ + /* This barrier is used for most synchronization of the team. */
+ gomp_barrier_t barrier; + gomp_barrier_t barrier;
@ -660,7 +684,7 @@
gomp_sem_t *ordered_release[]; gomp_sem_t *ordered_release[];
}; };
@@ -242,6 +275,11 @@ extern bool gomp_dyn_var; @@ -242,6 +282,11 @@ extern bool gomp_dyn_var;
extern bool gomp_nest_var; extern bool gomp_nest_var;
extern enum gomp_schedule_type gomp_run_sched_var; extern enum gomp_schedule_type gomp_run_sched_var;
extern unsigned long gomp_run_sched_chunk; extern unsigned long gomp_run_sched_chunk;
@ -672,7 +696,7 @@
/* 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;
@@ -306,17 +344,27 @@ extern unsigned gomp_dynamic_max_threads @@ -306,17 +351,27 @@ extern unsigned gomp_dynamic_max_threads
/* team.c */ /* team.c */
@ -761,14 +785,14 @@
{ {
long left = end - start; long left = end - start;
--- libgomp/work.c.jj 2007-12-07 14:41:01.000000000 +0100 --- libgomp/work.c.jj 2007-12-07 14:41:01.000000000 +0100
+++ libgomp/work.c 2008-03-26 15:11:32.000000000 +0100 +++ libgomp/work.c 2008-03-27 12:21:51.000000000 +0100
@@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc. -/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2008 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).
@@ -29,39 +29,117 @@ @@ -29,39 +29,138 @@
of threads. */ of threads. */
#include "libgomp.h" #include "libgomp.h"
@ -804,6 +828,7 @@
- ws = gomp_malloc_cleared (size); - ws = gomp_malloc_cleared (size);
- gomp_mutex_init (&ws->lock); - gomp_mutex_init (&ws->lock);
- ws->ordered_owner = -1; - ws->ordered_owner = -1;
+#ifdef HAVE_SYNC_BUILTINS
+ ws = team->work_share_list_free; + ws = team->work_share_list_free;
+ /* We need atomic read from work_share_list_free, + /* We need atomic read from work_share_list_free,
+ as free_work_share can be called concurrently. */ + as free_work_share can be called concurrently. */
@ -816,6 +841,18 @@
+ team->work_share_list_alloc = next->next_free; + team->work_share_list_alloc = next->next_free;
+ return next; + return next;
+ } + }
+#else
+ gomp_mutex_lock (&team->work_share_list_free_lock);
+ ws = team->work_share_list_free;
+ if (ws)
+ {
+ team->work_share_list_alloc = ws->next_free;
+ team->work_share_list_free = NULL;
+ gomp_mutex_unlock (&team->work_share_list_free_lock);
+ return ws;
+ }
+ gomp_mutex_unlock (&team->work_share_list_free_lock);
+#endif
+ team->work_share_chunk *= 2; + team->work_share_chunk *= 2;
+ ws = gomp_malloc (team->work_share_chunk * sizeof (struct gomp_work_share)); + ws = gomp_malloc (team->work_share_chunk * sizeof (struct gomp_work_share));
@ -888,6 +925,7 @@
+ else + else
+ { + {
+ struct gomp_work_share *next_ws; + struct gomp_work_share *next_ws;
+#ifdef HAVE_SYNC_BUILTINS
+ do + do
+ { + {
+ next_ws = team->work_share_list_free; + next_ws = team->work_share_list_free;
@ -895,12 +933,19 @@
+ } + }
+ while (!__sync_bool_compare_and_swap (&team->work_share_list_free, + while (!__sync_bool_compare_and_swap (&team->work_share_list_free,
+ next_ws, ws)); + next_ws, ws));
+#else
+ gomp_mutex_lock (&team->work_share_list_free_lock);
+ next_ws = team->work_share_list_free;
+ ws->next_free = next_ws;
+ team->work_share_list_free = ws;
+ gomp_mutex_unlock (&team->work_share_list_free_lock);
+#endif
+ } + }
+} +}
/* The current thread is ready to begin the next work sharing construct. /* The current thread is ready to begin the next work sharing construct.
In all cases, thr->ts.work_share is updated to point to the new In all cases, thr->ts.work_share is updated to point to the new
@@ -74,71 +152,34 @@ gomp_work_share_start (bool ordered) @@ -74,71 +173,34 @@ gomp_work_share_start (bool ordered)
struct gomp_thread *thr = gomp_thread (); struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team; struct gomp_team *team = thr->ts.team;
struct gomp_work_share *ws; struct gomp_work_share *ws;
@ -987,7 +1032,7 @@
/* The current thread is done with its current work sharing construct. /* The current thread is done with its current work sharing construct.
This version does imply a barrier at the end of the work-share. */ This version does imply a barrier at the end of the work-share. */
@@ -147,36 +188,28 @@ gomp_work_share_end (void) @@ -147,36 +209,28 @@ gomp_work_share_end (void)
{ {
struct gomp_thread *thr = gomp_thread (); struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team; struct gomp_team *team = thr->ts.team;
@ -1033,7 +1078,7 @@
/* The current thread is done with its current work sharing construct. /* The current thread is done with its current work sharing construct.
This version does NOT imply a barrier at the end of the work-share. */ This version does NOT imply a barrier at the end of the work-share. */
@@ -188,15 +221,17 @@ gomp_work_share_end_nowait (void) @@ -188,15 +242,17 @@ gomp_work_share_end_nowait (void)
struct gomp_work_share *ws = thr->ts.work_share; struct gomp_work_share *ws = thr->ts.work_share;
unsigned completed; unsigned completed;
@ -1054,7 +1099,7 @@
#ifdef HAVE_SYNC_BUILTINS #ifdef HAVE_SYNC_BUILTINS
completed = __sync_add_and_fetch (&ws->threads_completed, 1); completed = __sync_add_and_fetch (&ws->threads_completed, 1);
#else #else
@@ -206,18 +241,6 @@ gomp_work_share_end_nowait (void) @@ -206,18 +262,6 @@ gomp_work_share_end_nowait (void)
#endif #endif
if (completed == team->nthreads) if (completed == team->nthreads)
@ -1372,7 +1417,7 @@
nodist_noinst_HEADERS = libgomp_f.h nodist_noinst_HEADERS = libgomp_f.h
nodist_libsubinclude_HEADERS = omp.h nodist_libsubinclude_HEADERS = omp.h
--- libgomp/team.c.jj 2007-12-07 14:41:01.000000000 +0100 --- libgomp/team.c.jj 2007-12-07 14:41:01.000000000 +0100
+++ libgomp/team.c 2008-03-26 16:21:37.000000000 +0100 +++ libgomp/team.c 2008-03-27 12:22:26.000000000 +0100
@@ -94,7 +94,7 @@ gomp_thread_start (void *xdata) @@ -94,7 +94,7 @@ gomp_thread_start (void *xdata)
{ {
gomp_barrier_wait (&thr->ts.team->barrier); gomp_barrier_wait (&thr->ts.team->barrier);
@ -1396,7 +1441,7 @@
gomp_barrier_wait (&gomp_threads_dock); gomp_barrier_wait (&gomp_threads_dock);
local_fn = thr->fn; local_fn = thr->fn;
@@ -133,21 +132,25 @@ gomp_thread_start (void *xdata) @@ -133,21 +132,29 @@ gomp_thread_start (void *xdata)
/* Create a new team data structure. */ /* Create a new team data structure. */
@ -1419,7 +1464,11 @@
- team->num_live_gen = work_share != NULL; - team->num_live_gen = work_share != NULL;
- team->work_shares[0] = work_share; - team->work_shares[0] = work_share;
+ team->work_share_chunk = 8; + team->work_share_chunk = 8;
+#ifdef HAVE_SYNC_BUILTINS
+ team->single_count = 0; + team->single_count = 0;
+#else
+ gomp_mutex_init (&team->work_share_list_free_lock);
+#endif
+ gomp_init_work_share (&team->work_shares[0], false, nthreads); + gomp_init_work_share (&team->work_shares[0], false, nthreads);
+ team->work_shares[0].next_alloc = NULL; + team->work_shares[0].next_alloc = NULL;
+ team->work_share_list_free = NULL; + team->work_share_list_free = NULL;
@ -1430,7 +1479,7 @@
team->nthreads = nthreads; team->nthreads = nthreads;
gomp_barrier_init (&team->barrier, nthreads); gomp_barrier_init (&team->barrier, nthreads);
@@ -164,8 +167,17 @@ new_team (unsigned nthreads, struct gomp @@ -164,10 +171,22 @@ new_team (unsigned nthreads, struct gomp
static void static void
free_team (struct gomp_team *team) free_team (struct gomp_team *team)
{ {
@ -1449,8 +1498,13 @@
+ } + }
gomp_barrier_destroy (&team->barrier); gomp_barrier_destroy (&team->barrier);
gomp_sem_destroy (&team->master_release); gomp_sem_destroy (&team->master_release);
+#ifndef HAVE_SYNC_BUILTINS
+ gomp_mutex_destroy (&team->work_share_list_free_lock);
+#endif
free (team); free (team);
@@ -176,11 +188,10 @@ free_team (struct gomp_team *team) }
@@ -176,11 +195,10 @@ free_team (struct gomp_team *team)
void void
gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads, gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
@ -1463,7 +1517,7 @@
bool nested; bool nested;
unsigned i, n, old_threads_used = 0; unsigned i, n, old_threads_used = 0;
pthread_attr_t thread_attr, *attr; pthread_attr_t thread_attr, *attr;
@@ -188,17 +199,16 @@ gomp_team_start (void (*fn) (void *), vo @@ -188,17 +206,18 @@ gomp_team_start (void (*fn) (void *), vo
thr = gomp_thread (); thr = gomp_thread ();
nested = thr->ts.team != NULL; nested = thr->ts.team != NULL;
@ -1480,11 +1534,13 @@
- thr->ts.work_share_generation = 0; - thr->ts.work_share_generation = 0;
+ thr->ts.work_share = &team->work_shares[0]; + thr->ts.work_share = &team->work_shares[0];
+ thr->ts.last_work_share = NULL; + thr->ts.last_work_share = NULL;
+#ifdef HAVE_SYNC_BUILTINS
+ thr->ts.single_count = 0; + thr->ts.single_count = 0;
+#endif
thr->ts.static_trip = 0; thr->ts.static_trip = 0;
if (nthreads == 1) if (nthreads == 1)
@@ -241,9 +251,10 @@ gomp_team_start (void (*fn) (void *), vo @@ -241,9 +260,12 @@ gomp_team_start (void (*fn) (void *), vo
{ {
nthr = gomp_threads[i]; nthr = gomp_threads[i];
nthr->ts.team = team; nthr->ts.team = team;
@ -1493,11 +1549,13 @@
+ nthr->ts.last_work_share = NULL; + nthr->ts.last_work_share = NULL;
nthr->ts.team_id = i; nthr->ts.team_id = i;
- nthr->ts.work_share_generation = 0; - nthr->ts.work_share_generation = 0;
+#ifdef HAVE_SYNC_BUILTINS
+ nthr->ts.single_count = 0; + nthr->ts.single_count = 0;
+#endif
nthr->ts.static_trip = 0; nthr->ts.static_trip = 0;
nthr->fn = fn; nthr->fn = fn;
nthr->data = data; nthr->data = data;
@@ -266,8 +277,24 @@ gomp_team_start (void (*fn) (void *), vo @@ -266,8 +288,24 @@ gomp_team_start (void (*fn) (void *), vo
} }
} }
@ -1523,7 +1581,7 @@
{ {
size_t stacksize; size_t stacksize;
pthread_attr_init (&thread_attr); pthread_attr_init (&thread_attr);
@@ -287,9 +314,10 @@ gomp_team_start (void (*fn) (void *), vo @@ -287,9 +325,12 @@ gomp_team_start (void (*fn) (void *), vo
int err; int err;
start_data->ts.team = team; start_data->ts.team = team;
@ -1532,11 +1590,13 @@
+ start_data->ts.last_work_share = NULL; + start_data->ts.last_work_share = NULL;
start_data->ts.team_id = i; start_data->ts.team_id = i;
- start_data->ts.work_share_generation = 0; - start_data->ts.work_share_generation = 0;
+#ifdef HAVE_SYNC_BUILTINS
+ start_data->ts.single_count = 0; + start_data->ts.single_count = 0;
+#endif
start_data->ts.static_trip = 0; start_data->ts.static_trip = 0;
start_data->fn = fn; start_data->fn = fn;
start_data->fn_data = data; start_data->fn_data = data;
@@ -303,7 +331,7 @@ gomp_team_start (void (*fn) (void *), vo @@ -303,7 +344,7 @@ gomp_team_start (void (*fn) (void *), vo
gomp_fatal ("Thread creation failed: %s", strerror (err)); gomp_fatal ("Thread creation failed: %s", strerror (err));
} }
@ -1545,7 +1605,7 @@
pthread_attr_destroy (&thread_attr); pthread_attr_destroy (&thread_attr);
do_release: do_release:
@@ -313,8 +341,20 @@ gomp_team_start (void (*fn) (void *), vo @@ -313,8 +354,20 @@ gomp_team_start (void (*fn) (void *), vo
that should arrive back at the end of this team. The extra that should arrive back at the end of this team. The extra
threads should be exiting. Note that we arrange for this test threads should be exiting. Note that we arrange for this test
to never be true for nested teams. */ to never be true for nested teams. */
@ -1568,7 +1628,7 @@
} }
@@ -329,8 +369,21 @@ gomp_team_end (void) @@ -329,8 +382,21 @@ gomp_team_end (void)
gomp_barrier_wait (&team->barrier); gomp_barrier_wait (&team->barrier);

View File

@ -1,6 +1,6 @@
%define DATE 20080326 %define DATE 20080326
%define gcc_version 4.3.0 %define gcc_version 4.3.0
%define gcc_release 4 %define gcc_release 5
%define _unpackaged_files_terminate_build 0 %define _unpackaged_files_terminate_build 0
%define multilib_64_archs sparc64 ppc64 s390x x86_64 %define multilib_64_archs sparc64 ppc64 s390x x86_64
%define include_gappletviewer 1 %define include_gappletviewer 1
@ -143,6 +143,7 @@ Patch13: gcc43-java-debug-iface-type.patch
Patch14: gcc43-libgomp-speedup.patch Patch14: gcc43-libgomp-speedup.patch
Patch15: gcc43-pr35440.patch Patch15: gcc43-pr35440.patch
Patch16: gcc43-pr35546.patch Patch16: gcc43-pr35546.patch
Patch17: gcc43-i386-libgomp.patch
# On ARM EABI systems, we do want -gnueabi to be part of the # On ARM EABI systems, we do want -gnueabi to be part of the
# target triple. # target triple.
@ -443,6 +444,7 @@ which are required to run programs compiled with the GNAT.
%patch14 -p0 -b .libgomp-speedup~ %patch14 -p0 -b .libgomp-speedup~
%patch15 -p0 -b .pr35440~ %patch15 -p0 -b .pr35440~
%patch16 -p0 -b .pr35546~ %patch16 -p0 -b .pr35546~
%patch17 -p0 -b .i386-libgomp~
tar xzf %{SOURCE4} tar xzf %{SOURCE4}
@ -1655,6 +1657,12 @@ fi
%doc rpm.doc/changelogs/libmudflap/ChangeLog* %doc rpm.doc/changelogs/libmudflap/ChangeLog*
%changelog %changelog
* Thu Mar 27 2008 Jakub Jelinek <jakub@redhat.com> 4.3.0-5
- fix libgomp when sync builtins aren't available
- on i386 build libgomp and __cxa_guard_* as i486+,
NPTL doesn't support pre-i486 anyway and atomic builtins give
significant speedups
* Wed Mar 26 2008 Jakub Jelinek <jakub@redhat.com> 4.3.0-4 * Wed Mar 26 2008 Jakub Jelinek <jakub@redhat.com> 4.3.0-4
- update from gcc-4_3-branch - update from gcc-4_3-branch
- PRs c++/35332, c++/35548, debug/31510, fortran/33295, fortran/34813, - PRs c++/35332, c++/35548, debug/31510, fortran/33295, fortran/34813,