From patchwork Thu Nov 3 17:44:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 123474 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D809AB6F0E for ; Fri, 4 Nov 2011 04:44:57 +1100 (EST) Received: (qmail 29620 invoked by alias); 3 Nov 2011 17:44:54 -0000 Received: (qmail 29590 invoked by uid 22791); 3 Nov 2011 17:44:47 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL, BAYES_50, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS, TW_BJ, TW_CP, TW_CX, TW_DC X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 03 Nov 2011 17:44:30 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pA3HiTmk014933 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 3 Nov 2011 13:44:29 -0400 Received: from houston.quesejoda.com (vpn-236-154.phx2.redhat.com [10.3.236.154]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id pA3HiTm3015937 for ; Thu, 3 Nov 2011 13:44:29 -0400 Message-ID: <4EB2D2FC.7010403@redhat.com> Date: Thu, 03 Nov 2011 12:44:28 -0500 From: Aldy Hernandez User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0) Gecko/20110927 Thunderbird/7.0 MIME-Version: 1.0 To: gcc-patches Subject: [patch] 1/n: trans-mem: libitm runtime tests Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org These are all new files, thus require no ChangeLog entries (for the tests themselves anyhow). However, I will post a separate ChangeLog for the entire libitm. Index: libitm/testsuite/Makefile.am =================================================================== --- libitm/testsuite/Makefile.am (.../trunk) (revision 0) +++ libitm/testsuite/Makefile.am (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,13 @@ +## Process this file with automake to produce Makefile.in. + +AUTOMAKE_OPTIONS = foreign dejagnu + +# May be used by various substitution variables. +gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) + +EXPECT = $(shell if test -f $(top_builddir)/../expect/expect; then \ + echo $(top_builddir)/../expect/expect; else echo expect; fi) + +_RUNTEST = $(shell if test -f $(top_srcdir)/../dejagnu/runtest; then \ + echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi) +RUNTEST = "$(_RUNTEST) $(AM_RUNTESTFLAGS)" Index: libitm/testsuite/libitm.c/clone-1.c =================================================================== --- libitm/testsuite/libitm.c/clone-1.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/clone-1.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,28 @@ +/* Verify that we can look up tm clone of transaction_callable + and transaction_pure. */ + +#include +#include + +static int x; + +int __attribute__((transaction_pure)) pure(int i) +{ + return i+2; +} + +int __attribute__((transaction_callable)) callable(void) +{ + return ++x; +} + +int main() +{ + if (_ITM_getTMCloneSafe (&pure) != &pure) + abort (); + + if (_ITM_getTMCloneSafe (&callable) == NULL) + abort (); + + return 0; +} Index: libitm/testsuite/libitm.c/dropref-2.c =================================================================== --- libitm/testsuite/libitm.c/dropref-2.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/dropref-2.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,36 @@ +/* { dg-xfail-run-if "unsupported" { *-*-* } } */ +#include +#include + +/* Test that _ITM_dropReferences() forces a commit of given chunk. */ + +unsigned char pp[100]; + +int main() +{ + int i; + + for(i=0; i < 100; ++i) + pp[i]=0x22; + + __transaction_atomic { + for(i=0; i < 100; ++i) + pp[i]=0x33; + + /* This should write-through pp[0..49]... */ + _ITM_dropReferences (pp, 50); + + /* ...while this should revert everything but pp[0..49]. */ + __transaction_cancel; + } + + for(i=0; i < 50; ++i) + if (pp[i] != 0x33) + abort(); + + for(i=50; i < 100; ++i) + if (pp[i] != 0x22) + abort(); + + return 0; +} Index: libitm/testsuite/libitm.c/dropref.c =================================================================== --- libitm/testsuite/libitm.c/dropref.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/dropref.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,12 @@ +/* { dg-xfail-run-if "unsupported" { *-*-* } } */ +#include + +char *pp; + +int main() +{ + __transaction_atomic { + _ITM_dropReferences (pp, 555); + } + return 0; +} Index: libitm/testsuite/libitm.c/reentrant.c =================================================================== --- libitm/testsuite/libitm.c/reentrant.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/reentrant.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,64 @@ +/* Tests that new transactions can be started from both transaction_pure and + transaction_unsafe code. This also requires proper handling of reentrant + nesting in the serial_lock implementation. */ + +#include +#include +#include + +int x = 0; + +int __attribute__((transaction_pure)) pure(int i) +{ + __transaction_atomic { + x++; + } + if (_ITM_inTransaction() == outsideTransaction) + abort(); + return i+1; +} + +int __attribute__((transaction_unsafe)) unsafe(int i) +{ + if (_ITM_inTransaction() != inIrrevocableTransaction) + abort(); + __transaction_atomic { + x++; + } + if (_ITM_inTransaction() != inIrrevocableTransaction) + abort(); + return i+1; +} + +static void *thread (void *dummy __attribute__((unused))) +{ + __transaction_atomic { + pure(1); + } + __transaction_relaxed { + unsafe(1); + } + return 0; +} + +int main() +{ + pthread_t pt; + int r = 0; + + __transaction_atomic { + r += pure(1) + x; + } + __transaction_relaxed { + r += unsafe(1) + x; + } + if (r != 7) + abort(); + + // Spawn a new thread to check that the serial lock is not held. + pthread_create(&pt, NULL, thread, NULL); + pthread_join(pt, NULL); + if (x != 4) + abort(); + return 0; +} Index: libitm/testsuite/libitm.c/cancel.c =================================================================== --- libitm/testsuite/libitm.c/cancel.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/cancel.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,55 @@ +#include +#include + +unsigned char pp[100]; + +void __attribute((transaction_may_cancel_outer,noinline)) cancel1() +{ + __transaction_cancel [[outer]]; +} + +int a, b; + +int main() +{ + a = b = 0; + + __transaction_atomic { + a = 1; + __transaction_atomic { + b = 1; + __transaction_cancel; + } + } + if (a != 1 || b != 0) + abort(); + if (_ITM_inTransaction() != outsideTransaction) + abort(); + + __transaction_atomic [[outer]] { + a = 2; + __transaction_atomic { + b = 2; + __transaction_cancel [[outer]]; + } + } + if (a != 1 || b != 0) + abort(); + if (_ITM_inTransaction() != outsideTransaction) + abort(); + + __transaction_atomic [[outer]] { + a = 2; + __transaction_atomic { + b = 2; + __transaction_cancel [[outer]]; + cancel1(); + } + } + if (a != 1 || b != 0) + abort(); + if (_ITM_inTransaction() != outsideTransaction) + abort(); + + return 0; +} Index: libitm/testsuite/libitm.c/simple-1.c =================================================================== --- libitm/testsuite/libitm.c/simple-1.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/simple-1.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,24 @@ +/* Verify that two sequential runs of a transaction will complete and + produce correct results. An early test of the library did in fact + leave things in an inconsistent state following the commit of the + first transaction. */ + +#include + +static int x; + +static void start (void) +{ + __transaction_atomic { x++; } +} + +int main() +{ + start (); + start (); + + if (x != 2) + abort (); + + return 0; +} Index: libitm/testsuite/libitm.c/memcpy-1.c =================================================================== --- libitm/testsuite/libitm.c/memcpy-1.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/memcpy-1.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,139 @@ +/* Verify memcpy operation. */ + +#include +#include +#include +#include +#include + +#define BEG_TRANSACTION \ + _ITM_beginTransaction (pr_instrumentedCode | pr_hasNoAbort \ + | pr_hasNoIrrevocable) +#define END_TRANSACTION \ + _ITM_commitTransaction () + +#define MEMCPY _ITM_memcpyRtWt + +static unsigned char *buf1, *buf2; +static size_t bufsize, page_size; +static int fail; + +static void +do_test (size_t align1, size_t align2, size_t len) +{ + size_t i, j; + unsigned char *s1, *s2; + unsigned char c1, c2; + + if (align1 + len >= bufsize) + return; + if (align2 + len >= bufsize) + return; + + c1 = random () >> 8; + c2 = random () >> 8; + memset (buf1, c1, bufsize); + memset (buf2, c2, bufsize); + + s1 = buf1 + align1; + s2 = buf2 + align2; + + for (i = 0, j = 1; i < len; i++, j += 23) + s1[i] = (j == c1 ? j + 1 : j); + + BEG_TRANSACTION; + MEMCPY (s2, s1, len); + END_TRANSACTION; + + if (memcmp (s1, s2, len) != 0) + { + printf ("Wrong result: dalign %zd salign %zd len %zd\n", + align2, align1, len); + fail = 1; + return; + } + + for (i = (align2 > 64 ? align2 - 64 : 0); i < align2; ++i) + if (buf2[i] != c2) + { + printf ("Garbage before: ofs %zd\n", i); + fail = 1; + break; + } + for (i = align2 + len, j = i+64 < bufsize ? i+64 : bufsize; i < j; ++i) + if (buf2[i] != c2) + { + printf ("Garbage after: ofs %zd\n", i); + fail = 1; + break; + } +} + +int main() +{ + size_t i, j; + + page_size = getpagesize (); + bufsize = 2 * page_size; + + buf1 = mmap (NULL, bufsize + 2*page_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (buf1 == MAP_FAILED) + return 1; + buf2 = mmap (NULL, bufsize + 2*page_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (buf2 == MAP_FAILED) + return 1; + + if (mprotect (buf1, page_size, PROT_NONE)) + return 1; + buf1 += page_size; + if (mprotect (buf1 + bufsize, page_size, PROT_NONE)) + return 1; + + if (mprotect (buf2, page_size, PROT_NONE)) + return 1; + buf2 += page_size; + if (mprotect (buf2 + bufsize, page_size, PROT_NONE)) + return 1; + + for (i = 0; i < 18; ++i) + { + size_t len = 1 << i; + + do_test (0, 0, len); + do_test (i, 0, len); + do_test (0, i, len); + do_test (i, i, len); + + do_test (0, bufsize - len, len); + do_test (bufsize - len, 0, len); + do_test (i, bufsize - len, len); + do_test (bufsize - len, i, len); + } + + for (i = 0; i < 32; ++i) + { + do_test (i, 0, i); + do_test (0, i, i); + do_test (i, i, i); + + for (j = 0; j < 32; ++j) + { + do_test (i, bufsize - i - j, i); + do_test (bufsize - i - j, i, i); + } + } + + for (i = 3; i < 32; ++i) + { + if ((i & (i - 1)) == 0) + continue; + do_test (0, 0, 16 * i); + do_test (i, 0, 16 * i); + do_test (0, i, 16 * i); + do_test (i, i, 16 * i); + } + + return fail; +} Index: libitm/testsuite/libitm.c/memset-1.c =================================================================== --- libitm/testsuite/libitm.c/memset-1.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/memset-1.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,102 @@ +/* Verify memcpy operation. */ + +#include +#include +#include +#include +#include + +#define BEG_TRANSACTION \ + _ITM_beginTransaction (pr_instrumentedCode | pr_hasNoAbort \ + | pr_hasNoIrrevocable) +#define END_TRANSACTION \ + _ITM_commitTransaction () + +#define MEMSET _ITM_memsetW + +static unsigned char *buf; +static size_t bufsize, page_size; +static int fail; + +static void +do_test (size_t align, size_t len) +{ + size_t i, j; + unsigned char c1, c2; + + if (align + len >= bufsize) + return; + + c1 = random () >> 8; + c2 = random () >> 8; + if (c1 == c2) + c1++; + memset (buf, c1, bufsize); + + BEG_TRANSACTION; + MEMSET (buf + align, c2, len); + END_TRANSACTION; + + i = (align > 64 ? align - 64 : 0); + for (; i < align; ++i) + if (buf[i] != c1) + { + printf ("Garbage before: ofs %zd\n", i); + fail = 1; + break; + } + for (; i < align + len; ++i) + if (buf[i] != c2) + { + printf ("Wrong result: ofs %zd\n", i); + fail = 1; + break; + } + for (j = i + 64 < bufsize ? i + 64 : bufsize; i < j; ++i) + if (buf[i] != c1) + { + printf ("Garbage after: ofs %zd\n", i); + fail = 1; + break; + } +} + +int main() +{ + size_t i, j; + + page_size = getpagesize (); + bufsize = 2 * page_size; + + buf = mmap (NULL, bufsize + 2*page_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (buf == MAP_FAILED) + return 1; + + if (mprotect (buf, page_size, PROT_NONE)) + return 1; + buf += page_size; + if (mprotect (buf + bufsize, page_size, PROT_NONE)) + return 1; + + for (i = 0; i < 18; ++i) + { + size_t len = 1 << i; + do_test (0, len); + do_test (bufsize - len, len); + } + + for (i = 0; i < 32; ++i) + for (j = 0; j < 32; ++j) + do_test (j, i); + + for (i = 3; i < 32; ++i) + { + if ((i & (i - 1)) == 0) + continue; + do_test (0, 16 * i); + do_test (i, 16 * i); + } + + return fail; +} Index: libitm/testsuite/libitm.c/notx.c =================================================================== --- libitm/testsuite/libitm.c/notx.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/notx.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,33 @@ +/* These tests all check whether initialization happens properly even if no + transaction has been used in the current thread yet. */ +#include +#include +#include + +static void *test1 (void *dummy __attribute__((unused))) +{ + if (_ITM_inTransaction() != outsideTransaction) + abort(); + return NULL; +} + +static void *test2 (void *dummy __attribute__((unused))) +{ + if (_ITM_getTransactionId() != _ITM_noTransactionId) + abort(); + return NULL; +} + + +int main() +{ + pthread_t thread; + + pthread_create(&thread, NULL, test1, NULL); + pthread_join(thread, NULL); + + pthread_create(&thread, NULL, test2, NULL); + pthread_join(thread, NULL); + + return 0; +} Index: libitm/testsuite/libitm.c/simple-2.c =================================================================== --- libitm/testsuite/libitm.c/simple-2.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/simple-2.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,29 @@ +/* Simplest test involving real threads. Verify we get the correct answer. */ + +#include +#include + +static int x; + +static void *start (void *dummy __attribute__((unused))) +{ + __transaction_atomic { x++; } + return NULL; +} + +int main() +{ + pthread_t p[10]; + int i; + + for (i = 0; i < 10; ++i) + pthread_create (p+i, NULL, start, NULL); + + for (i = 0; i < 10; ++i) + pthread_join (p[i], NULL); + + if (x != 10) + abort (); + + return 0; +} Index: libitm/testsuite/libitm.c/c.exp =================================================================== --- libitm/testsuite/libitm.c/c.exp (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/c.exp (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,30 @@ +if [info exists lang_library_path] then { + unset lang_library_path + unset lang_link_flags +} +if [info exists lang_test_file] then { + unset lang_test_file +} + +load_lib libitm-dg.exp + +# If a testcase doesn't have special options, use these. +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS "-O2" +} + +# Initialize dg. +dg-init + +# Gather a list of all tests. +set tests [lsort [find $srcdir/$subdir *.c]] + +set ld_library_path $always_ld_library_path +append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] +set_ld_library_path_env_vars + +# Main loop. +dg-runtest $tests "" $DEFAULT_CFLAGS + +# All done. +dg-finish Index: libitm/testsuite/libitm.c/txrelease.c =================================================================== --- libitm/testsuite/libitm.c/txrelease.c (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c/txrelease.c (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,47 @@ +/* This test triggers execution of the code that releases per-thread + transaction data when a thread exists, potentially repeatedly. However, + we currently cannot check whether the data has indeed been released. */ + +#include +#include +#include + +static int round = 0; +static pthread_key_t key; + +static void +thread_exit_handler(void *dummy __attribute__((unused))) +{ + if (round == 0) + abort(); + if (round == 1) + { + // ??? It would be good if we could check here that the transaction has + // indeed been released. + __transaction_atomic { round++; } + if (pthread_setspecific(key, &round)) + abort(); + } + // ??? It would be good if we could check here that the transaction has + // indeed been released (again). +} + +static void *thread (void *dummy __attribute__((unused))) +{ + if (pthread_key_create(&key, thread_exit_handler)) + abort(); + if (pthread_setspecific(key, &round)) + abort(); + __transaction_atomic { round++; } + return NULL; +} + +int main() +{ + pthread_t pt; + pthread_create(&pt, NULL, thread, NULL); + pthread_join(pt, NULL); + if (round != 2) + abort(); + return 0; +} Index: libitm/testsuite/config/default.exp =================================================================== --- libitm/testsuite/config/default.exp (.../trunk) (revision 0) +++ libitm/testsuite/config/default.exp (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,17 @@ +# Copyright (C) 1997 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +load_lib "standard.exp" Index: libitm/testsuite/lib/libitm-dg.exp =================================================================== --- libitm/testsuite/lib/libitm-dg.exp (.../trunk) (revision 0) +++ libitm/testsuite/lib/libitm-dg.exp (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,7 @@ +proc libitm-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 libitm_target_compile $prog $do_what $extra_tool_flags] +} + +proc libitm-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} Index: libitm/testsuite/lib/libitm.exp =================================================================== --- libitm/testsuite/lib/libitm.exp (.../trunk) (revision 0) +++ libitm/testsuite/lib/libitm.exp (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,216 @@ +# Damn dejagnu for not having proper library search paths for load_lib. +# We have to explicitly load everything that gcc-dg.exp wants to load. + +proc load_gcc_lib { filename } { + global srcdir loaded_libs + + load_file $srcdir/../../gcc/testsuite/lib/$filename + set loaded_libs($filename) "" +} + +load_lib dg.exp +load_gcc_lib file-format.exp +load_gcc_lib target-supports.exp +load_gcc_lib target-supports-dg.exp +load_gcc_lib scanasm.exp +load_gcc_lib scandump.exp +load_gcc_lib scanrtl.exp +load_gcc_lib scantree.exp +load_gcc_lib scanipa.exp +load_gcc_lib prune.exp +load_gcc_lib target-libpath.exp +load_gcc_lib wrapper.exp +load_gcc_lib gcc-defs.exp +load_gcc_lib torture-options.exp +load_gcc_lib timeout.exp +load_gcc_lib timeout-dg.exp +load_gcc_lib gcc-dg.exp +load_gcc_lib gfortran-dg.exp + +set dg-do-what-default run + +# +# GCC_UNDER_TEST is the compiler under test. +# + +set libitm_compile_options "" + +# +# libitm_init +# + +if [info exists TOOL_OPTIONS] { + set multilibs [get_multilibs $TOOL_OPTIONS] +} else { + set multilibs [get_multilibs] +} + +proc libitm_init { args } { + global srcdir blddir objdir tool_root_dir + global libitm_initialized + global tmpdir + global blddir + global gluefile wrap_flags + global ALWAYS_CFLAGS + global CFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global GCC_UNDER_TEST + global TESTING_IN_BUILD_TREE + global target_triplet + global always_ld_library_path + + set blddir [lookfor_file [get_multilibs] libitm] + + # We set LC_ALL and LANG to C so that we get the same error + # messages as expected. + setenv LC_ALL C + setenv LANG C + + if ![info exists GCC_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GCC_UNDER_TEST $TOOL_EXECUTABLE + } else { + set GCC_UNDER_TEST "[find_gcc]" + } + } + + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + if {![info exists CFLAGS]} { + set CFLAGS "" + } + + # Locate libgcc.a so we don't need to account for different values of + # SHLIB_EXT on different platforms + set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] + if {$gccdir != ""} { + set gccdir [file dirname $gccdir] + } + + # Compute what needs to be put into LD_LIBRARY_PATH + set always_ld_library_path ".:${blddir}/.libs" + + # Compute what needs to be added to the existing LD_LIBRARY_PATH. + if {$gccdir != ""} { + # Add AIX pthread directory first. + if { [llength [glob -nocomplain ${gccdir}/pthread/libgcc_s*.a]] >= 1 } { + append always_ld_library_path ":${gccdir}/pthread" + } + append always_ld_library_path ":${gccdir}" + set compiler [lindex $GCC_UNDER_TEST 0] + + if { [is_remote host] == 0 && [which $compiler] != 0 } { + foreach i "[exec $compiler --print-multi-lib]" { + set mldir "" + regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir + set mldir [string trimright $mldir "\;@"] + if { "$mldir" == "." } { + continue + } + if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } { + append always_ld_library_path ":${gccdir}/${mldir}" + } + } + } + } + + set ALWAYS_CFLAGS "" + if { $blddir != "" } { + lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/" + lappend ALWAYS_CFLAGS "additional_flags=-I${blddir}" + lappend ALWAYS_CFLAGS "ldflags=-L${blddir}/.libs" + } + lappend ALWAYS_CFLAGS "additional_flags=-I${srcdir}/.." + lappend ALWAYS_CFLAGS "ldflags=-litm" + + # We use atomic operations in the testcases to validate results. + if { ([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_effective_target_ilp32] } { + lappend ALWAYS_CFLAGS "additional_flags=-march=i486" + } + + if [istarget *-*-darwin*] { + lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc" + } + + if [istarget sparc*-*-*] { + lappend ALWAYS_CFLAGS "additional_flags=-mcpu=v9" + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_CFLAGS "additional_flags=$TOOL_OPTIONS" + } + + # Make sure that lines are not wrapped. That can confuse the + # error-message parsing machinery. + lappend ALWAYS_CFLAGS "additional_flags=-fmessage-length=0" + + # Turn on transactional memory support. + lappend ALWAYS_CFLAGS "additional_flags=-fgnu-tm" +} + +# +# libitm_target_compile -- compile a source file +# + +proc libitm_target_compile { source dest type options } { + global blddir + global libitm_compile_options + global gluefile wrap_flags + global ALWAYS_CFLAGS + global GCC_UNDER_TEST + global lang_test_file + global lang_library_path + global lang_link_flags + + if { [info exists lang_test_file] } { + if { $blddir != "" } { + lappend options "ldflags=-L${blddir}/${lang_library_path}" + } + lappend options "ldflags=${lang_link_flags}" + } + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + lappend options "additional_flags=[libio_include_flags]" + lappend options "timeout=[timeout_value]" + lappend options "compiler=$GCC_UNDER_TEST" + + set options [concat $libitm_compile_options $options] + + if [info exists ALWAYS_CFLAGS] { + set options [concat "$ALWAYS_CFLAGS" $options] + } + + set options [dg-additional-files-options $options $source] + + set result [target_compile $source $dest $type $options] + + return $result +} + +proc libitm_option_help { } { + send_user " --additional_options,OPTIONS\t\tUse OPTIONS to compile the testcase files. OPTIONS should be comma-separated.\n" +} + +proc libitm_option_proc { option } { + if [regexp "^--additional_options," $option] { + global libitm_compile_options + regsub "--additional_options," $option "" option + foreach x [split $option ","] { + lappend libitm_compile_options "additional_flags=$x" + } + return 1 + } else { + return 0 + } +} Index: libitm/testsuite/libitm.c++/static_ctor.C =================================================================== --- libitm/testsuite/libitm.c++/static_ctor.C (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c++/static_ctor.C (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,38 @@ +// { dg-do run } +/* Tests static constructors inside of transactional code. */ + +#include +#include + +int f(int x) __attribute__((noinline,transaction_safe)); +int f(int x) +{ + static int y = x; + return y*x; +} + +static void *thread (void *) +{ + int bar; + __transaction_atomic { bar = f(10); } + if (bar != 100) + abort(); + return 0; +} + +int main() +{ + int bar; + + // First, initialize y in another thread. + pthread_t pt; + pthread_create(&pt, NULL, thread, NULL); + pthread_join(pt, NULL); + + // Now y should already be initialized. + __transaction_atomic { bar = f(20); } + if (bar != 200) + abort(); + + return 0; +} Index: libitm/testsuite/libitm.c++/dropref.C =================================================================== --- libitm/testsuite/libitm.c++/dropref.C (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c++/dropref.C (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,12 @@ +/* { dg-xfail-run-if "unsupported" { *-*-* } } */ +#include + +char *pp; + +int main() +{ + __transaction_atomic { + _ITM_dropReferences (pp, 555); + } + return 0; +} Index: libitm/testsuite/libitm.c++/c++.exp =================================================================== --- libitm/testsuite/libitm.c++/c++.exp (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c++/c++.exp (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,60 @@ +load_lib libitm-dg.exp + +global shlib_ext + +set shlib_ext [get_shlib_extension] +set lang_link_flags "-lstdc++" +set lang_test_file_found 0 +set lang_library_path "../libstdc++-v3/src/.libs" + +# Initialize dg. +dg-init + +set blddir [lookfor_file [get_multilibs] libgomp] + + +if { $blddir != "" } { + # Look for a static libstdc++ first. + if [file exists "${blddir}/${lang_library_path}/libstdc++.a"] { + set lang_test_file "${lang_library_path}/libstdc++.a" + set lang_test_file_found 1 + # We may have a shared only build, so look for a shared libstdc++. + } elseif [file exists "${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"] { + set lang_test_file "${lang_library_path}/libstdc++.${shlib_ext}" + set lang_test_file_found 1 + } else { + puts "No libstdc++ library found, will not execute c++ tests" + } +} elseif { [info exists GXX_UNDER_TEST] } { + set lang_test_file_found 1 + # Needs to exist for libgomp.exp. + set lang_test_file "" +} else { + puts "GXX_UNDER_TEST not defined, will not execute c++ tests" +} + +if { $lang_test_file_found } { + # Gather a list of all tests. + set tests [lsort [glob -nocomplain $srcdir/$subdir/*.C]] + + if { $blddir != "" } { + set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}" + } else { + set ld_library_path "$always_ld_library_path" + } + append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] + set_ld_library_path_env_vars + + set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags" + if { [file exists $flags_file] } { + set libstdcxx_includes [exec sh $flags_file --build-includes] + } else { + set libstdcxx_includes "" + } + + # Main loop. + gfortran-dg-runtest $tests $libstdcxx_includes +} + +# All done. +dg-finish Index: libitm/testsuite/libitm.c++/eh-1.C =================================================================== --- libitm/testsuite/libitm.c++/eh-1.C (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c++/eh-1.C (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,36 @@ +// { dg-do run } + +extern "C" void abort (); + +int dothrow; +int g; + +static void f1() +{ + g++; + if (dothrow) + throw 1; +} + +static void f2() +{ + __transaction_atomic { + f1(); + } +} + +int main() +{ + dothrow = 0; + f2(); + + dothrow = 1; + try { + f2(); + } catch (...) { + } + + if (g != 2) + abort (); + return 0; +} Index: libitm/testsuite/libitm.c++/throwdown.C =================================================================== --- libitm/testsuite/libitm.c++/throwdown.C (.../trunk) (revision 0) +++ libitm/testsuite/libitm.c++/throwdown.C (.../branches/transactional-memory) (revision 180773) @@ -0,0 +1,13 @@ +// { dg-do compile } + +#include + +static void throwit() { + throw 1; +} + +void tranfunc() { + __transaction_atomic { + throwit(); + } +}