From bae61767963efd9edc24fa9bddc185bbbf49af00 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 9 Jun 2008 11:42:57 +0000 Subject: [PATCH] 4.3.1-1 --- .cvsignore | 2 +- gcc43-cpp-pragma.patch | 284 --- gcc43-libgomp-omp_h-multilib.patch | 17 + gcc43-libgomp-speedup.patch | 2797 ---------------------------- gcc43-pr35650.patch | 50 - gcc43-pr35909.patch | 41 - gcc43-pr35987.patch | 37 - gcc43-sparc-config-detection.patch | 40 + gcc43.spec | 136 +- sources | 2 +- 10 files changed, 144 insertions(+), 3262 deletions(-) delete mode 100644 gcc43-cpp-pragma.patch create mode 100644 gcc43-libgomp-omp_h-multilib.patch delete mode 100644 gcc43-libgomp-speedup.patch delete mode 100644 gcc43-pr35650.patch delete mode 100644 gcc43-pr35909.patch delete mode 100644 gcc43-pr35987.patch create mode 100644 gcc43-sparc-config-detection.patch diff --git a/.cvsignore b/.cvsignore index d4b4867..2accf17 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,2 +1,2 @@ -gcc-4.3.0-20080428.tar.bz2 +gcc-4.3.1-20080609.tar.bz2 fastjar-0.95.tar.gz diff --git a/gcc43-cpp-pragma.patch b/gcc43-cpp-pragma.patch deleted file mode 100644 index 00d37bd..0000000 --- a/gcc43-cpp-pragma.patch +++ /dev/null @@ -1,284 +0,0 @@ -2008-02-26 Jakub Jelinek - - * c-ppoutput.c (scan_translation_unit): Handle CPP_PRAGMA - and CPP_PRAGMA_EOL. - * c-pragma.c (pragma_ns_name): New typedef. - (registered_pp_pragmas): New variable. - (c_pp_lookup_pragma): New function. - (c_register_pragma_1): If flag_preprocess_only, do nothing - for non-expanded pragmas, for expanded ones push pragma's - namespace and name into registered_pp_pragmas vector. - (c_invoke_pragma_handler): Register OpenMP pragmas even when - flag_preprocess_only, don't register GCC pch_preprocess - pragma if flag_preprocess_only. - * c-opts.c (c_common_init): Call init_pragma even if - flag_preprocess_only. - * c-pragma.c (c_pp_lookup_pragma): New prototype. - * config/darwin.h (DARWIN_REGISTER_TARGET_PRAGMAS): Don't call - cpp_register_pragma if flag_preprocess_only. - - * gcc.dg/gomp/preprocess-1.c: New test. - ---- gcc/c-ppoutput.c.jj 2008-01-26 18:01:16.000000000 +0100 -+++ gcc/c-ppoutput.c 2008-02-26 22:54:57.000000000 +0100 -@@ -1,6 +1,6 @@ - /* Preprocess only, using cpplib. -- Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007 -- Free Software Foundation, Inc. -+ Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, -+ 2008 Free Software Foundation, Inc. - Written by Per Bothner, 1994-95. - - This program is free software; you can redistribute it and/or modify it -@@ -177,7 +177,24 @@ scan_translation_unit (cpp_reader *pfile - avoid_paste = false; - print.source = NULL; - print.prev = token; -- cpp_output_token (token, print.outf); -+ if (token->type == CPP_PRAGMA) -+ { -+ const char *space; -+ const char *name; -+ -+ maybe_print_line (token->src_loc); -+ fputs ("#pragma ", print.outf); -+ c_pp_lookup_pragma (token->val.pragma, &space, &name); -+ if (space) -+ fprintf (print.outf, "%s %s", space, name); -+ else -+ fprintf (print.outf, "%s", name); -+ print.printed = 1; -+ } -+ else if (token->type == CPP_PRAGMA_EOL) -+ maybe_print_line (token->src_loc); -+ else -+ cpp_output_token (token, print.outf); - - if (token->type == CPP_COMMENT) - account_for_newlines (token->val.str.text, token->val.str.len); ---- gcc/c-pragma.c.jj 2008-02-15 18:43:03.000000000 +0100 -+++ gcc/c-pragma.c 2008-02-26 22:59:44.000000000 +0100 -@@ -1,6 +1,6 @@ - /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack. - Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -- 2006, 2007 Free Software Foundation, Inc. -+ 2006, 2007, 2008 Free Software Foundation, Inc. - - This file is part of GCC. - -@@ -872,6 +872,61 @@ DEF_VEC_ALLOC_O (pragma_handler, heap); - - static VEC(pragma_handler, heap) *registered_pragmas; - -+typedef struct -+{ -+ const char *space; -+ const char *name; -+} pragma_ns_name; -+ -+DEF_VEC_O (pragma_ns_name); -+DEF_VEC_ALLOC_O (pragma_ns_name, heap); -+ -+static VEC(pragma_ns_name, heap) *registered_pp_pragmas; -+ -+struct omp_pragma_def { const char *name; unsigned int id; }; -+static const struct omp_pragma_def omp_pragmas[] = { -+ { "atomic", PRAGMA_OMP_ATOMIC }, -+ { "barrier", PRAGMA_OMP_BARRIER }, -+ { "critical", PRAGMA_OMP_CRITICAL }, -+ { "flush", PRAGMA_OMP_FLUSH }, -+ { "for", PRAGMA_OMP_FOR }, -+ { "master", PRAGMA_OMP_MASTER }, -+ { "ordered", PRAGMA_OMP_ORDERED }, -+ { "parallel", PRAGMA_OMP_PARALLEL }, -+ { "section", PRAGMA_OMP_SECTION }, -+ { "sections", PRAGMA_OMP_SECTIONS }, -+ { "single", PRAGMA_OMP_SINGLE }, -+ { "threadprivate", PRAGMA_OMP_THREADPRIVATE } -+}; -+ -+void -+c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) -+{ -+ const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); -+ int i; -+ -+ for (i = 0; i < n_omp_pragmas; ++i) -+ if (omp_pragmas[i].id == id) -+ { -+ *space = "omp"; -+ *name = omp_pragmas[i].name; -+ return; -+ } -+ -+ if (id >= PRAGMA_FIRST_EXTERNAL -+ && (id < PRAGMA_FIRST_EXTERNAL -+ + VEC_length (pragma_ns_name, registered_pp_pragmas))) -+ { -+ *space = VEC_index (pragma_ns_name, registered_pp_pragmas, -+ id - PRAGMA_FIRST_EXTERNAL)->space; -+ *name = VEC_index (pragma_ns_name, registered_pp_pragmas, -+ id - PRAGMA_FIRST_EXTERNAL)->name; -+ return; -+ } -+ -+ gcc_unreachable (); -+} -+ - /* Front-end wrappers for pragma registration to avoid dragging - cpplib.h in almost everywhere. */ - -@@ -881,13 +936,29 @@ c_register_pragma_1 (const char *space, - { - unsigned id; - -- VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); -- id = VEC_length (pragma_handler, registered_pragmas); -- id += PRAGMA_FIRST_EXTERNAL - 1; -- -- /* The C++ front end allocates 6 bits in cp_token; the C front end -- allocates 7 bits in c_token. At present this is sufficient. */ -- gcc_assert (id < 64); -+ if (flag_preprocess_only) -+ { -+ pragma_ns_name ns_name; -+ -+ if (!allow_expansion) -+ return; -+ -+ ns_name.space = space; -+ ns_name.name = name; -+ VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas, &ns_name); -+ id = VEC_length (pragma_ns_name, registered_pp_pragmas); -+ id += PRAGMA_FIRST_EXTERNAL - 1; -+ } -+ else -+ { -+ VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); -+ id = VEC_length (pragma_handler, registered_pragmas); -+ id += PRAGMA_FIRST_EXTERNAL - 1; -+ -+ /* The C++ front end allocates 6 bits in cp_token; the C front end -+ allocates 7 bits in c_token. At present this is sufficient. */ -+ gcc_assert (id < 64); -+ } - - cpp_register_deferred_pragma (parse_in, space, name, id, - allow_expansion, false); -@@ -921,24 +992,8 @@ c_invoke_pragma_handler (unsigned int id - void - init_pragma (void) - { -- if (flag_openmp && !flag_preprocess_only) -+ if (flag_openmp) - { -- struct omp_pragma_def { const char *name; unsigned int id; }; -- static const struct omp_pragma_def omp_pragmas[] = { -- { "atomic", PRAGMA_OMP_ATOMIC }, -- { "barrier", PRAGMA_OMP_BARRIER }, -- { "critical", PRAGMA_OMP_CRITICAL }, -- { "flush", PRAGMA_OMP_FLUSH }, -- { "for", PRAGMA_OMP_FOR }, -- { "master", PRAGMA_OMP_MASTER }, -- { "ordered", PRAGMA_OMP_ORDERED }, -- { "parallel", PRAGMA_OMP_PARALLEL }, -- { "section", PRAGMA_OMP_SECTION }, -- { "sections", PRAGMA_OMP_SECTIONS }, -- { "single", PRAGMA_OMP_SINGLE }, -- { "threadprivate", PRAGMA_OMP_THREADPRIVATE } -- }; -- - const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); - int i; - -@@ -947,8 +1002,9 @@ init_pragma (void) - omp_pragmas[i].id, true, true); - } - -- cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess", -- PRAGMA_GCC_PCH_PREPROCESS, false, false); -+ if (!flag_preprocess_only) -+ cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess", -+ PRAGMA_GCC_PCH_PREPROCESS, false, false); - - #ifdef HANDLE_PRAGMA_PACK - #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION ---- gcc/c-opts.c.jj 2008-02-26 22:53:23.000000000 +0100 -+++ gcc/c-opts.c 2008-02-26 22:54:57.000000000 +0100 -@@ -1,5 +1,5 @@ - /* C/ObjC/C++ command line option handling. -- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 -+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. - Contributed by Neil Booth. - -@@ -1239,6 +1239,9 @@ c_common_init (void) - if (version_flag) - c_common_print_pch_checksum (stderr); - -+ /* Has to wait until now so that cpplib has its hash table. */ -+ init_pragma (); -+ - if (flag_preprocess_only) - { - finish_options (); -@@ -1246,9 +1249,6 @@ c_common_init (void) - return false; - } - -- /* Has to wait until now so that cpplib has its hash table. */ -- init_pragma (); -- - return true; - } - ---- gcc/c-pragma.h.jj 2008-01-26 18:01:16.000000000 +0100 -+++ gcc/c-pragma.h 2008-02-26 22:54:57.000000000 +0100 -@@ -1,6 +1,6 @@ - /* Pragma related interfaces. - Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -- 2007 Free Software Foundation, Inc. -+ 2007, 2008 Free Software Foundation, Inc. - - This file is part of GCC. - -@@ -124,4 +124,6 @@ extern enum cpp_ttype pragma_lex (tree * - extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *, - int); - -+extern void c_pp_lookup_pragma (unsigned int, const char **, const char **); -+ - #endif /* GCC_C_PRAGMA_H */ ---- gcc/config/darwin.h.jj 2008-02-11 14:48:12.000000000 +0100 -+++ gcc/config/darwin.h 2008-02-26 22:54:57.000000000 +0100 -@@ -892,8 +892,9 @@ enum machopic_addr_class { - - #define DARWIN_REGISTER_TARGET_PRAGMAS() \ - do { \ -- cpp_register_pragma (parse_in, NULL, "mark", \ -- darwin_pragma_ignore, false); \ -+ if (!flag_preprocess_only) \ -+ cpp_register_pragma (parse_in, NULL, "mark", \ -+ darwin_pragma_ignore, false); \ - c_register_pragma (0, "options", darwin_pragma_options); \ - c_register_pragma (0, "segment", darwin_pragma_ignore); \ - c_register_pragma (0, "unused", darwin_pragma_unused); \ ---- gcc/testsuite/gcc.dg/gomp/preprocess-1.c.jj 2008-02-26 22:54:57.000000000 +0100 -+++ gcc/testsuite/gcc.dg/gomp/preprocess-1.c 2008-02-26 22:54:57.000000000 +0100 -@@ -0,0 +1,16 @@ -+/* { dg-do preprocess } */ -+ -+void foo (void) -+{ -+ int i1, j1, k1; -+#define p parallel -+#define P(x) private (x##1) -+#define S(x) shared (x##1) -+#define F(x) firstprivate (x##1) -+#pragma omp p P(i) \ -+ S(j) \ -+ F(k) -+ ; -+} -+ -+/* { dg-final { scan-file preprocess-1.i "(^|\n)#pragma omp parallel private \\(i1\\) shared \\(j1\\) firstprivate \\(k1\\)($|\n)" } } */ diff --git a/gcc43-libgomp-omp_h-multilib.patch b/gcc43-libgomp-omp_h-multilib.patch new file mode 100644 index 0000000..d0e98d1 --- /dev/null +++ b/gcc43-libgomp-omp_h-multilib.patch @@ -0,0 +1,17 @@ +2008-06-09 Jakub Jelinek + + * omp.h.in (omp_nest_lock_t): Fix up for Linux multilibs. + +--- libgomp/omp.h.in.jj 2008-06-09 13:34:05.000000000 +0200 ++++ libgomp/omp.h.in 2008-06-09 13:34:48.000000000 +0200 +@@ -42,8 +42,8 @@ typedef struct + + typedef struct + { +- unsigned char _x[@OMP_NEST_LOCK_SIZE@] +- __attribute__((__aligned__(@OMP_NEST_LOCK_ALIGN@))); ++ unsigned char _x[8 + sizeof (void *)] ++ __attribute__((__aligned__(sizeof (void *)))); + } omp_nest_lock_t; + #endif + diff --git a/gcc43-libgomp-speedup.patch b/gcc43-libgomp-speedup.patch deleted file mode 100644 index da85e55..0000000 --- a/gcc43-libgomp-speedup.patch +++ /dev/null @@ -1,2797 +0,0 @@ -2008-03-28 Jakub Jelinek - - * config/linux/sparc/futex.h (atomic_write_barrier): Fix membar - argument. - -2008-03-27 Jakub Jelinek - - * 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 - - * loop.c (gomp_loop_init): Fix GFS_DYNAMIC ws->mode setting. - * testsuite/libgomp.c/loop-4.c: New test. - - * libgomp.h (struct gomp_team_state): Add single_count field. - (struct gomp_team): Likewise. - * team.c (gomp_new_team): Clear single_count. - (gomp_team_start): Likewise. - * single.c (GOMP_single_start): Rewritten if HAVE_SYNC_BUILTINS. - -2008-03-25 Jakub Jelinek - - * team.c (gomp_thread_start): Don't clear ts.static_trip here. - * loop.c (gomp_loop_static_start, gomp_loop_dynamic_start): Clear - ts.static_trip here. - * work.c (gomp_work_share_start): Don't clear ts.static_trip here. - -2008-03-21 Jakub Jelinek - - * libgomp.h: Include ptrlock.h. - (struct gomp_work_share): Reshuffle fields. Add next_alloc, - next_ws, next_free and inline_ordered_team_ids fields, change - ordered_team_ids into pointer from flexible array member. - (struct gomp_team_state): Add last_work_share field, remove - work_share_generation. - (struct gomp_team): Remove work_share_lock, generation_mask, - oldest_live_gen, num_live_gen and init_work_shares fields, add - work work_share_list_alloc, work_share_list_free and work_share_chunk - fields. Change work_shares from pointer to pointers into an array. - (gomp_new_team): New prototype. - (gomp_team_start): Change type of last argument. - (gomp_new_work_share): Removed. - (gomp_init_work_share, gomp_fini_work_share): New prototypes. - (gomp_work_share_init_done): New static inline. - * team.c (gomp_thread_start): Clear ts.last_work_share, don't clear - ts.work_share_generation. - (new_team): Removed. - (gomp_new_team): New function. - (free_team): Free gomp_work_share blocks chained through next_alloc, - instead of freeing work_shares and destroying work_share_lock. - (gomp_team_start): Change last argument from ws to team, don't create - new team, set ts.work_share to &team->work_shares[0] and clear - ts.last_work_share. Don't clear ts.work_share_generation. - (gomp_team_end): Call gomp_fini_work_share. - * work.c (gomp_new_work_share): Removed. - (alloc_work_share, gomp_init_work_share, gomp_fini_work_share): New - functions. - (free_work_share): Add team argument. Call gomp_fini_work_share - and then either free ws if orphaned, or put it into - work_share_list_free list of the current team. - (gomp_work_share_start, gomp_work_share_end, - gomp_work_share_end_nowait): Rewritten. - * sections.c (GOMP_sections_start): Call gomp_work_share_init_done - after gomp_sections_init. If HAVE_SYNC_BUILTINS, call - gomp_iter_dynamic_next instead of the _locked variant and don't take - lock around it, otherwise acquire it before calling - gomp_iter_dynamic_next_locked. - (GOMP_sections_next): If HAVE_SYNC_BUILTINS, call - gomp_iter_dynamic_next instead of the _locked variant and don't take - lock around it. - (GOMP_parallel_sections_start): Call gomp_new_team instead of - gomp_new_work_share. Call gomp_sections_init on &team->work_shares[0]. - Adjust gomp_team_start caller. - * loop.c (gomp_loop_static_start, gomp_loop_ordered_static_start): Call - gomp_work_share_init_done after gomp_loop_init. Don't unlock ws->lock. - (gomp_loop_dynamic_start, gomp_loop_guided_start): Call - gomp_work_share_init_done after gomp_loop_init. If HAVE_SYNC_BUILTINS, - don't unlock ws->lock, otherwise lock it. - (gomp_loop_ordered_dynamic_start, gomp_loop_ordered_guided_start): Call - gomp_work_share_init_done after gomp_loop_init. Lock ws->lock. - (gomp_parallel_loop_start): Call gomp_new_team instead of - gomp_new_work_share. Call gomp_loop_init on &team->work_shares[0]. - Adjust gomp_team_start caller. - * single.c (GOMP_single_start, GOMP_single_copy_start): Call - gomp_work_share_init_done if gomp_work_share_start returned true. - Don't unlock ws->lock. - * parallel.c (GOMP_parallel_start): Call gomp_new_team and pass that - as last argument to gomp_team_start. - * config/linux/ptrlock.c: New file. - * config/linux/ptrlock.h: New file. - * config/posix/ptrlock.c: New file. - * config/posix/ptrlock.h: New file. - * Makefile.am (libgomp_la_SOURCES): Add ptrlock.c. - * Makefile.in: Regenerated. - * testsuite/Makefile.in: Regenerated. - -2008-03-19 Jakub Jelinek - - * libgomp.h (gomp_active_wait_policy): Remove decl. - (gomp_throttled_spin_count_var, gomp_available_cpus, - gomp_managed_threads): New extern decls. - * team.c (gomp_team_start, gomp_team_end): If number of threads - changed, adjust atomically gomp_managed_threads. - * env.c (gomp_active_wait_policy, gomp_block_time_var): Remove. - (gomp_throttled_spin_count_var, gomp_available_cpus, - gomp_managed_threads): New variables. - (parse_millis): Removed. - (parse_spincount): New function. - (parse_wait_policy): Return -1/0/1 instead of setting - gomp_active_wait_policy. - (initialize_env): Call gomp_init_num_threads unconditionally. - Initialize gomp_available_cpus. Call parse_spincount instead - of parse_millis, initialize gomp_{,throttled_}spin_count_var - depending on presence and value of OMP_WAIT_POLICY and - GOMP_SPINCOUNT env vars. - * config/linux/wait.h (do_wait): Use gomp_throttled_spin_count_var - instead of gomp_spin_count_var if gomp_managed_threads > - gomp_available_cpus. - - * config/linux/wait.h: Include errno.h. - (FUTEX_WAIT, FUTEX_WAKE, FUTEX_PRIVATE_FLAG): Define. - (gomp_futex_wake, gomp_futex_wait): New extern decls. - * config/linux/mutex.c (gomp_futex_wake, gomp_futex_wait): New - variables. - * config/linux/powerpc/futex.h (FUTEX_WAIT, FUTEX_WAKE): Remove. - (sys_futex0): Return error code. - (futex_wake, futex_wait): If ENOSYS was returned, clear - FUTEX_PRIVATE_FLAG in gomp_futex_wa{ke,it} and retry. - * config/linux/alpha/futex.h (FUTEX_WAIT, FUTEX_WAKE): Remove. - (futex_wake, futex_wait): If ENOSYS was returned, clear - FUTEX_PRIVATE_FLAG in gomp_futex_wa{ke,it} and retry. - * config/linux/x86/futex.h (FUTEX_WAIT, FUTEX_WAKE): Remove. - (sys_futex0): Return error code. - (futex_wake, futex_wait): If ENOSYS was returned, clear - FUTEX_PRIVATE_FLAG in gomp_futex_wa{ke,it} and retry. - * config/linux/s390/futex.h (FUTEX_WAIT, FUTEX_WAKE): Remove. - (sys_futex0): Return error code. - (futex_wake, futex_wait): If ENOSYS was returned, clear - FUTEX_PRIVATE_FLAG in gomp_futex_wa{ke,it} and retry. - * config/linux/ia64/futex.h (FUTEX_WAIT, FUTEX_WAKE): Remove. - (sys_futex0): Return error code. - (futex_wake, futex_wait): If ENOSYS was returned, clear - FUTEX_PRIVATE_FLAG in gomp_futex_wa{ke,it} and retry. - * config/linux/sparc/futex.h (FUTEX_WAIT, FUTEX_WAKE): Remove. - (sys_futex0): Return error code. - (futex_wake, futex_wait): If ENOSYS was returned, clear - FUTEX_PRIVATE_FLAG in gomp_futex_wa{ke,it} and retry. - -2008-03-18 Jakub Jelinek - - * libgomp.h (struct gomp_work_share): Add mode field. Put lock and - next into a different cache line from most of the write-once fields. - * loop.c: Include limits.h. - (gomp_loop_init): For GFS_DYNAMIC, multiply ws->chunk_size by incr. - If adding ws->chunk_size nthreads + 1 times after end won't - overflow, set ws->mode to 1. - * iter.c (gomp_iter_dynamic_next_locked): Don't multiply - ws->chunk_size by incr. - (gomp_iter_dynamic_next): Likewise. If ws->mode, use more efficient - code. - * work.c: Include stddef.h. - (gomp_new_work_share): Use offsetof rather than sizeof. - -2008-03-17 Jakub Jelinek - - * libgomp.h (struct gomp_team): Change ordered_release field - into gomp_sem_t ** from flexible array member. Add implicit_task - and initial_work_shares fields. - (gomp_new_task): Removed. - (gomp_init_task): New prototype. - * team.c (new_team): Allocate implicit_task for each thread - and initial work_shares together with gomp_team allocation. - (free_team): Only free work_shares if it is not init_work_shares. - (gomp_team_start): Use gomp_init_task instead of gomp_new_task, - set thr->task to the corresponding implicit_task array entry. - * task.c (gomp_new_task): Removed. - (gomp_init_task): New function. - (gomp_end_task): Don't free the task. - (GOMP_task): Allocate struct gomp_task on the stack, call - gomp_init_task rather than gomp_new_task. - * work.c (gomp_work_share_start): If work_shares == - init_work_shares, gomp_malloc + memcpy rather than gomp_realloc. - -2008-03-15 Jakub Jelinek - Ulrich Drepper - - * config/linux/bar.h (gomp_barrier_state_t): Rewritten. - (gomp_barrier_state_t): Change to unsigned int. - (gomp_barrier_init, gomp_barrier_reinit, gomp_barrier_destroy, - gomp_barrier_wait_start, gomp_barrier_last_thread): Rewritten. - (gomp_barrier_wait_last): Prototype rather than inline. - * config/linux/bar.c (gomp_barrier_wait_end): Rewritten. - (gomp_barrier_wait_last): New function. - -2008-03-15 Jakub Jelinek - - * team.c (gomp_thread_start): Use gomp_barrier_wait_last instead - of gomp_barrier_wait. - * env.c (gomp_block_time_var, gomp_spin_count_var): New variables. - (parse_millis): New function. - (initialize_env): Handle GOMP_BLOCKTIME env var. - * libgomp.h (struct gomp_team): Move close to the end of the struct. - (gomp_spin_count_var): New extern var decl. - * work.c (gomp_work_share_end): Use gomp_barrier_state_t bstate - var instead of bool last, call gomp_barrier_last_thread to check - for last thread, pass bstate to gomp_barrier_wait_end. - * config/linux/wait.h: New file. - * config/linux/mutex.c: Include wait.h instead of libgomp.h and - futex.h. - (gomp_mutex_lock_slow): Call do_wait instead of futex_wait. - * config/linux/bar.c: Include wait.h instead of libgomp.h and - futex.h. - (gomp_barrier_wait_end): Change second argument to - gomp_barrier_state_t. Call do_wait instead of futex_wait. - * config/linux/sem.c: Include wait.h instead of libgomp.h and - futex.h. - (gomp_sem_wait_slow): Call do_wait instead of futex_wait. - * config/linux/lock.c: Include wait.h instead of libgomp.h and - futex.h. - (gomp_set_nest_lock_25): Call do_wait instead of futex_wait. - * config/linux/affinity.c: Assume HAVE_SYNC_BUILTINS. - * config/linux/bar.h (gomp_barrier_state_t): New typedef. - (gomp_barrier_wait_end): Change second argument to - gomp_barrier_state_t. - (gomp_barrier_wait_start): Return gomp_barrier_state_t. - (gomp_barrier_last_thread, gomp_barrier_wait_last): New static - inlines. - * config/linux/powerpc/futex.h (cpu_relax, atomic_write_barrier): New - static inlines. - * config/linux/alpha/futex.h (cpu_relax, atomic_write_barrier): - Likewise. - * config/linux/x86/futex.h (cpu_relax, atomic_write_barrier): - Likewise. - * config/linux/s390/futex.h (cpu_relax, atomic_write_barrier): - Likewise. - * config/linux/ia64/futex.h (cpu_relax, atomic_write_barrier): - Likewise. - * config/linux/sparc/futex.h (cpu_relax, atomic_write_barrier): - Likewise. - * config/posix/bar.c (gomp_barrier_wait_end): Change second argument - to gomp_barrier_state_t. - * config/posix/bar.h (gomp_barrier_state_t): New typedef. - (gomp_barrier_wait_end): Change second argument to - gomp_barrier_state_t. - (gomp_barrier_wait_start): Return gomp_barrier_state_t. - (gomp_barrier_last_thread, gomp_barrier_wait_last): New static - inlines. - ---- libgomp/parallel.c.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/parallel.c 2008-03-26 15:32:06.000000000 +0100 -@@ -68,7 +68,7 @@ void - GOMP_parallel_start (void (*fn) (void *), void *data, unsigned num_threads) - { - num_threads = gomp_resolve_num_threads (num_threads); -- gomp_team_start (fn, data, num_threads, NULL); -+ gomp_team_start (fn, data, num_threads, gomp_new_team (num_threads)); - } - - void ---- libgomp/sections.c.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/sections.c 2008-03-26 15:33:06.000000000 +0100 -@@ -59,14 +59,24 @@ GOMP_sections_start (unsigned count) - long s, e, ret; - - if (gomp_work_share_start (false)) -- gomp_sections_init (thr->ts.work_share, count); -+ { -+ gomp_sections_init (thr->ts.work_share, count); -+ gomp_work_share_init_done (); -+ } - -+#ifdef HAVE_SYNC_BUILTINS -+ if (gomp_iter_dynamic_next (&s, &e)) -+ ret = s; -+ else -+ ret = 0; -+#else -+ gomp_mutex_lock (&thr->ts.work_share->lock); - if (gomp_iter_dynamic_next_locked (&s, &e)) - ret = s; - else - ret = 0; -- - gomp_mutex_unlock (&thr->ts.work_share->lock); -+#endif - - return ret; - } -@@ -83,15 +93,23 @@ GOMP_sections_start (unsigned count) - unsigned - GOMP_sections_next (void) - { -- struct gomp_thread *thr = gomp_thread (); - long s, e, ret; - -+#ifdef HAVE_SYNC_BUILTINS -+ if (gomp_iter_dynamic_next (&s, &e)) -+ ret = s; -+ else -+ ret = 0; -+#else -+ struct gomp_thread *thr = gomp_thread (); -+ - gomp_mutex_lock (&thr->ts.work_share->lock); - if (gomp_iter_dynamic_next_locked (&s, &e)) - ret = s; - else - ret = 0; - gomp_mutex_unlock (&thr->ts.work_share->lock); -+#endif - - return ret; - } -@@ -103,15 +121,15 @@ void - GOMP_parallel_sections_start (void (*fn) (void *), void *data, - unsigned num_threads, unsigned count) - { -- struct gomp_work_share *ws; -+ struct gomp_team *team; - - num_threads = gomp_resolve_num_threads (num_threads); - if (gomp_dyn_var && num_threads > count) - num_threads = count; - -- ws = gomp_new_work_share (false, num_threads); -- gomp_sections_init (ws, count); -- gomp_team_start (fn, data, num_threads, ws); -+ team = gomp_new_team (num_threads); -+ gomp_sections_init (&team->work_shares[0], count); -+ gomp_team_start (fn, data, num_threads, team); - } - - /* The GOMP_section_end* routines are called after the thread is told ---- libgomp/env.c.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/env.c 2008-03-26 16:40:26.000000000 +0100 -@@ -44,6 +44,11 @@ enum gomp_schedule_type gomp_run_sched_v - unsigned long gomp_run_sched_chunk = 1; - unsigned short *gomp_cpu_affinity; - size_t gomp_cpu_affinity_len; -+#ifndef HAVE_SYNC_BUILTINS -+gomp_mutex_t gomp_remaining_threads_lock; -+#endif -+unsigned long gomp_available_cpus = 1, gomp_managed_threads = 1; -+unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var; - - /* Parse the OMP_SCHEDULE environment variable. */ - -@@ -147,6 +152,79 @@ parse_unsigned_long (const char *name, u - return false; - } - -+/* Parse the GOMP_SPINCOUNT environment varible. Return true if one was -+ present and it was successfully parsed. */ -+ -+static bool -+parse_spincount (const char *name, unsigned long long *pvalue) -+{ -+ char *env, *end; -+ unsigned long long value, mult = 1; -+ -+ env = getenv (name); -+ if (env == NULL) -+ return false; -+ -+ while (isspace ((unsigned char) *env)) -+ ++env; -+ if (*env == '\0') -+ goto invalid; -+ -+ if (strncasecmp (env, "infinite", 8) == 0 -+ || strncasecmp (env, "infinity", 8) == 0) -+ { -+ value = ~0ULL; -+ end = env + 8; -+ goto check_tail; -+ } -+ -+ errno = 0; -+ value = strtoull (env, &end, 10); -+ if (errno) -+ goto invalid; -+ -+ while (isspace ((unsigned char) *end)) -+ ++end; -+ if (*end != '\0') -+ { -+ switch (tolower (*end)) -+ { -+ case 'k': -+ mult = 1000LL; -+ break; -+ case 'm': -+ mult = 1000LL * 1000LL; -+ break; -+ case 'g': -+ mult = 1000LL * 1000LL * 1000LL; -+ break; -+ case 't': -+ mult = 1000LL * 1000LL * 1000LL * 1000LL; -+ break; -+ default: -+ goto invalid; -+ } -+ ++end; -+ check_tail: -+ while (isspace ((unsigned char) *end)) -+ ++end; -+ if (*end != '\0') -+ goto invalid; -+ } -+ -+ if (value > ~0ULL / mult) -+ value = ~0ULL; -+ else -+ value *= mult; -+ -+ *pvalue = value; -+ return true; -+ -+ invalid: -+ gomp_error ("Invalid value for environment variable %s", name); -+ return false; -+} -+ - /* Parse a boolean value for environment variable NAME and store the - result in VALUE. */ - -@@ -281,10 +359,25 @@ initialize_env (void) - parse_schedule (); - parse_boolean ("OMP_DYNAMIC", &gomp_dyn_var); - parse_boolean ("OMP_NESTED", &gomp_nest_var); -+ gomp_init_num_threads (); -+ gomp_available_cpus = gomp_nthreads_var; - if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_nthreads_var)) -- gomp_init_num_threads (); -+ gomp_nthreads_var = gomp_available_cpus; - if (parse_affinity ()) - gomp_init_affinity (); -+ if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var)) -+ { -+ /* Using a rough estimation of 100000 spins per msec, -+ use 200 msec blocking. -+ Depending on the CPU speed, this can be e.g. 5 times longer -+ or 5 times shorter. */ -+ gomp_spin_count_var = 20000000LL; -+ } -+ /* gomp_throttled_spin_count_var is used when there are more libgomp -+ managed threads than available CPUs. Use very short spinning. */ -+ gomp_throttled_spin_count_var = 100LL; -+ if (gomp_throttled_spin_count_var > gomp_spin_count_var) -+ gomp_throttled_spin_count_var = gomp_spin_count_var; - - /* Not strictly environment related, but ordering constructors is tricky. */ - pthread_attr_init (&gomp_thread_attr); ---- libgomp/libgomp.h.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/libgomp.h 2008-03-27 12:21:51.000000000 +0100 -@@ -50,6 +50,7 @@ - #include "sem.h" - #include "mutex.h" - #include "bar.h" -+#include "ptrlock.h" - - - /* This structure contains the data to control one work-sharing construct, -@@ -70,6 +71,8 @@ struct gomp_work_share - If this is a SECTIONS construct, this value will always be DYNAMIC. */ - enum gomp_schedule_type sched; - -+ int mode; -+ - /* This is the chunk_size argument to the SCHEDULE clause. */ - long chunk_size; - -@@ -81,17 +84,38 @@ struct gomp_work_share - is always 1. */ - long incr; - -- /* This lock protects the update of the following members. */ -- gomp_mutex_t lock; -+ /* This is a circular queue that details which threads will be allowed -+ into the ordered region and in which order. When a thread allocates -+ iterations on which it is going to work, it also registers itself at -+ the end of the array. When a thread reaches the ordered region, it -+ checks to see if it is the one at the head of the queue. If not, it -+ blocks on its RELEASE semaphore. */ -+ unsigned *ordered_team_ids; - -- union { -- /* This is the next iteration value to be allocated. In the case of -- GFS_STATIC loops, this the iteration start point and never changes. */ -- long next; -+ /* This is the number of threads that have registered themselves in -+ the circular queue ordered_team_ids. */ -+ unsigned ordered_num_used; - -- /* This is the returned data structure for SINGLE COPYPRIVATE. */ -- void *copyprivate; -- }; -+ /* This is the team_id of the currently acknowledged owner of the ordered -+ section, or -1u if the ordered section has not been acknowledged by -+ any thread. This is distinguished from the thread that is *allowed* -+ to take the section next. */ -+ unsigned ordered_owner; -+ -+ /* This is the index into the circular queue ordered_team_ids of the -+ current thread that's allowed into the ordered reason. */ -+ unsigned ordered_cur; -+ -+ /* This is a chain of allocated gomp_work_share blocks, valid only -+ in the first gomp_work_share struct in the block. */ -+ struct gomp_work_share *next_alloc; -+ -+ /* The above fields are written once during workshare initialization, -+ or related to ordered worksharing. Make sure the following fields -+ are in a different cache line. */ -+ -+ /* This lock protects the update of the following members. */ -+ gomp_mutex_t lock __attribute__((aligned (64))); - - /* This is the count of the number of threads that have exited the work - share construct. If the construct was marked nowait, they have moved on -@@ -99,27 +123,28 @@ struct gomp_work_share - of the team to exit the work share construct must deallocate it. */ - unsigned threads_completed; - -- /* This is the index into the circular queue ordered_team_ids of the -- current thread that's allowed into the ordered reason. */ -- unsigned ordered_cur; -+ union { -+ /* This is the next iteration value to be allocated. In the case of -+ GFS_STATIC loops, this the iteration start point and never changes. */ -+ long next; - -- /* This is the number of threads that have registered themselves in -- the circular queue ordered_team_ids. */ -- unsigned ordered_num_used; -+ /* This is the returned data structure for SINGLE COPYPRIVATE. */ -+ void *copyprivate; -+ }; - -- /* This is the team_id of the currently acknoledged owner of the ordered -- section, or -1u if the ordered section has not been acknowledged by -- any thread. This is distinguished from the thread that is *allowed* -- to take the section next. */ -- unsigned ordered_owner; -+ union { -+ /* Link to gomp_work_share struct for next work sharing construct -+ encountered after this one. */ -+ gomp_ptrlock_t next_ws; -+ -+ /* gomp_work_share structs are chained in the free work share cache -+ through this. */ -+ struct gomp_work_share *next_free; -+ }; - -- /* This is a circular queue that details which threads will be allowed -- into the ordered region and in which order. When a thread allocates -- iterations on which it is going to work, it also registers itself at -- the end of the array. When a thread reaches the ordered region, it -- checks to see if it is the one at the head of the queue. If not, it -- blocks on its RELEASE semaphore. */ -- unsigned ordered_team_ids[]; -+ /* If only few threads are in the team, ordered_team_ids can point -+ to this array which fills the padding at the end of this struct. */ -+ unsigned inline_ordered_team_ids[0]; - }; - - /* This structure contains all of the thread-local data associated with -@@ -133,21 +158,24 @@ struct gomp_team_state - - /* This is the work share construct which this thread is currently - processing. Recall that with NOWAIT, not all threads may be -- processing the same construct. This value is NULL when there -- is no construct being processed. */ -+ processing the same construct. */ - struct gomp_work_share *work_share; - -+ /* This is the previous work share construct or NULL if there wasn't any. -+ When all threads are done with the current work sharing construct, -+ the previous one can be freed. The current one can't, as its -+ next_ws field is used. */ -+ struct gomp_work_share *last_work_share; -+ - /* This is the ID of this thread within the team. This value is - guaranteed to be between 0 and N-1, where N is the number of - threads in the team. */ - unsigned team_id; - -- /* The work share "generation" is a number that increases by one for -- each work share construct encountered in the dynamic flow of the -- program. It is used to find the control data for the work share -- when encountering it for the first time. This particular number -- reflects the generation of the work_share member of this struct. */ -- unsigned work_share_generation; -+#ifdef HAVE_SYNC_BUILTINS -+ /* Number of single stmts encountered. */ -+ unsigned long single_count; -+#endif - - /* For GFS_RUNTIME loops that resolved to GFS_STATIC, this is the - trip number through the loop. So first time a particular loop -@@ -163,41 +191,53 @@ struct gomp_team_state - - struct gomp_team - { -- /* This lock protects access to the following work shares data structures. */ -- gomp_mutex_t work_share_lock; -- -- /* This is a dynamically sized array containing pointers to the control -- structs for all "live" work share constructs. Here "live" means that -- the construct has been encountered by at least one thread, and not -- completed by all threads. */ -- struct gomp_work_share **work_shares; -- -- /* The work_shares array is indexed by "generation & generation_mask". -- The mask will be 2**N - 1, where 2**N is the size of the array. */ -- unsigned generation_mask; -- -- /* These two values define the bounds of the elements of the work_shares -- array that are currently in use. */ -- unsigned oldest_live_gen; -- unsigned num_live_gen; -- - /* This is the number of threads in the current team. */ - unsigned nthreads; - -+ /* This is number of gomp_work_share structs that have been allocated -+ as a block last time. */ -+ unsigned work_share_chunk; -+ - /* This is the saved team state that applied to a master thread before - the current thread was created. */ - struct gomp_team_state prev_ts; - -- /* This barrier is used for most synchronization of the team. */ -- gomp_barrier_t barrier; -- - /* This semaphore should be used by the master thread instead of its - "native" semaphore in the thread structure. Required for nested - parallels, as the master is a member of two teams. */ - gomp_sem_t master_release; - -- /* This array contains pointers to the release semaphore of the threads -- in the team. */ -+ /* List of gomp_work_share structs chained through next_free fields. -+ This is populated and taken off only by the first thread in the -+ team encountering a new work sharing construct, in a critical -+ section. */ -+ struct gomp_work_share *work_share_list_alloc; -+ -+ /* List of gomp_work_share structs freed by free_work_share. New -+ entries are atomically added to the start of the list, and -+ alloc_work_share can safely only move all but the first entry -+ to work_share_list alloc, as free_work_share can happen concurrently -+ with alloc_work_share. */ -+ struct gomp_work_share *work_share_list_free; -+ -+#ifdef HAVE_SYNC_BUILTINS -+ /* Number of simple single regions encountered by threads in this -+ team. */ -+ 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. */ -+ gomp_barrier_t barrier; -+ -+ /* Initial work shares, to avoid allocating any gomp_work_share -+ structs in the common case. */ -+ struct gomp_work_share work_shares[8]; -+ -+ /* This is an array with pointers to the release semaphore -+ of the threads in the team. */ - gomp_sem_t *ordered_release[]; - }; - -@@ -242,6 +282,11 @@ extern bool gomp_dyn_var; - extern bool gomp_nest_var; - extern enum gomp_schedule_type gomp_run_sched_var; - extern unsigned long gomp_run_sched_chunk; -+#ifndef HAVE_SYNC_BUILTINS -+extern gomp_mutex_t gomp_remaining_threads_lock; -+#endif -+extern unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var; -+extern unsigned long gomp_available_cpus, gomp_managed_threads; - - /* The attributes to be used during thread creation. */ - extern pthread_attr_t gomp_thread_attr; -@@ -306,17 +351,27 @@ extern unsigned gomp_dynamic_max_threads - - /* team.c */ - -+extern struct gomp_team *gomp_new_team (unsigned); - extern void gomp_team_start (void (*) (void *), void *, unsigned, -- struct gomp_work_share *); -+ struct gomp_team *); - extern void gomp_team_end (void); - - /* work.c */ - --extern struct gomp_work_share * gomp_new_work_share (bool, unsigned); -+extern void gomp_init_work_share (struct gomp_work_share *, bool, unsigned); -+extern void gomp_fini_work_share (struct gomp_work_share *); - extern bool gomp_work_share_start (bool); - extern void gomp_work_share_end (void); - extern void gomp_work_share_end_nowait (void); - -+static inline void -+gomp_work_share_init_done (void) -+{ -+ struct gomp_thread *thr = gomp_thread (); -+ if (__builtin_expect (thr->ts.last_work_share != NULL, 1)) -+ gomp_ptrlock_set (&thr->ts.last_work_share->next_ws, thr->ts.work_share); -+} -+ - #ifdef HAVE_ATTRIBUTE_VISIBILITY - # pragma GCC visibility pop - #endif ---- libgomp/iter.c.jj 2008-03-26 14:48:34.000000000 +0100 -+++ libgomp/iter.c 2008-03-26 15:11:23.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -154,7 +154,7 @@ gomp_iter_dynamic_next_locked (long *pst - if (start == ws->end) - return false; - -- chunk = ws->chunk_size * ws->incr; -+ chunk = ws->chunk_size; - left = ws->end - start; - if (ws->incr < 0) - { -@@ -186,11 +186,38 @@ gomp_iter_dynamic_next (long *pstart, lo - struct gomp_work_share *ws = thr->ts.work_share; - long start, end, nend, chunk, incr; - -- start = ws->next; - end = ws->end; - incr = ws->incr; -- chunk = ws->chunk_size * incr; -+ chunk = ws->chunk_size; -+ -+ if (__builtin_expect (ws->mode, 1)) -+ { -+ long tmp = __sync_fetch_and_add (&ws->next, chunk); -+ if (incr > 0) -+ { -+ if (tmp >= end) -+ return false; -+ nend = tmp + chunk; -+ if (nend > end) -+ nend = end; -+ *pstart = tmp; -+ *pend = nend; -+ return true; -+ } -+ else -+ { -+ if (tmp <= end) -+ return false; -+ nend = tmp + chunk; -+ if (nend < end) -+ nend = end; -+ *pstart = tmp; -+ *pend = nend; -+ return true; -+ } -+ } - -+ start = ws->next; - while (1) - { - long left = end - start; ---- libgomp/work.c.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/work.c 2008-03-27 12:21:51.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -29,39 +29,138 @@ - of threads. */ - - #include "libgomp.h" -+#include - #include - #include - - --/* Create a new work share structure. */ -+/* Allocate a new work share structure, preferably from current team's -+ free gomp_work_share cache. */ - --struct gomp_work_share * --gomp_new_work_share (bool ordered, unsigned nthreads) -+static struct gomp_work_share * -+alloc_work_share (struct gomp_team *team) - { - struct gomp_work_share *ws; -- size_t size; -+ unsigned int i; - -- size = sizeof (*ws); -- if (ordered) -- size += nthreads * sizeof (ws->ordered_team_ids[0]); -+ /* This is called in a critical section. */ -+ if (team->work_share_list_alloc != NULL) -+ { -+ ws = team->work_share_list_alloc; -+ team->work_share_list_alloc = ws->next_free; -+ return ws; -+ } - -- ws = gomp_malloc_cleared (size); -- gomp_mutex_init (&ws->lock); -- ws->ordered_owner = -1; -+#ifdef HAVE_SYNC_BUILTINS -+ ws = team->work_share_list_free; -+ /* We need atomic read from work_share_list_free, -+ as free_work_share can be called concurrently. */ -+ __asm ("" : "+r" (ws)); -+ -+ if (ws && ws->next_free) -+ { -+ struct gomp_work_share *next = ws->next_free; -+ ws->next_free = NULL; -+ team->work_share_list_alloc = next->next_free; -+ 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; -+ ws = gomp_malloc (team->work_share_chunk * sizeof (struct gomp_work_share)); -+ ws->next_alloc = team->work_shares[0].next_alloc; -+ team->work_shares[0].next_alloc = ws; -+ team->work_share_list_alloc = &ws[1]; -+ for (i = 1; i < team->work_share_chunk - 1; i++) -+ ws[i].next_free = &ws[i + 1]; -+ ws[i].next_free = NULL; - return ws; - } - -+/* Initialize an already allocated struct gomp_work_share. -+ This shouldn't touch the next_alloc field. */ -+ -+void -+gomp_init_work_share (struct gomp_work_share *ws, bool ordered, -+ unsigned nthreads) -+{ -+ gomp_mutex_init (&ws->lock); -+ if (__builtin_expect (ordered, 0)) -+ { -+#define INLINE_ORDERED_TEAM_IDS_CNT \ -+ ((sizeof (struct gomp_work_share) \ -+ - offsetof (struct gomp_work_share, inline_ordered_team_ids)) \ -+ / sizeof (((struct gomp_work_share *) 0)->inline_ordered_team_ids[0])) -+ -+ if (nthreads > INLINE_ORDERED_TEAM_IDS_CNT) -+ ws->ordered_team_ids -+ = gomp_malloc (nthreads * sizeof (*ws->ordered_team_ids)); -+ else -+ ws->ordered_team_ids = ws->inline_ordered_team_ids; -+ memset (ws->ordered_team_ids, '\0', -+ nthreads * sizeof (*ws->ordered_team_ids)); -+ ws->ordered_num_used = 0; -+ ws->ordered_owner = -1; -+ ws->ordered_cur = 0; -+ } -+ else -+ ws->ordered_team_ids = NULL; -+ gomp_ptrlock_init (&ws->next_ws, NULL); -+ ws->threads_completed = 0; -+} - --/* Free a work share structure. */ -+/* Do any needed destruction of gomp_work_share fields before it -+ is put back into free gomp_work_share cache or freed. */ - --static void --free_work_share (struct gomp_work_share *ws) -+void -+gomp_fini_work_share (struct gomp_work_share *ws) - { - gomp_mutex_destroy (&ws->lock); -- free (ws); -+ if (ws->ordered_team_ids != ws->inline_ordered_team_ids) -+ free (ws->ordered_team_ids); -+ gomp_ptrlock_destroy (&ws->next_ws); - } - -+/* Free a work share struct, if not orphaned, put it into current -+ team's free gomp_work_share cache. */ -+ -+static inline void -+free_work_share (struct gomp_team *team, struct gomp_work_share *ws) -+{ -+ gomp_fini_work_share (ws); -+ if (__builtin_expect (team == NULL, 0)) -+ free (ws); -+ else -+ { -+ struct gomp_work_share *next_ws; -+#ifdef HAVE_SYNC_BUILTINS -+ do -+ { -+ next_ws = team->work_share_list_free; -+ ws->next_free = next_ws; -+ } -+ while (!__sync_bool_compare_and_swap (&team->work_share_list_free, -+ 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. - In all cases, thr->ts.work_share is updated to point to the new -@@ -74,71 +173,34 @@ gomp_work_share_start (bool ordered) - struct gomp_thread *thr = gomp_thread (); - struct gomp_team *team = thr->ts.team; - struct gomp_work_share *ws; -- unsigned ws_index, ws_gen; - - /* Work sharing constructs can be orphaned. */ - if (team == NULL) - { -- ws = gomp_new_work_share (ordered, 1); -+ ws = gomp_malloc (sizeof (*ws)); -+ gomp_init_work_share (ws, ordered, 1); - thr->ts.work_share = ws; -- thr->ts.static_trip = 0; -- gomp_mutex_lock (&ws->lock); -- return true; -+ return ws; - } - -- gomp_mutex_lock (&team->work_share_lock); -- -- /* This thread is beginning its next generation. */ -- ws_gen = ++thr->ts.work_share_generation; -- -- /* If this next generation is not newer than any other generation in -- the team, then simply reference the existing construct. */ -- if (ws_gen - team->oldest_live_gen < team->num_live_gen) -+ ws = thr->ts.work_share; -+ thr->ts.last_work_share = ws; -+ ws = gomp_ptrlock_get (&ws->next_ws); -+ if (ws == NULL) - { -- ws_index = ws_gen & team->generation_mask; -- ws = team->work_shares[ws_index]; -+ /* This thread encountered a new ws first. */ -+ struct gomp_work_share *ws = alloc_work_share (team); -+ gomp_init_work_share (ws, ordered, team->nthreads); - thr->ts.work_share = ws; -- thr->ts.static_trip = 0; -- -- gomp_mutex_lock (&ws->lock); -- gomp_mutex_unlock (&team->work_share_lock); -- -- return false; -+ return true; - } -- -- /* Resize the work shares queue if we've run out of space. */ -- if (team->num_live_gen++ == team->generation_mask) -+ else - { -- team->work_shares = gomp_realloc (team->work_shares, -- 2 * team->num_live_gen -- * sizeof (*team->work_shares)); -- -- /* Unless oldest_live_gen is zero, the sequence of live elements -- wraps around the end of the array. If we do nothing, we break -- lookup of the existing elements. Fix that by unwrapping the -- data from the front to the end. */ -- if (team->oldest_live_gen > 0) -- memcpy (team->work_shares + team->num_live_gen, -- team->work_shares, -- (team->oldest_live_gen & team->generation_mask) -- * sizeof (*team->work_shares)); -- -- team->generation_mask = team->generation_mask * 2 + 1; -- } -- -- ws_index = ws_gen & team->generation_mask; -- ws = gomp_new_work_share (ordered, team->nthreads); -- thr->ts.work_share = ws; -- thr->ts.static_trip = 0; -- team->work_shares[ws_index] = ws; -- -- gomp_mutex_lock (&ws->lock); -- gomp_mutex_unlock (&team->work_share_lock); -- -- return true; -+ thr->ts.work_share = ws; -+ return false; -+ } - } - -- - /* The current thread is done with its current work sharing construct. - This version does imply a barrier at the end of the work-share. */ - -@@ -147,36 +209,28 @@ gomp_work_share_end (void) - { - struct gomp_thread *thr = gomp_thread (); - struct gomp_team *team = thr->ts.team; -- struct gomp_work_share *ws = thr->ts.work_share; -- bool last; -- -- thr->ts.work_share = NULL; -+ gomp_barrier_state_t bstate; - - /* Work sharing constructs can be orphaned. */ - if (team == NULL) - { -- free_work_share (ws); -+ free_work_share (NULL, thr->ts.work_share); -+ thr->ts.work_share = NULL; - return; - } - -- last = gomp_barrier_wait_start (&team->barrier); -+ bstate = gomp_barrier_wait_start (&team->barrier); - -- if (last) -+ if (gomp_barrier_last_thread (bstate)) - { -- unsigned ws_index; -- -- ws_index = thr->ts.work_share_generation & team->generation_mask; -- team->work_shares[ws_index] = NULL; -- team->oldest_live_gen++; -- team->num_live_gen = 0; -- -- free_work_share (ws); -+ if (__builtin_expect (thr->ts.last_work_share != NULL, 1)) -+ free_work_share (team, thr->ts.last_work_share); - } - -- gomp_barrier_wait_end (&team->barrier, last); -+ gomp_barrier_wait_end (&team->barrier, bstate); -+ thr->ts.last_work_share = NULL; - } - -- - /* 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. */ - -@@ -188,15 +242,17 @@ gomp_work_share_end_nowait (void) - struct gomp_work_share *ws = thr->ts.work_share; - unsigned completed; - -- thr->ts.work_share = NULL; -- - /* Work sharing constructs can be orphaned. */ - if (team == NULL) - { -- free_work_share (ws); -+ free_work_share (NULL, ws); -+ thr->ts.work_share = NULL; - return; - } - -+ if (__builtin_expect (thr->ts.last_work_share == NULL, 0)) -+ return; -+ - #ifdef HAVE_SYNC_BUILTINS - completed = __sync_add_and_fetch (&ws->threads_completed, 1); - #else -@@ -206,18 +262,6 @@ gomp_work_share_end_nowait (void) - #endif - - if (completed == team->nthreads) -- { -- unsigned ws_index; -- -- gomp_mutex_lock (&team->work_share_lock); -- -- ws_index = thr->ts.work_share_generation & team->generation_mask; -- team->work_shares[ws_index] = NULL; -- team->oldest_live_gen++; -- team->num_live_gen--; -- -- gomp_mutex_unlock (&team->work_share_lock); -- -- free_work_share (ws); -- } -+ free_work_share (team, thr->ts.last_work_share); -+ thr->ts.last_work_share = NULL; - } ---- libgomp/single.c.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/single.c 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -37,10 +37,24 @@ - bool - GOMP_single_start (void) - { -+#ifdef HAVE_SYNC_BUILTINS -+ struct gomp_thread *thr = gomp_thread (); -+ struct gomp_team *team = thr->ts.team; -+ unsigned long single_count; -+ -+ if (__builtin_expect (team == NULL, 0)) -+ return true; -+ -+ single_count = thr->ts.single_count++; -+ return __sync_bool_compare_and_swap (&team->single_count, single_count, -+ single_count + 1L); -+#else - bool ret = gomp_work_share_start (false); -- gomp_mutex_unlock (&gomp_thread ()->ts.work_share->lock); -+ if (ret) -+ gomp_work_share_init_done (); - gomp_work_share_end_nowait (); - return ret; -+#endif - } - - /* This routine is called when first encountering a SINGLE construct that -@@ -57,10 +71,12 @@ GOMP_single_copy_start (void) - void *ret; - - first = gomp_work_share_start (false); -- gomp_mutex_unlock (&thr->ts.work_share->lock); - - if (first) -- ret = NULL; -+ { -+ gomp_work_share_init_done (); -+ ret = NULL; -+ } - else - { - gomp_barrier_wait (&thr->ts.team->barrier); ---- libgomp/loop.c.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/loop.c 2008-03-26 18:47:04.000000000 +0100 -@@ -27,8 +27,9 @@ - - /* This file handles the LOOP (FOR/DO) construct. */ - --#include "libgomp.h" -+#include - #include -+#include "libgomp.h" - - - /* Initialize the given work share construct from the given arguments. */ -@@ -44,6 +45,39 @@ gomp_loop_init (struct gomp_work_share * - ? start : end; - ws->incr = incr; - ws->next = start; -+ if (sched == GFS_DYNAMIC) -+ { -+ ws->chunk_size *= incr; -+ -+#ifdef HAVE_SYNC_BUILTINS -+ { -+ /* For dynamic scheduling prepare things to make each iteration -+ faster. */ -+ struct gomp_thread *thr = gomp_thread (); -+ struct gomp_team *team = thr->ts.team; -+ long nthreads = team ? team->nthreads : 1; -+ -+ if (__builtin_expect (incr > 0, 1)) -+ { -+ /* Cheap overflow protection. */ -+ if (__builtin_expect ((nthreads | ws->chunk_size) -+ >= 1UL << (sizeof (long) -+ * __CHAR_BIT__ / 2 - 1), 0)) -+ ws->mode = 0; -+ else -+ ws->mode = ws->end < (LONG_MAX -+ - (nthreads + 1) * ws->chunk_size); -+ } -+ /* Cheap overflow protection. */ -+ else if (__builtin_expect ((nthreads | -ws->chunk_size) -+ >= 1UL << (sizeof (long) -+ * __CHAR_BIT__ / 2 - 1), 0)) -+ ws->mode = 0; -+ else -+ ws->mode = ws->end > (nthreads + 1) * -ws->chunk_size - LONG_MAX; -+ } -+#endif -+ } - } - - /* The *_start routines are called when first encountering a loop construct -@@ -68,10 +102,13 @@ gomp_loop_static_start (long start, long - { - struct gomp_thread *thr = gomp_thread (); - -+ thr->ts.static_trip = 0; - if (gomp_work_share_start (false)) -- gomp_loop_init (thr->ts.work_share, start, end, incr, -- GFS_STATIC, chunk_size); -- gomp_mutex_unlock (&thr->ts.work_share->lock); -+ { -+ gomp_loop_init (thr->ts.work_share, start, end, incr, -+ GFS_STATIC, chunk_size); -+ gomp_work_share_init_done (); -+ } - - return !gomp_iter_static_next (istart, iend); - } -@@ -84,13 +121,16 @@ gomp_loop_dynamic_start (long start, lon - bool ret; - - if (gomp_work_share_start (false)) -- gomp_loop_init (thr->ts.work_share, start, end, incr, -- GFS_DYNAMIC, chunk_size); -+ { -+ gomp_loop_init (thr->ts.work_share, start, end, incr, -+ GFS_DYNAMIC, chunk_size); -+ gomp_work_share_init_done (); -+ } - - #ifdef HAVE_SYNC_BUILTINS -- gomp_mutex_unlock (&thr->ts.work_share->lock); - ret = gomp_iter_dynamic_next (istart, iend); - #else -+ gomp_mutex_lock (&thr->ts.work_share->lock); - ret = gomp_iter_dynamic_next_locked (istart, iend); - gomp_mutex_unlock (&thr->ts.work_share->lock); - #endif -@@ -106,13 +146,16 @@ gomp_loop_guided_start (long start, long - bool ret; - - if (gomp_work_share_start (false)) -- gomp_loop_init (thr->ts.work_share, start, end, incr, -- GFS_GUIDED, chunk_size); -+ { -+ gomp_loop_init (thr->ts.work_share, start, end, incr, -+ GFS_GUIDED, chunk_size); -+ gomp_work_share_init_done (); -+ } - - #ifdef HAVE_SYNC_BUILTINS -- gomp_mutex_unlock (&thr->ts.work_share->lock); - ret = gomp_iter_guided_next (istart, iend); - #else -+ gomp_mutex_lock (&thr->ts.work_share->lock); - ret = gomp_iter_guided_next_locked (istart, iend); - gomp_mutex_unlock (&thr->ts.work_share->lock); - #endif -@@ -149,13 +192,14 @@ gomp_loop_ordered_static_start (long sta - { - struct gomp_thread *thr = gomp_thread (); - -+ thr->ts.static_trip = 0; - if (gomp_work_share_start (true)) - { - gomp_loop_init (thr->ts.work_share, start, end, incr, - GFS_STATIC, chunk_size); - gomp_ordered_static_init (); -+ gomp_work_share_init_done (); - } -- gomp_mutex_unlock (&thr->ts.work_share->lock); - - return !gomp_iter_static_next (istart, iend); - } -@@ -168,8 +212,14 @@ gomp_loop_ordered_dynamic_start (long st - bool ret; - - if (gomp_work_share_start (true)) -- gomp_loop_init (thr->ts.work_share, start, end, incr, -- GFS_DYNAMIC, chunk_size); -+ { -+ gomp_loop_init (thr->ts.work_share, start, end, incr, -+ GFS_DYNAMIC, chunk_size); -+ gomp_mutex_lock (&thr->ts.work_share->lock); -+ gomp_work_share_init_done (); -+ } -+ else -+ gomp_mutex_lock (&thr->ts.work_share->lock); - - ret = gomp_iter_dynamic_next_locked (istart, iend); - if (ret) -@@ -187,8 +237,14 @@ gomp_loop_ordered_guided_start (long sta - bool ret; - - if (gomp_work_share_start (true)) -- gomp_loop_init (thr->ts.work_share, start, end, incr, -- GFS_GUIDED, chunk_size); -+ { -+ gomp_loop_init (thr->ts.work_share, start, end, incr, -+ GFS_GUIDED, chunk_size); -+ gomp_mutex_lock (&thr->ts.work_share->lock); -+ gomp_work_share_init_done (); -+ } -+ else -+ gomp_mutex_lock (&thr->ts.work_share->lock); - - ret = gomp_iter_guided_next_locked (istart, iend); - if (ret) -@@ -375,12 +431,12 @@ gomp_parallel_loop_start (void (*fn) (vo - long incr, enum gomp_schedule_type sched, - long chunk_size) - { -- struct gomp_work_share *ws; -+ struct gomp_team *team; - - num_threads = gomp_resolve_num_threads (num_threads); -- ws = gomp_new_work_share (false, num_threads); -- gomp_loop_init (ws, start, end, incr, sched, chunk_size); -- gomp_team_start (fn, data, num_threads, ws); -+ team = gomp_new_team (num_threads); -+ gomp_loop_init (&team->work_shares[0], start, end, incr, sched, chunk_size); -+ gomp_team_start (fn, data, num_threads, team); - } - - void ---- libgomp/Makefile.in.jj 2008-01-10 20:53:47.000000000 +0100 -+++ libgomp/Makefile.in 2008-03-26 18:51:01.000000000 +0100 -@@ -83,7 +83,7 @@ libgomp_la_LIBADD = - am_libgomp_la_OBJECTS = alloc.lo barrier.lo critical.lo env.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 \ -- bar.lo time.lo fortran.lo affinity.lo -+ bar.lo ptrlock.lo time.lo fortran.lo affinity.lo - libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS) - DEFAULT_INCLUDES = -I. -I$(srcdir) -I. - depcomp = $(SHELL) $(top_srcdir)/../depcomp -@@ -292,7 +292,7 @@ libgomp_version_info = -version-info $(l - libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) - 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 \ -- lock.c mutex.c proc.c sem.c bar.c time.c fortran.c affinity.c -+ lock.c mutex.c proc.c sem.c bar.c ptrlock.c time.c fortran.c affinity.c - - nodist_noinst_HEADERS = libgomp_f.h - nodist_libsubinclude_HEADERS = omp.h -@@ -434,6 +434,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ordered.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parallel.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Plo@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptrlock.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sections.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sem.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/single.Plo@am__quote@ ---- libgomp/testsuite/libgomp.c/loop-4.c.jj 2008-03-26 18:47:04.000000000 +0100 -+++ libgomp/testsuite/libgomp.c/loop-4.c 2008-03-26 18:47:04.000000000 +0100 -@@ -0,0 +1,28 @@ -+/* { dg-do run } */ -+ -+extern void abort (void); -+ -+int -+main (void) -+{ -+ int e = 0; -+#pragma omp parallel num_threads (4) reduction(+:e) -+ { -+ long i; -+ #pragma omp for schedule(dynamic,1) -+ for (i = __LONG_MAX__ - 30001; i <= __LONG_MAX__ - 10001; i += 10000) -+ if (i != __LONG_MAX__ - 30001 -+ && i != __LONG_MAX__ - 20001 -+ && i != __LONG_MAX__ - 10001) -+ e = 1; -+ #pragma omp for schedule(dynamic,1) -+ for (i = -__LONG_MAX__ + 30000; i >= -__LONG_MAX__ + 10000; i -= 10000) -+ if (i != -__LONG_MAX__ + 30000 -+ && i != -__LONG_MAX__ + 20000 -+ && i != -__LONG_MAX__ + 10000) -+ e = 1; -+ } -+ if (e) -+ abort (); -+ return 0; -+} ---- libgomp/Makefile.am.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/Makefile.am 2008-03-26 15:15:19.000000000 +0100 -@@ -31,7 +31,7 @@ libgomp_la_LDFLAGS = $(libgomp_version_i - - 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 \ -- lock.c mutex.c proc.c sem.c bar.c time.c fortran.c affinity.c -+ lock.c mutex.c proc.c sem.c bar.c ptrlock.c time.c fortran.c affinity.c - - nodist_noinst_HEADERS = libgomp_f.h - nodist_libsubinclude_HEADERS = omp.h ---- libgomp/team.c.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/team.c 2008-03-27 12:22:26.000000000 +0100 -@@ -94,7 +94,7 @@ gomp_thread_start (void *xdata) - { - gomp_barrier_wait (&thr->ts.team->barrier); - local_fn (local_data); -- gomp_barrier_wait (&thr->ts.team->barrier); -+ gomp_barrier_wait_last (&thr->ts.team->barrier); - } - else - { -@@ -114,11 +114,10 @@ gomp_thread_start (void *xdata) - thr->data = NULL; - thr->ts.team = NULL; - thr->ts.work_share = NULL; -+ thr->ts.last_work_share = NULL; - thr->ts.team_id = 0; -- thr->ts.work_share_generation = 0; -- thr->ts.static_trip = 0; - -- gomp_barrier_wait (&team->barrier); -+ gomp_barrier_wait_last (&team->barrier); - gomp_barrier_wait (&gomp_threads_dock); - - local_fn = thr->fn; -@@ -133,21 +132,29 @@ gomp_thread_start (void *xdata) - - /* Create a new team data structure. */ - --static struct gomp_team * --new_team (unsigned nthreads, struct gomp_work_share *work_share) -+struct gomp_team * -+gomp_new_team (unsigned nthreads) - { - struct gomp_team *team; - size_t size; -+ int i; - - size = sizeof (*team) + nthreads * sizeof (team->ordered_release[0]); - team = gomp_malloc (size); -- gomp_mutex_init (&team->work_share_lock); - -- team->work_shares = gomp_malloc (4 * sizeof (struct gomp_work_share *)); -- team->generation_mask = 3; -- team->oldest_live_gen = work_share == NULL; -- team->num_live_gen = work_share != NULL; -- team->work_shares[0] = work_share; -+ team->work_share_chunk = 8; -+#ifdef HAVE_SYNC_BUILTINS -+ 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); -+ team->work_shares[0].next_alloc = NULL; -+ team->work_share_list_free = NULL; -+ team->work_share_list_alloc = &team->work_shares[1]; -+ for (i = 1; i < 7; i++) -+ team->work_shares[i].next_free = &team->work_shares[i + 1]; -+ team->work_shares[i].next_free = NULL; - - team->nthreads = nthreads; - gomp_barrier_init (&team->barrier, nthreads); -@@ -164,10 +171,22 @@ new_team (unsigned nthreads, struct gomp - static void - free_team (struct gomp_team *team) - { -- free (team->work_shares); -- gomp_mutex_destroy (&team->work_share_lock); -+ if (__builtin_expect (team->work_shares[0].next_alloc != NULL, 0)) -+ { -+ struct gomp_work_share *ws = team->work_shares[0].next_alloc; -+ do -+ { -+ struct gomp_work_share *next_ws = ws->next_alloc; -+ free (ws); -+ ws = next_ws; -+ } -+ while (ws != NULL); -+ } - gomp_barrier_destroy (&team->barrier); - gomp_sem_destroy (&team->master_release); -+#ifndef HAVE_SYNC_BUILTINS -+ gomp_mutex_destroy (&team->work_share_list_free_lock); -+#endif - free (team); - } - -@@ -176,11 +195,10 @@ free_team (struct gomp_team *team) - - void - gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads, -- struct gomp_work_share *work_share) -+ struct gomp_team *team) - { - struct gomp_thread_start_data *start_data; - struct gomp_thread *thr, *nthr; -- struct gomp_team *team; - bool nested; - unsigned i, n, old_threads_used = 0; - pthread_attr_t thread_attr, *attr; -@@ -188,17 +206,18 @@ gomp_team_start (void (*fn) (void *), vo - thr = gomp_thread (); - nested = thr->ts.team != NULL; - -- team = new_team (nthreads, work_share); -- - /* Always save the previous state, even if this isn't a nested team. - In particular, we should save any work share state from an outer - orphaned work share construct. */ - team->prev_ts = thr->ts; - - thr->ts.team = team; -- thr->ts.work_share = work_share; - thr->ts.team_id = 0; -- thr->ts.work_share_generation = 0; -+ thr->ts.work_share = &team->work_shares[0]; -+ thr->ts.last_work_share = NULL; -+#ifdef HAVE_SYNC_BUILTINS -+ thr->ts.single_count = 0; -+#endif - thr->ts.static_trip = 0; - - if (nthreads == 1) -@@ -241,9 +260,12 @@ gomp_team_start (void (*fn) (void *), vo - { - nthr = gomp_threads[i]; - nthr->ts.team = team; -- nthr->ts.work_share = work_share; -+ nthr->ts.work_share = &team->work_shares[0]; -+ nthr->ts.last_work_share = NULL; - nthr->ts.team_id = i; -- nthr->ts.work_share_generation = 0; -+#ifdef HAVE_SYNC_BUILTINS -+ nthr->ts.single_count = 0; -+#endif - nthr->ts.static_trip = 0; - nthr->fn = fn; - nthr->data = data; -@@ -266,8 +288,24 @@ gomp_team_start (void (*fn) (void *), vo - } - } - -+ if (__builtin_expect (nthreads > old_threads_used, 0)) -+ { -+ long diff = (long) nthreads - (long) old_threads_used; -+ -+ if (old_threads_used == 0) -+ --diff; -+ -+#ifdef HAVE_SYNC_BUILTINS -+ __sync_fetch_and_add (&gomp_managed_threads, diff); -+#else -+ gomp_mutex_lock (&gomp_remaining_threads_lock); -+ gomp_managed_threads += diff; -+ gomp_mutex_unlock (&gomp_remaining_threads_lock); -+#endif -+ } -+ - attr = &gomp_thread_attr; -- if (gomp_cpu_affinity != NULL) -+ if (__builtin_expect (gomp_cpu_affinity != NULL, 0)) - { - size_t stacksize; - pthread_attr_init (&thread_attr); -@@ -287,9 +325,12 @@ gomp_team_start (void (*fn) (void *), vo - int err; - - start_data->ts.team = team; -- start_data->ts.work_share = work_share; -+ start_data->ts.work_share = &team->work_shares[0]; -+ start_data->ts.last_work_share = NULL; - start_data->ts.team_id = i; -- start_data->ts.work_share_generation = 0; -+#ifdef HAVE_SYNC_BUILTINS -+ start_data->ts.single_count = 0; -+#endif - start_data->ts.static_trip = 0; - start_data->fn = fn; - start_data->fn_data = data; -@@ -303,7 +344,7 @@ gomp_team_start (void (*fn) (void *), vo - gomp_fatal ("Thread creation failed: %s", strerror (err)); - } - -- if (gomp_cpu_affinity != NULL) -+ if (__builtin_expect (gomp_cpu_affinity != NULL, 0)) - pthread_attr_destroy (&thread_attr); - - do_release: -@@ -313,8 +354,20 @@ gomp_team_start (void (*fn) (void *), vo - that should arrive back at the end of this team. The extra - threads should be exiting. Note that we arrange for this test - to never be true for nested teams. */ -- if (nthreads < old_threads_used) -- gomp_barrier_reinit (&gomp_threads_dock, nthreads); -+ if (__builtin_expect (nthreads < old_threads_used, 0)) -+ { -+ long diff = (long) nthreads - (long) old_threads_used; -+ -+ gomp_barrier_reinit (&gomp_threads_dock, nthreads); -+ -+#ifdef HAVE_SYNC_BUILTINS -+ __sync_fetch_and_add (&gomp_managed_threads, diff); -+#else -+ gomp_mutex_lock (&gomp_remaining_threads_lock); -+ gomp_managed_threads += diff; -+ gomp_mutex_unlock (&gomp_remaining_threads_lock); -+#endif -+ } - } - - -@@ -329,8 +382,21 @@ gomp_team_end (void) - - gomp_barrier_wait (&team->barrier); - -+ gomp_fini_work_share (thr->ts.work_share); -+ - thr->ts = team->prev_ts; - -+ if (__builtin_expect (thr->ts.team != NULL, 0)) -+ { -+#ifdef HAVE_SYNC_BUILTINS -+ __sync_fetch_and_add (&gomp_managed_threads, 1L - team->nthreads); -+#else -+ gomp_mutex_lock (&gomp_remaining_threads_lock); -+ gomp_managed_threads -= team->nthreads - 1L; -+ gomp_mutex_unlock (&gomp_remaining_threads_lock); -+#endif -+ } -+ - free_team (team); - } - ---- libgomp/config/posix/bar.h.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/config/posix/bar.h 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -46,18 +46,32 @@ typedef struct - unsigned total; - unsigned arrived; - } gomp_barrier_t; -+typedef bool gomp_barrier_state_t; - - extern void gomp_barrier_init (gomp_barrier_t *, unsigned); - extern void gomp_barrier_reinit (gomp_barrier_t *, unsigned); - extern void gomp_barrier_destroy (gomp_barrier_t *); - - extern void gomp_barrier_wait (gomp_barrier_t *); --extern void gomp_barrier_wait_end (gomp_barrier_t *, bool); -+extern void gomp_barrier_wait_end (gomp_barrier_t *, gomp_barrier_state_t); - --static inline bool gomp_barrier_wait_start (gomp_barrier_t *bar) -+static inline gomp_barrier_state_t -+gomp_barrier_wait_start (gomp_barrier_t *bar) - { - gomp_mutex_lock (&bar->mutex1); - return ++bar->arrived == bar->total; - } - -+static inline bool -+gomp_barrier_last_thread (gomp_barrier_state_t state) -+{ -+ return state; -+} -+ -+static inline void -+gomp_barrier_wait_last (gomp_barrier_t *bar) -+{ -+ gomp_barrier_wait (bar); -+} -+ - #endif /* GOMP_BARRIER_H */ ---- libgomp/config/posix/ptrlock.h.jj 2008-03-26 15:11:32.000000000 +0100 -+++ libgomp/config/posix/ptrlock.h 2008-03-26 15:11:32.000000000 +0100 -@@ -0,0 +1,69 @@ -+/* Copyright (C) 2008 Free Software Foundation, Inc. -+ Contributed by Jakub Jelinek . -+ -+ 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 mutex synchronization -+ mechanism for libgomp. This type is private to the library. This -+ implementation uses atomic instructions and the futex syscall. */ -+ -+#ifndef GOMP_PTRLOCK_H -+#define GOMP_PTRLOCK_H 1 -+ -+typedef struct { void *ptr; gomp_mutex_t lock; } gomp_ptrlock_t; -+ -+static inline void gomp_ptrlock_init (gomp_ptrlock_t *ptrlock, void *ptr) -+{ -+ ptrlock->ptr = ptr; -+ gomp_mutex_init (&ptrlock->lock); -+} -+ -+static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock) -+{ -+ if (ptrlock->ptr != NULL) -+ return ptrlock->ptr; -+ -+ gomp_mutex_lock (&ptrlock->lock); -+ if (ptrlock->ptr != NULL) -+ { -+ gomp_mutex_unlock (&ptrlock->lock); -+ return ptrlock->ptr; -+ } -+ -+ return NULL; -+} -+ -+static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr) -+{ -+ ptrlock->ptr = ptr; -+ gomp_mutex_unlock (&ptrlock->lock); -+} -+ -+static inline void gomp_ptrlock_destroy (gomp_ptrlock_t *ptrlock) -+{ -+ gomp_mutex_destroy (&ptrlock->lock); -+} -+ -+#endif /* GOMP_PTRLOCK_H */ ---- libgomp/config/posix/ptrlock.c.jj 2008-03-26 15:11:32.000000000 +0100 -+++ libgomp/config/posix/ptrlock.c 2008-03-26 15:11:32.000000000 +0100 -@@ -0,0 +1 @@ -+/* Everything is in the header. */ ---- libgomp/config/posix/bar.c.jj 2007-12-07 14:41:01.000000000 +0100 -+++ libgomp/config/posix/bar.c 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -70,7 +70,7 @@ gomp_barrier_reinit (gomp_barrier_t *bar - } - - void --gomp_barrier_wait_end (gomp_barrier_t *bar, bool last) -+gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t last) - { - unsigned int n; - ---- libgomp/config/linux/alpha/futex.h.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/alpha/futex.h 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -30,8 +30,6 @@ - #ifndef SYS_futex - #define SYS_futex 394 - #endif --#define FUTEX_WAIT 0 --#define FUTEX_WAKE 1 - - - static inline void -@@ -45,7 +43,7 @@ futex_wait (int *addr, int val) - - sc_0 = SYS_futex; - sc_16 = (long) addr; -- sc_17 = FUTEX_WAIT; -+ sc_17 = gomp_futex_wait; - sc_18 = val; - sc_19 = 0; - __asm volatile ("callsys" -@@ -53,6 +51,20 @@ futex_wait (int *addr, int val) - : "0"(sc_0), "r" (sc_16), "r"(sc_17), "r"(sc_18), "1"(sc_19) - : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$22", "$23", "$24", "$25", "$27", "$28", "memory"); -+ if (__builtin_expect (sc_19, 0) && sc_0 == ENOSYS) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sc_0 = SYS_futex; -+ sc_17 &= ~FUTEX_PRIVATE_FLAG; -+ sc_19 = 0; -+ __asm volatile ("callsys" -+ : "=r" (sc_0), "=r"(sc_19) -+ : "0"(sc_0), "r" (sc_16), "r"(sc_17), "r"(sc_18), -+ "1"(sc_19) -+ : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", -+ "$22", "$23", "$24", "$25", "$27", "$28", "memory"); -+ } - } - - static inline void -@@ -66,11 +78,35 @@ futex_wake (int *addr, int count) - - sc_0 = SYS_futex; - sc_16 = (long) addr; -- sc_17 = FUTEX_WAKE; -+ sc_17 = gomp_futex_wake; - sc_18 = count; - __asm volatile ("callsys" - : "=r" (sc_0), "=r"(sc_19) - : "0"(sc_0), "r" (sc_16), "r"(sc_17), "r"(sc_18) - : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$22", "$23", "$24", "$25", "$27", "$28", "memory"); -+ if (__builtin_expect (sc_19, 0) && sc_0 == ENOSYS) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sc_0 = SYS_futex; -+ sc_17 &= ~FUTEX_PRIVATE_FLAG; -+ __asm volatile ("callsys" -+ : "=r" (sc_0), "=r"(sc_19) -+ : "0"(sc_0), "r" (sc_16), "r"(sc_17), "r"(sc_18) -+ : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", -+ "$22", "$23", "$24", "$25", "$27", "$28", "memory"); -+ } -+} -+ -+static inline void -+cpu_relax (void) -+{ -+ __asm volatile ("" : : : "memory"); -+} -+ -+static inline void -+atomic_write_barrier (void) -+{ -+ __asm volatile ("wmb" : : : "memory"); - } ---- libgomp/config/linux/affinity.c.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/affinity.c 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2006, 2007 Free Software Foundation, Inc. -+/* Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. - Contributed by Jakub Jelinek . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -38,9 +38,6 @@ - #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) -@@ -76,9 +73,6 @@ gomp_init_affinity (void) - 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 -@@ -87,13 +81,7 @@ gomp_init_thread_affinity (pthread_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); ---- libgomp/config/linux/bar.h.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/bar.h 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -36,40 +36,49 @@ - - typedef struct - { -- gomp_mutex_t mutex; -- unsigned total; -- unsigned arrived; -- int generation; -+ /* Make sure total/generation is in a mostly read cacheline, while -+ awaited in a separate cacheline. */ -+ unsigned total __attribute__((aligned (64))); -+ unsigned generation; -+ unsigned awaited __attribute__((aligned (64))); - } gomp_barrier_t; -+typedef unsigned int gomp_barrier_state_t; - - static inline void gomp_barrier_init (gomp_barrier_t *bar, unsigned count) - { -- gomp_mutex_init (&bar->mutex); - bar->total = count; -- bar->arrived = 0; -+ bar->awaited = count; - bar->generation = 0; - } - - static inline void gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count) - { -- gomp_mutex_lock (&bar->mutex); -+ __sync_fetch_and_add (&bar->awaited, count - bar->total); - bar->total = count; -- gomp_mutex_unlock (&bar->mutex); - } - - static inline void gomp_barrier_destroy (gomp_barrier_t *bar) - { -- /* Before destroying, make sure all threads have left the barrier. */ -- gomp_mutex_lock (&bar->mutex); - } - - extern void gomp_barrier_wait (gomp_barrier_t *); --extern void gomp_barrier_wait_end (gomp_barrier_t *, bool); -+extern void gomp_barrier_wait_last (gomp_barrier_t *); -+extern void gomp_barrier_wait_end (gomp_barrier_t *, gomp_barrier_state_t); - --static inline bool gomp_barrier_wait_start (gomp_barrier_t *bar) -+static inline gomp_barrier_state_t -+gomp_barrier_wait_start (gomp_barrier_t *bar) - { -- gomp_mutex_lock (&bar->mutex); -- return ++bar->arrived == bar->total; -+ unsigned int ret = bar->generation; -+ /* Do we need any barrier here or is __sync_add_and_fetch acting -+ as the needed LoadLoad barrier already? */ -+ ret += __sync_add_and_fetch (&bar->awaited, -1) == 0; -+ return ret; -+} -+ -+static inline bool -+gomp_barrier_last_thread (gomp_barrier_state_t state) -+{ -+ return state & 1; - } - - #endif /* GOMP_BARRIER_H */ ---- libgomp/config/linux/ptrlock.h.jj 2008-03-26 15:11:32.000000000 +0100 -+++ libgomp/config/linux/ptrlock.h 2008-03-26 15:11:32.000000000 +0100 -@@ -0,0 +1,65 @@ -+/* Copyright (C) 2008 Free Software Foundation, Inc. -+ Contributed by Jakub Jelinek . -+ -+ 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 mutex synchronization -+ mechanism for libgomp. This type is private to the library. This -+ implementation uses atomic instructions and the futex syscall. */ -+ -+#ifndef GOMP_PTRLOCK_H -+#define GOMP_PTRLOCK_H 1 -+ -+typedef void *gomp_ptrlock_t; -+ -+static inline void gomp_ptrlock_init (gomp_ptrlock_t *ptrlock, void *ptr) -+{ -+ *ptrlock = ptr; -+} -+ -+extern void *gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock); -+static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock) -+{ -+ if ((uintptr_t) *ptrlock > 2) -+ return *ptrlock; -+ -+ if (__sync_bool_compare_and_swap (ptrlock, NULL, (uintptr_t) 1)) -+ return NULL; -+ -+ return gomp_ptrlock_get_slow (ptrlock); -+} -+ -+extern void gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock, void *ptr); -+static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr) -+{ -+ if (!__sync_bool_compare_and_swap (ptrlock, (uintptr_t) 1, ptr)) -+ gomp_ptrlock_set_slow (ptrlock, ptr); -+} -+ -+static inline void gomp_ptrlock_destroy (gomp_ptrlock_t *ptrlock) -+{ -+} -+ -+#endif /* GOMP_PTRLOCK_H */ ---- libgomp/config/linux/lock.c.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/lock.c 2008-03-26 15:11:32.000000000 +0100 -@@ -29,11 +29,10 @@ - primitives. This implementation uses atomic instructions and the futex - syscall. */ - --#include "libgomp.h" - #include - #include - #include --#include "futex.h" -+#include "wait.h" - - - /* The internal gomp_mutex_t and the external non-recursive omp_lock_t -@@ -137,7 +136,7 @@ omp_set_nest_lock (omp_nest_lock_t *lock - return; - } - -- futex_wait (&lock->owner, otid); -+ do_wait (&lock->owner, otid); - } - } - ---- libgomp/config/linux/ptrlock.c.jj 2008-03-26 15:11:32.000000000 +0100 -+++ libgomp/config/linux/ptrlock.c 2008-03-26 15:11:32.000000000 +0100 -@@ -0,0 +1,70 @@ -+/* Copyright (C) 2008 Free Software Foundation, Inc. -+ Contributed by Jakub Jelinek . -+ -+ 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 mutex synchronization -+ mechanism for libgomp. This type is private to the library. This -+ implementation uses atomic instructions and the futex syscall. */ -+ -+#include -+#include -+#include "wait.h" -+ -+void * -+gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock) -+{ -+ int *intptr; -+ __sync_bool_compare_and_swap (ptrlock, 1, 2); -+ -+ /* futex works on ints, not pointers. -+ But a valid work share pointer will be at least -+ 8 byte aligned, so it is safe to assume the low -+ 32-bits of the pointer won't contain values 1 or 2. */ -+ __asm volatile ("" : "=r" (intptr) : "0" (ptrlock)); -+#if __BYTE_ORDER == __BIG_ENDIAN -+ if (sizeof (*ptrlock) > sizeof (int)) -+ intptr += (sizeof (*ptrlock) / sizeof (int)) - 1; -+#endif -+ do -+ do_wait (intptr, 2); -+ while (*intptr == 2); -+ __asm volatile ("" : : : "memory"); -+ return *ptrlock; -+} -+ -+void -+gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock, void *ptr) -+{ -+ int *intptr; -+ -+ *ptrlock = ptr; -+ __asm volatile ("" : "=r" (intptr) : "0" (ptrlock)); -+#if __BYTE_ORDER == __BIG_ENDIAN -+ if (sizeof (*ptrlock) > sizeof (int)) -+ intptr += (sizeof (*ptrlock) / sizeof (int)) - 1; -+#endif -+ futex_wake (intptr, INT_MAX); -+} ---- libgomp/config/linux/x86/futex.h.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/x86/futex.h 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -27,9 +27,6 @@ - - /* Provide target-specific access to the futex system call. */ - --#define FUTEX_WAIT 0 --#define FUTEX_WAKE 1 -- - #ifdef __LP64__ - # ifndef SYS_futex - # define SYS_futex 202 -@@ -38,14 +35,26 @@ - static inline void - futex_wait (int *addr, int val) - { -- register long r10 __asm__("%r10") = 0; -+ register long r10 __asm__("%r10"); - long res; - -+ r10 = 0; - __asm volatile ("syscall" - : "=a" (res) -- : "0"(SYS_futex), "D" (addr), "S"(FUTEX_WAIT), -- "d"(val), "r"(r10) -+ : "0" (SYS_futex), "D" (addr), "S" (gomp_futex_wait), -+ "d" (val), "r" (r10) - : "r11", "rcx", "memory"); -+ if (__builtin_expect (res == -ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ r10 = 0; -+ __asm volatile ("syscall" -+ : "=a" (res) -+ : "0" (SYS_futex), "D" (addr), "S" (gomp_futex_wait), -+ "d" (val), "r" (r10) -+ : "r11", "rcx", "memory"); -+ } - } - - static inline void -@@ -55,8 +64,19 @@ futex_wake (int *addr, int count) - - __asm volatile ("syscall" - : "=a" (res) -- : "0"(SYS_futex), "D" (addr), "S"(FUTEX_WAKE), "d"(count) -+ : "0" (SYS_futex), "D" (addr), "S" (gomp_futex_wake), -+ "d" (count) - : "r11", "rcx", "memory"); -+ if (__builtin_expect (res == -ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ __asm volatile ("syscall" -+ : "=a" (res) -+ : "0" (SYS_futex), "D" (addr), "S" (gomp_futex_wake), -+ "d" (count) -+ : "r11", "rcx", "memory"); -+ } - } - #else - # ifndef SYS_futex -@@ -65,7 +85,7 @@ futex_wake (int *addr, int count) - - # ifdef __PIC__ - --static inline void -+static inline long - sys_futex0 (int *addr, int op, int val) - { - long res; -@@ -77,11 +97,12 @@ sys_futex0 (int *addr, int op, int val) - : "0"(SYS_futex), "r" (addr), "c"(op), - "d"(val), "S"(0) - : "memory"); -+ return res; - } - - # else - --static inline void -+static inline long - sys_futex0 (int *addr, int op, int val) - { - long res; -@@ -91,6 +112,7 @@ sys_futex0 (int *addr, int op, int val) - : "0"(SYS_futex), "b" (addr), "c"(op), - "d"(val), "S"(0) - : "memory"); -+ return res; - } - - # endif /* __PIC__ */ -@@ -98,13 +120,37 @@ sys_futex0 (int *addr, int op, int val) - static inline void - futex_wait (int *addr, int val) - { -- sys_futex0 (addr, FUTEX_WAIT, val); -+ long res = sys_futex0 (addr, gomp_futex_wait, val); -+ if (__builtin_expect (res == -ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wait, val); -+ } - } - - static inline void - futex_wake (int *addr, int count) - { -- sys_futex0 (addr, FUTEX_WAKE, count); -+ long res = sys_futex0 (addr, gomp_futex_wake, count); -+ if (__builtin_expect (res == -ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wake, count); -+ } - } - - #endif /* __LP64__ */ -+ -+static inline void -+cpu_relax (void) -+{ -+ __asm volatile ("rep; nop" : : : "memory"); -+} -+ -+static inline void -+atomic_write_barrier (void) -+{ -+ __sync_synchronize (); -+} ---- libgomp/config/linux/wait.h.jj 2008-03-26 15:11:32.000000000 +0100 -+++ libgomp/config/linux/wait.h 2008-03-26 15:11:32.000000000 +0100 -@@ -0,0 +1,68 @@ -+/* Copyright (C) 2008 Free Software Foundation, Inc. -+ Contributed by Jakub Jelinek . -+ -+ 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 mutex synchronization -+ mechanism for libgomp. This type is private to the library. This -+ implementation uses atomic instructions and the futex syscall. */ -+ -+#ifndef GOMP_WAIT_H -+#define GOMP_WAIT_H 1 -+ -+#include "libgomp.h" -+#include -+ -+#define FUTEX_WAIT 0 -+#define FUTEX_WAKE 1 -+#define FUTEX_PRIVATE_FLAG 128L -+ -+#ifdef HAVE_ATTRIBUTE_VISIBILITY -+# pragma GCC visibility push(hidden) -+#endif -+ -+extern long int gomp_futex_wait, gomp_futex_wake; -+ -+#include "futex.h" -+ -+static inline void do_wait (int *addr, int val) -+{ -+ unsigned long long i, count = gomp_spin_count_var; -+ -+ if (__builtin_expect (gomp_managed_threads > gomp_available_cpus, 0)) -+ count = gomp_throttled_spin_count_var; -+ for (i = 0; i < count; i++) -+ if (__builtin_expect (*addr != val, 0)) -+ return; -+ else -+ cpu_relax (); -+ futex_wait (addr, val); -+} -+ -+#ifdef HAVE_ATTRIBUTE_VISIBILITY -+# pragma GCC visibility pop -+#endif -+ -+#endif /* GOMP_WAIT_H */ ---- libgomp/config/linux/sparc/futex.h.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/sparc/futex.h 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Jakub Jelinek . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -28,10 +28,8 @@ - /* Provide target-specific access to the futex system call. */ - - #include --#define FUTEX_WAIT 0 --#define FUTEX_WAKE 1 - --static inline void -+static inline long - sys_futex0 (int *addr, int op, int val) - { - register long int g1 __asm__ ("g1"); -@@ -47,9 +45,9 @@ sys_futex0 (int *addr, int op, int val) - o3 = 0; - - #ifdef __arch64__ --# define SYSCALL_STRING "ta\t0x6d" -+# define SYSCALL_STRING "ta\t0x6d; bcs,a,pt %%xcc, 1f; sub %%g0, %%o0, %%o0; 1:" - #else --# define SYSCALL_STRING "ta\t0x10" -+# define SYSCALL_STRING "ta\t0x10; bcs,a 1f; sub %%g0, %%o0, %%o0; 1:" - #endif - - __asm volatile (SYSCALL_STRING -@@ -65,16 +63,49 @@ sys_futex0 (int *addr, int op, int val) - "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", - #endif - "cc", "memory"); -+ return o0; - } - - static inline void - futex_wait (int *addr, int val) - { -- sys_futex0 (addr, FUTEX_WAIT, val); -+ long err = sys_futex0 (addr, gomp_futex_wait, val); -+ if (__builtin_expect (err == ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wait, val); -+ } - } - - static inline void - futex_wake (int *addr, int count) - { -- sys_futex0 (addr, FUTEX_WAKE, count); -+ long err = sys_futex0 (addr, gomp_futex_wake, count); -+ if (__builtin_expect (err == ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wake, count); -+ } -+} -+ -+static inline void -+cpu_relax (void) -+{ -+#if defined __arch64__ || defined __sparc_v9__ -+ __asm volatile ("membar #LoadLoad" : : : "memory"); -+#else -+ __asm volatile ("" : : : "memory"); -+#endif -+} -+ -+static inline void -+atomic_write_barrier (void) -+{ -+#if defined __arch64__ || defined __sparc_v9__ -+ __asm volatile ("membar #StoreStore" : : : "memory"); -+#else -+ __sync_synchronize (); -+#endif - } ---- libgomp/config/linux/ia64/futex.h.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/ia64/futex.h 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -29,23 +29,24 @@ - - #include - --#define FUTEX_WAIT 0 --#define FUTEX_WAKE 1 - - --static inline void --sys_futex0(int *addr, int op, int val) -+static inline long -+sys_futex0(int *addr, long op, int val) - { - register long out0 asm ("out0") = (long) addr; - register long out1 asm ("out1") = op; - register long out2 asm ("out2") = val; - register long out3 asm ("out3") = 0; -+ register long r8 asm ("r8"); -+ register long r10 asm ("r10"); - register long r15 asm ("r15") = SYS_futex; - - __asm __volatile ("break 0x100000" -- : "=r"(r15), "=r"(out0), "=r"(out1), "=r"(out2), "=r"(out3) -+ : "=r"(r15), "=r"(out0), "=r"(out1), "=r"(out2), "=r"(out3), -+ "=r"(r8), "=r"(r10) - : "r"(r15), "r"(out0), "r"(out1), "r"(out2), "r"(out3) -- : "memory", "r8", "r10", "out4", "out5", "out6", "out7", -+ : "memory", "out4", "out5", "out6", "out7", - /* Non-stacked integer registers, minus r8, r10, r15. */ - "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", - "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", -@@ -56,16 +57,41 @@ sys_futex0(int *addr, int op, int val) - "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - /* Branch registers. */ - "b6"); -+ return r8 & r10; - } - - static inline void - futex_wait (int *addr, int val) - { -- sys_futex0 (addr, FUTEX_WAIT, val); -+ long err = sys_futex0 (addr, gomp_futex_wait, val); -+ if (__builtin_expect (err == ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wait, val); -+ } - } - - static inline void - futex_wake (int *addr, int count) - { -- sys_futex0 (addr, FUTEX_WAKE, count); -+ long err = sys_futex0 (addr, gomp_futex_wake, count); -+ if (__builtin_expect (err == ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wake, count); -+ } -+} -+ -+static inline void -+cpu_relax (void) -+{ -+ __asm volatile ("hint @pause" : : : "memory"); -+} -+ -+static inline void -+atomic_write_barrier (void) -+{ -+ __sync_synchronize (); - } ---- libgomp/config/linux/s390/futex.h.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/s390/futex.h 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Jakub Jelinek . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -28,10 +28,8 @@ - /* Provide target-specific access to the futex system call. */ - - #include --#define FUTEX_WAIT 0 --#define FUTEX_WAKE 1 - --static inline void -+static inline long - sys_futex0 (int *addr, int op, int val) - { - register long int gpr2 __asm__ ("2"); -@@ -49,16 +47,41 @@ sys_futex0 (int *addr, int op, int val) - : "i" (SYS_futex), - "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5) - : "memory"); -+ return gpr2; - } - - static inline void - futex_wait (int *addr, int val) - { -- sys_futex0 (addr, FUTEX_WAIT, val); -+ long err = sys_futex0 (addr, gomp_futex_wait, val); -+ if (__builtin_expect (err == -ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wait, val); -+ } - } - - static inline void - futex_wake (int *addr, int count) - { -- sys_futex0 (addr, FUTEX_WAKE, count); -+ long err = sys_futex0 (addr, gomp_futex_wake, count); -+ if (__builtin_expect (err == -ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wake, count); -+ } -+} -+ -+static inline void -+cpu_relax (void) -+{ -+ __asm volatile ("" : : : "memory"); -+} -+ -+static inline void -+atomic_write_barrier (void) -+{ -+ __sync_synchronize (); - } ---- libgomp/config/linux/mutex.c.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/mutex.c 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -29,9 +29,10 @@ - mechanism for libgomp. This type is private to the library. This - implementation uses atomic instructions and the futex syscall. */ - --#include "libgomp.h" --#include "futex.h" -+#include "wait.h" - -+long int gomp_futex_wake = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; -+long int gomp_futex_wait = FUTEX_WAIT | FUTEX_PRIVATE_FLAG; - - void - gomp_mutex_lock_slow (gomp_mutex_t *mutex) -@@ -40,7 +41,7 @@ gomp_mutex_lock_slow (gomp_mutex_t *mute - { - int oldval = __sync_val_compare_and_swap (mutex, 1, 2); - if (oldval != 0) -- futex_wait (mutex, 2); -+ do_wait (mutex, 2); - } - while (!__sync_bool_compare_and_swap (mutex, 0, 2)); - } ---- libgomp/config/linux/sem.c.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/sem.c 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -29,8 +29,7 @@ - mechanism for libgomp. This type is private to the library. This - implementation uses atomic instructions and the futex syscall. */ - --#include "libgomp.h" --#include "futex.h" -+#include "wait.h" - - - void -@@ -44,7 +43,7 @@ gomp_sem_wait_slow (gomp_sem_t *sem) - if (__sync_bool_compare_and_swap (sem, val, val - 1)) - return; - } -- futex_wait (sem, -1); -+ do_wait (sem, -1); - } - } - ---- libgomp/config/linux/powerpc/futex.h.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/powerpc/futex.h 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -28,10 +28,8 @@ - /* Provide target-specific access to the futex system call. */ - - #include --#define FUTEX_WAIT 0 --#define FUTEX_WAKE 1 - --static inline void -+static inline long - sys_futex0 (int *addr, int op, int val) - { - register long int r0 __asm__ ("r0"); -@@ -50,21 +48,48 @@ sys_futex0 (int *addr, int op, int val) - doesn't. It doesn't much matter for us. In the interest of unity, - go ahead and clobber it always. */ - -- __asm volatile ("sc" -+ __asm volatile ("sc; mfcr %0" - : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6) - : "r"(r0), "r"(r3), "r"(r4), "r"(r5), "r"(r6) - : "r7", "r8", "r9", "r10", "r11", "r12", - "cr0", "ctr", "memory"); -+ if (__builtin_expect (r0 & (1 << 28), 0)) -+ return r3; -+ return 0; - } - - static inline void - futex_wait (int *addr, int val) - { -- sys_futex0 (addr, FUTEX_WAIT, val); -+ long err = sys_futex0 (addr, gomp_futex_wait, val); -+ if (__builtin_expect (err == ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wait, val); -+ } - } - - static inline void - futex_wake (int *addr, int count) - { -- sys_futex0 (addr, FUTEX_WAKE, count); -+ long err = sys_futex0 (addr, gomp_futex_wake, count); -+ if (__builtin_expect (err == ENOSYS, 0)) -+ { -+ gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; -+ gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; -+ sys_futex0 (addr, gomp_futex_wake, count); -+ } -+} -+ -+static inline void -+cpu_relax (void) -+{ -+ __asm volatile ("" : : : "memory"); -+} -+ -+static inline void -+atomic_write_barrier (void) -+{ -+ __asm volatile ("eieio" : : : "memory"); - } ---- libgomp/config/linux/bar.c.jj 2007-12-07 14:41:00.000000000 +0100 -+++ libgomp/config/linux/bar.c 2008-03-26 15:11:32.000000000 +0100 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -+/* Copyright (C) 2005, 2008 Free Software Foundation, Inc. - Contributed by Richard Henderson . - - This file is part of the GNU OpenMP Library (libgomp). -@@ -29,32 +29,29 @@ - mechanism for libgomp. This type is private to the library. This - implementation uses atomic instructions and the futex syscall. */ - --#include "libgomp.h" --#include "futex.h" - #include -+#include "wait.h" - - - void --gomp_barrier_wait_end (gomp_barrier_t *bar, bool last) -+gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) - { -- if (last) -+ if (__builtin_expect ((state & 1) != 0, 0)) - { -- bar->generation++; -- futex_wake (&bar->generation, INT_MAX); -+ /* Next time we'll be awaiting TOTAL threads again. */ -+ bar->awaited = bar->total; -+ atomic_write_barrier (); -+ bar->generation += 2; -+ futex_wake ((int *) &bar->generation, INT_MAX); - } - else - { -- unsigned int generation = bar->generation; -- -- gomp_mutex_unlock (&bar->mutex); -+ unsigned int generation = state; - - do -- futex_wait (&bar->generation, generation); -+ do_wait ((int *) &bar->generation, generation); - while (bar->generation == generation); - } -- -- if (__sync_add_and_fetch (&bar->arrived, -1) == 0) -- gomp_mutex_unlock (&bar->mutex); - } - - void -@@ -62,3 +59,18 @@ gomp_barrier_wait (gomp_barrier_t *barri - { - gomp_barrier_wait_end (barrier, gomp_barrier_wait_start (barrier)); - } -+ -+/* Like gomp_barrier_wait, except that if the encountering thread -+ is not the last one to hit the barrier, it returns immediately. -+ The intended usage is that a thread which intends to gomp_barrier_destroy -+ this barrier calls gomp_barrier_wait, while all other threads -+ call gomp_barrier_wait_last. When gomp_barrier_wait returns, -+ the barrier can be safely destroyed. */ -+ -+void -+gomp_barrier_wait_last (gomp_barrier_t *barrier) -+{ -+ gomp_barrier_state_t state = gomp_barrier_wait_start (barrier); -+ if (state & 1) -+ gomp_barrier_wait_end (barrier, state); -+} diff --git a/gcc43-pr35650.patch b/gcc43-pr35650.patch deleted file mode 100644 index c3b4775..0000000 --- a/gcc43-pr35650.patch +++ /dev/null @@ -1,50 +0,0 @@ -2008-04-21 Jakub Jelinek - - PR c++/35650 - * parser.c (cp_parser_lookup_name): Look through single function - OVERLOAD. - - * g++.dg/init/ref17.C: New test. - ---- gcc/cp/parser.c.jj 2008-04-18 17:00:44.000000000 +0200 -+++ gcc/cp/parser.c 2008-04-21 23:58:00.000000000 +0200 -@@ -16407,6 +16407,13 @@ cp_parser_lookup_name (cp_parser *parser - decl = lookup_qualified_name (parser->scope, name, - tag_type != none_type, - /*complain=*/true); -+ -+ /* If we have a single function from a using decl, pull it out. */ -+ if (decl -+ && TREE_CODE (decl) == OVERLOAD -+ && !really_overloaded_fn (decl)) -+ decl = OVL_FUNCTION (decl); -+ - if (pushed_scope) - pop_scope (pushed_scope); - } ---- gcc/testsuite/g++.dg/init/ref17.C.jj 2008-04-21 22:48:02.000000000 +0200 -+++ gcc/testsuite/g++.dg/init/ref17.C 2008-04-21 22:47:09.000000000 +0200 -@@ -0,0 +1,23 @@ -+// PR c++/35650 -+// { dg-do compile } -+ -+void f1 (); -+ -+namespace N -+{ -+ using::f1; -+ void f2 (); -+ void f3 (); -+} -+ -+using N::f3; -+ -+void -+test () -+{ -+ void (&a) () = f1; -+ void (&b) () = N::f1; -+ void (&c) () = N::f2; -+ void (&d) () = f3; -+ void (&e) () = ::f3; -+} diff --git a/gcc43-pr35909.patch b/gcc43-pr35909.patch deleted file mode 100644 index 48171e3..0000000 --- a/gcc43-pr35909.patch +++ /dev/null @@ -1,41 +0,0 @@ -2008-04-24 Alexandre Oliva - - PR c++/35909 - * call.c (convert_like_real): Convert bitfield to desired type - before creating temporary. - - * g++.dg/conversion/bitfield9.C: New. - ---- gcc/cp/call.c.orig 2008-04-22 03:26:25.000000000 -0300 -+++ gcc/cp/call.c 2008-04-22 03:26:27.000000000 -0300 -@@ -4580,7 +4580,10 @@ convert_like_real (conversion *convs, tr - return error_mark_node; - } - if (lvalue & clk_bitfield) -- expr = convert_bitfield_to_declared_type (expr); -+ { -+ expr = convert_bitfield_to_declared_type (expr); -+ expr = fold_convert (type, expr); -+ } - expr = build_target_expr_with_type (expr, type); - } - ---- gcc/testsuite/g++.dg/conversion/bitfield9.C 1970-01-01 00:00:00.000000000 +0000 -+++ gcc/testsuite/g++.dg/conversion/bitfield9.C 2008-04-22 03:26:27.000000000 -0300 -@@ -0,0 +1,16 @@ -+// PR c++/35909 -+// { dg-do compile } -+ -+struct MidiCommand -+{ -+ unsigned data1 : 8; -+}; -+ -+void g(const unsigned char &); -+void h(const unsigned int &); -+ -+void f(MidiCommand mc) -+{ -+ g(mc.data1); -+ h(mc.data1); -+} diff --git a/gcc43-pr35987.patch b/gcc43-pr35987.patch deleted file mode 100644 index 4d92234..0000000 --- a/gcc43-pr35987.patch +++ /dev/null @@ -1,37 +0,0 @@ -2008-04-21 Jakub Jelinek - - PR c++/35987 - * typeck.c (build_modify_expr) : Don't build - COMPOUND_EXPR if the second argument would be error_mark_node. - - * g++.dg/other/error28.C: New test. - ---- gcc/cp/typeck.c.jj 2008-04-18 17:00:44.000000000 +0200 -+++ gcc/cp/typeck.c 2008-04-21 16:03:45.000000000 +0200 -@@ -5667,10 +5667,11 @@ build_modify_expr (tree lhs, enum tree_c - lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs), - stabilize_reference (TREE_OPERAND (lhs, 0)), - TREE_OPERAND (lhs, 1)); -- return build2 (COMPOUND_EXPR, lhstype, -- lhs, -- build_modify_expr (TREE_OPERAND (lhs, 0), -- modifycode, rhs)); -+ newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), -+ modifycode, rhs); -+ if (newrhs == error_mark_node) -+ return error_mark_node; -+ return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs); - - /* Handle (a, b) used as an "lvalue". */ - case COMPOUND_EXPR: ---- gcc/testsuite/g++.dg/other/error28.C.jj 2008-04-21 15:42:09.000000000 +0200 -+++ gcc/testsuite/g++.dg/other/error28.C 2008-04-21 15:37:00.000000000 +0200 -@@ -0,0 +1,8 @@ -+// PR c++/35987 -+// { dg-do compile } -+ -+void -+foo (char *p) -+{ -+ if (++p = true); // { dg-error "cannot convert" } -+} diff --git a/gcc43-sparc-config-detection.patch b/gcc43-sparc-config-detection.patch new file mode 100644 index 0000000..4ee95d4 --- /dev/null +++ b/gcc43-sparc-config-detection.patch @@ -0,0 +1,40 @@ +--- gcc/config.gcc.jj 2008-04-24 15:42:46.000000000 -0500 ++++ gcc/config.gcc 2008-04-24 15:44:51.000000000 -0500 +@@ -2343,7 +2343,7 @@ sparc-*-elf*) + extra_parts="crti.o crtn.o crtbegin.o crtend.o" + use_fixproto=yes + ;; +-sparc-*-linux*) # SPARC's running GNU/Linux, libc6 ++sparc-*-linux* | sparcv9*-*-linux*) # SPARC's running GNU/Linux, libc6 + tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h" + extra_options="${extra_options} sparc/long-double-switch.opt" + tmake_file="${tmake_file} sparc/t-linux sparc/t-crtfm" +@@ -2477,7 +2477,7 @@ sparc64-*-freebsd*|ultrasparc-*-freebsd* + esac + need_64bit_hwint=yes + ;; +-sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux ++sparc64*-*-linux*) # 64-bit SPARC's running GNU/Linux + tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux64.h" + extra_options="${extra_options} sparc/long-double-switch.opt" + tmake_file="${tmake_file} sparc/t-linux sparc/t-linux64 sparc/t-crtfm" +--- libgcc/config.host.jj 2008-04-24 15:46:19.000000000 -0500 ++++ libgcc/config.host 2008-04-24 15:46:49.000000000 -0500 +@@ -572,7 +572,7 @@ sparc64-*-openbsd*) + ;; + sparc-*-elf*) + ;; +-sparc-*-linux*) # SPARC's running GNU/Linux, libc6 ++sparc-*-linux* | sparcv9*-*-linux*) # SPARC's running GNU/Linux, libc6 + extra_parts="$extra_parts crtfastmath.o" + tmake_file="${tmake_file} sparc/t-crtfm" + ;; +@@ -590,7 +590,7 @@ sparc-wrs-vxworks) + ;; + sparc64-*-freebsd*|ultrasparc-*-freebsd*) + ;; +-sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux ++sparc64*-*-linux*) # 64-bit SPARC's running GNU/Linux + extra_parts="$extra_parts crtfastmath.o" + tmake_file="${tmake_file} sparc/t-crtfm" + ;; diff --git a/gcc43.spec b/gcc43.spec index 971216b..546f712 100644 --- a/gcc43.spec +++ b/gcc43.spec @@ -1,6 +1,6 @@ -%define DATE 20080428 -%define gcc_version 4.3.0 -%define gcc_release 8 +%define DATE 20080609 +%define gcc_version 4.3.1 +%define gcc_release 1 %define _unpackaged_files_terminate_build 0 %define multilib_64_archs sparc64 ppc64 s390x x86_64 %define include_gappletviewer 1 @@ -20,7 +20,7 @@ %define multilib_32_arch s390 %endif %ifarch sparc64 -%define multilib_32_arch sparc +%define multilib_32_arch sparcv9 %endif %ifarch ppc64 %define multilib_32_arch ppc @@ -71,7 +71,7 @@ BuildRequires: elfutils-devel >= 0.72 # Make sure glibc supports TFmode long double BuildRequires: glibc >= 2.3.90-35 %endif -%ifarch %{multilib_64_archs} sparc ppc +%ifarch %{multilib_64_archs} sparcv9 ppc # Ensure glibc{,-devel} is installed for both multilib arches BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so %endif @@ -138,27 +138,24 @@ Patch8: gcc43-pr32139.patch Patch9: gcc43-pr33763.patch Patch10: gcc43-rh330771.patch Patch11: gcc43-rh341221.patch -Patch12: gcc43-cpp-pragma.patch -Patch13: gcc43-java-debug-iface-type.patch -Patch14: gcc43-libgomp-speedup.patch -Patch15: gcc43-pr35909.patch -Patch16: gcc43-i386-libgomp.patch -Patch17: gcc43-pr35987.patch -Patch18: gcc43-rh251682.patch -Patch19: gcc43-pr35650.patch +Patch12: gcc43-java-debug-iface-type.patch +Patch13: gcc43-i386-libgomp.patch +Patch14: gcc43-rh251682.patch +Patch15: gcc43-sparc-config-detection.patch +Patch16: gcc43-libgomp-omp_h-multilib.patch # On ARM EABI systems, we do want -gnueabi to be part of the # target triple. %ifnarch %{arm} %define _gnu %{nil} %endif -%ifarch sparc +%ifarch sparcv9 %define gcc_target_platform sparc64-%{_vendor}-%{_target_os} %endif %ifarch ppc %define gcc_target_platform ppc64-%{_vendor}-%{_target_os} %endif -%ifnarch sparc ppc +%ifnarch sparcv9 ppc %define gcc_target_platform %{_target_platform} %endif @@ -441,14 +438,11 @@ which are required to run programs compiled with the GNAT. %patch9 -p0 -b .pr33763~ %patch10 -p0 -b .rh330771~ %patch11 -p0 -b .rh341221~ -%patch12 -p0 -b .cpp-pragma~ -%patch13 -p0 -b .java-debug-iface-type~ -%patch14 -p0 -b .libgomp-speedup~ -%patch15 -p0 -b .pr35909~ -%patch16 -p0 -b .i386-libgomp~ -%patch17 -p0 -b .pr35987~ -%patch18 -p0 -b .rh251682~ -%patch19 -p0 -b .pr35650~ +%patch12 -p0 -b .java-debug-iface-type~ +%patch13 -p0 -b .i386-libgomp~ +%patch14 -p0 -b .rh251682~ +%patch15 -p0 -b .sparc-config-detection~ +%patch16 -p0 -b .libgomp-omp_h-multilib~ tar xzf %{SOURCE4} @@ -456,7 +450,7 @@ tar xzf %{SOURCE4} tar xjf %{SOURCE10} %endif -sed -i -e 's/4\.3\.1/4.3.0/' gcc/BASE-VER +sed -i -e 's/4\.3\.2/4.3.1/' gcc/BASE-VER echo 'Red Hat %{version}-%{gcc_release}' > gcc/DEV-PHASE cp -a libstdc++-v3/config/cpu/i{4,3}86/atomicity.h @@ -544,7 +538,7 @@ cd .. CC=gcc OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/\(-Wp,\)\?-D_FORTIFY_SOURCE=[12]//g'` OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-m64//g;s/-m32//g;s/-m31//g'` -%ifarch sparc sparc64 +%ifarch sparc OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mcpu=ultrasparc/-mtune=ultrasparc/g;s/-mcpu=v[78]//g'` %endif %ifarch %{ix86} @@ -601,11 +595,17 @@ CC="$CC" CFLAGS="$OPT_FLAGS" CXXFLAGS="`echo $OPT_FLAGS | sed 's/ -Wall / /g'`" %ifarch ppc ppc64 --enable-secureplt \ %endif -%ifarch sparc ppc ppc64 s390 s390x alpha +%ifarch sparc sparcv9 sparc64 ppc ppc64 s390 s390x alpha --with-long-double-128 \ %endif %ifarch sparc - --build=%{gcc_target_platform} --target=%{gcc_target_platform} --with-cpu=v7 + --disable-linux-futex \ +%endif +%ifarch sparc64 + --with-cpu=ultrasparc \ +%endif +%ifarch sparc sparcv9 + --host=%{gcc_target_platform} --build=%{gcc_target_platform} --target=%{gcc_target_platform} --with-cpu=v7 %endif %ifarch ppc --build=%{gcc_target_platform} --target=%{gcc_target_platform} --with-cpu=default32 @@ -616,7 +616,7 @@ CC="$CC" CFLAGS="$OPT_FLAGS" CXXFLAGS="`echo $OPT_FLAGS | sed 's/ -Wall / /g'`" %ifarch s390 s390x --with-tune=z9-109 \ %endif -%ifnarch sparc ppc +%ifnarch sparc sparcv9 ppc --build=%{gcc_target_platform} %endif @@ -788,7 +788,7 @@ done # shipping this for everybody is unnecessary. rm -rf $RPM_BUILD_ROOT%{_prefix}/include/c++/%{gcc_version}/%{gcc_target_platform}/bits/stdc++.h.gch -%ifarch sparc sparc64 +%ifarch sparcv9 sparc64 ln -f $RPM_BUILD_ROOT%{_prefix}/bin/%{gcc_target_platform}-gcc \ $RPM_BUILD_ROOT%{_prefix}/bin/sparc-%{_vendor}-%{_target_os}-gcc %endif @@ -797,7 +797,7 @@ ln -f $RPM_BUILD_ROOT%{_prefix}/bin/%{gcc_target_platform}-gcc \ $RPM_BUILD_ROOT%{_prefix}/bin/ppc-%{_vendor}-%{_target_os}-gcc %endif -%ifarch sparc ppc +%ifarch sparcv9 ppc FULLLPATH=$FULLPATH/lib32 %endif %ifarch sparc64 ppc64 @@ -827,7 +827,7 @@ mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgcc_s.so.1 $RPM_BUILD_ROOT/%{_lib}/li chmod 755 $RPM_BUILD_ROOT/%{_lib}/libgcc_s-%{gcc_version}-%{DATE}.so.1 ln -sf libgcc_s-%{gcc_version}-%{DATE}.so.1 $RPM_BUILD_ROOT/%{_lib}/libgcc_s.so.1 ln -sf /%{_lib}/libgcc_s.so.1 $FULLPATH/libgcc_s.so -%ifarch sparc ppc +%ifarch sparcv9 ppc ln -sf /lib64/libgcc_s.so.1 $FULLPATH/64/libgcc_s.so %endif %ifarch %{multilib_64_archs} @@ -913,7 +913,7 @@ mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libobjc.*a . mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgomp.*a . mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libmudflap{,th}.*a $FULLLPATH/ -%ifarch sparc ppc +%ifarch sparcv9 ppc ln -sf ../../../../../lib64/libobjc.so.2 64/libobjc.so ln -sf ../`echo ../../../../lib/libstdc++.so.6.* | sed s~/lib/~/lib64/~` 64/libstdc++.so ln -sf ../`echo ../../../../lib/libgfortran.so.3.* | sed s~/lib/~/lib64/~` 64/libgfortran.so @@ -1055,7 +1055,7 @@ rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libssp* rm -f $RPM_BUILD_ROOT%{_prefix}/lib/lib*.so* rm -f $RPM_BUILD_ROOT%{_prefix}/lib/lib*.a %else -%ifarch sparc ppc +%ifarch sparcv9 ppc rm -f $RPM_BUILD_ROOT%{_prefix}/lib64/lib*.so* rm -f $RPM_BUILD_ROOT%{_prefix}/lib64/lib*.a %endif @@ -1199,10 +1199,10 @@ fi %{_prefix}/bin/gcov %{_prefix}/bin/protoize %{_prefix}/bin/unprotoize -%ifarch sparc ppc +%ifarch ppc %{_prefix}/bin/%{_target_platform}-gcc %endif -%ifarch sparc64 +%ifarch sparc64 sparcv9 %{_prefix}/bin/sparc-%{_vendor}-%{_target_os}-gcc %endif %ifarch ppc64 @@ -1264,7 +1264,7 @@ fi %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgomp.spec %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgomp.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgomp.so -%ifarch sparc ppc +%ifarch sparcv9 ppc %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/crt*.o %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcc.a @@ -1292,7 +1292,7 @@ fi %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libmudflap.so %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libmudflapth.so %endif -%ifarch sparc sparc64 ppc ppc64 +%ifarch sparcv9 sparc64 ppc ppc64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflap.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflapth.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflap.so @@ -1333,7 +1333,7 @@ fi %dir %{_prefix}/libexec/gcc/%{gcc_target_platform} %dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version} %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/cc1plus -%ifarch sparc ppc +%ifarch sparcv9 ppc %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libstdc++.so %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libstdc++.a @@ -1345,11 +1345,11 @@ fi %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libstdc++.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/32/libsupc++.a %endif -%ifarch sparc ppc %{multilib_64_archs} +%ifarch sparcv9 ppc %{multilib_64_archs} %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.so %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libsupc++.a %endif -%ifarch sparc sparc64 ppc ppc64 +%ifarch sparcv9 sparc64 ppc ppc64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.a %endif %doc rpm.doc/changelogs/gcc/cp/ChangeLog* @@ -1368,7 +1368,7 @@ fi %dir %{_prefix}/lib/gcc %dir %{_prefix}/lib/gcc/%{gcc_target_platform} %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} -%ifarch sparc ppc +%ifarch sparcv9 ppc %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libstdc++.a %endif @@ -1376,10 +1376,10 @@ fi %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libstdc++.a %endif -%ifnarch sparc sparc64 ppc ppc64 +%ifnarch sparcv9 sparc64 ppc ppc64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.a %endif -%ifnarch sparc ppc %{multilib_64_archs} +%ifnarch sparcv9 ppc %{multilib_64_archs} %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.so %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libsupc++.a %endif @@ -1398,7 +1398,7 @@ fi %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/cc1obj %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libobjc.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libobjc.so -%ifarch sparc ppc +%ifarch sparcv9 ppc %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libobjc.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libobjc.so @@ -1443,7 +1443,7 @@ fi %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgfortranbegin.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgfortran.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgfortran.so -%ifarch sparc ppc +%ifarch sparcv9 ppc %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgfortranbegin.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgfortran.a @@ -1484,11 +1484,11 @@ fi %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/jvgenmain %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj.so %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj-tools.so -%ifarch sparc sparc64 ppc ppc64 +%ifarch sparcv9 sparc64 ppc ppc64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj_bc.so %endif %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgij.so -%ifarch sparc ppc +%ifarch sparcv9 ppc %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcj.so %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/64/libgcj-tools.so @@ -1578,7 +1578,7 @@ fi %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/jni_md.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/jvmpi.h %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj.spec -%ifarch sparc ppc +%ifarch sparcv9 ppc %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libgcj_bc.so %endif @@ -1586,7 +1586,7 @@ fi %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libgcj_bc.so %endif -%ifnarch sparc sparc64 ppc ppc64 +%ifnarch sparcv9 sparc64 ppc ppc64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libgcj_bc.so %endif %dir %{_prefix}/include/c++ @@ -1645,7 +1645,7 @@ fi %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version} %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/include/mf-runtime.h -%ifarch sparc ppc +%ifarch sparcv9 ppc %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libmudflap.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib32/libmudflapth.a @@ -1655,7 +1655,7 @@ fi %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libmudflap.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/lib64/libmudflapth.a %endif -%ifnarch sparc sparc64 ppc ppc64 +%ifnarch sparcv9 sparc64 ppc ppc64 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflap.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflapth.a %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libmudflap.so @@ -1664,6 +1664,40 @@ fi %doc rpm.doc/changelogs/libmudflap/ChangeLog* %changelog +* Mon Jun 9 2008 Jakub Jelinek 4.3.1-1 +- update from gcc-4_3-branch + - 4.3.1 release + - PRs ada/24880, ada/26635, bootstrap/35169, bootstrap/36452, c++/35578, + c++/35986, c++/36023, c++/36237, c++/36308, fortran/35184, + fortran/35743, fortran/35745, fortran/35756, fortran/35759, + fortran/35780, fortran/35864, fortran/35997, fortran/36176, + fortran/36233, libfortran/35990, libfortran/35993, libfortran/35995, + libgcj/36252, libstdc++/35922, middle-end/34973, middle-end/36013, + middle-end/36077, middle-end/36093, middle-end/36106, + middle-end/36137, middle-end/36154, middle-end/36172, + middle-end/36194, middle-end/36227, middle-end/36244, + middle-end/36300, middle-end/PR28690, rtl-optimization/36111, + rtl-optimization/36419, target/27386, target/30243, target/34932, + target/35661, target/35921, target/36079, target/36090, target/36095, + target/36182, target/36224, target/36321, target/36362, + tree-optimization/34244, tree-optimization/34330, + tree-optimization/34976, tree-optimization/35204, + tree-optimization/36098, tree-optimization/36119, + tree-optimization/36129, tree-optimization/36181, + tree-optimization/36187, tree-optimization/36245, + tree-optimization/36262, tree-optimization/36291, + tree-optimization/36293, tree-optimization/36339 +- OpenMP 3.0 support + +* Tue May 20 2008 Tom "spot" Callaway 4.3.0-11 +- fix missing file with sparcv9 + +* Sun May 18 2008 Tom "spot" Callaway 4.3.0-10 +- make sparcv9 the multilib_32_arch for sparc64 + +* Sun May 18 2008 Tom "spot" Callaway 4.3.0-9 +- sparcv9 support and detection + * Mon Apr 28 2008 Jakub Jelinek 4.3.0-8 - update from gcc-4_3-branch - decrease compile time stack usage during GC (#443739, PR debug/36060) diff --git a/sources b/sources index ba916c5..03648a8 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -5dd05f97c3d766c2369fdf52c3f71017 gcc-4.3.0-20080428.tar.bz2 +91abbb3cb390ca0441acec2bb0908eab gcc-4.3.1-20080609.tar.bz2 92a70f9e56223b653bce0f58f90cf950 fastjar-0.95.tar.gz