Index: gdb-6.6/gdb/testsuite/gdb.threads/atomic-seq-threaded.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gdb-6.6/gdb/testsuite/gdb.threads/atomic-seq-threaded.c 2007-06-18 20:24:04.000000000 +0200 @@ -0,0 +1,171 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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. */ + +/* Test stepping over RISC atomic sequences. + This variant testcases the code for stepping another thread while skipping + over the atomic sequence in the former thread + (STEPPING_PAST_SINGLESTEP_BREAKPOINT). + Code comes from gcc/testsuite/gcc.dg/sync-2.c */ + +/* { dg-options "-march=i486" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ +/* { dg-options "-mcpu=v9" { target sparc*-*-* } } */ + +/* Test functionality of the intrinsics for 'short' and 'char'. */ + +#include +#include +#include +#include +#include + +#define LOOPS 2 + +static int unused; + +static char AI[18]; +static char init_qi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; +static char test_qi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; + +static void +do_qi (void) +{ + if (__sync_fetch_and_add(AI+4, 1) != 0) + abort (); + if (__sync_fetch_and_add(AI+5, 4) != 0) + abort (); + if (__sync_fetch_and_add(AI+6, 22) != 0) + abort (); + if (__sync_fetch_and_sub(AI+7, 12) != 0) + abort (); + if (__sync_fetch_and_and(AI+8, 7) != (char)-1) + abort (); + if (__sync_fetch_and_or(AI+9, 8) != 0) + abort (); + if (__sync_fetch_and_xor(AI+10, 9) != 0) + abort (); + if (__sync_fetch_and_nand(AI+11, 7) != 0) + abort (); + + if (__sync_add_and_fetch(AI+12, 1) != 1) + abort (); + if (__sync_sub_and_fetch(AI+13, 12) != (char)-12) + abort (); + if (__sync_and_and_fetch(AI+14, 7) != 7) + abort (); + if (__sync_or_and_fetch(AI+15, 8) != 8) + abort (); + if (__sync_xor_and_fetch(AI+16, 9) != 9) + abort (); + if (__sync_nand_and_fetch(AI+17, 7) != 7) + abort (); +} + +static short AL[18]; +static short init_hi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; +static short test_hi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; + +static void +do_hi (void) +{ + if (__sync_fetch_and_add(AL+4, 1) != 0) + abort (); + if (__sync_fetch_and_add(AL+5, 4) != 0) + abort (); + if (__sync_fetch_and_add(AL+6, 22) != 0) + abort (); + if (__sync_fetch_and_sub(AL+7, 12) != 0) + abort (); + if (__sync_fetch_and_and(AL+8, 7) != -1) + abort (); + if (__sync_fetch_and_or(AL+9, 8) != 0) + abort (); + if (__sync_fetch_and_xor(AL+10, 9) != 0) + abort (); + if (__sync_fetch_and_nand(AL+11, 7) != 0) + abort (); + + if (__sync_add_and_fetch(AL+12, 1) != 1) + abort (); + if (__sync_sub_and_fetch(AL+13, 12) != -12) + abort (); + if (__sync_and_and_fetch(AL+14, 7) != 7) + abort (); + if (__sync_or_and_fetch(AL+15, 8) != 8) + abort (); + if (__sync_xor_and_fetch(AL+16, 9) != 9) + abort (); + if (__sync_nand_and_fetch(AL+17, 7) != 7) + abort (); +} + +static void * +start1 (void *arg) +{ + unsigned loop; + sleep(1); + + for (loop = 0; loop < LOOPS; loop++) + { + memcpy(AI, init_qi, sizeof(init_qi)); + + do_qi (); + + if (memcmp (AI, test_qi, sizeof(test_qi))) + abort (); + } + + return arg; /* _delete1_ */ +} + +static void * +start2 (void *arg) +{ + unsigned loop; + + for (loop = 0; loop < LOOPS; loop++) + { + memcpy(AL, init_hi, sizeof(init_hi)); + + do_hi (); + + if (memcmp (AL, test_hi, sizeof(test_hi))) + abort (); + } + + return arg; /* _delete2_ */ +} + +int +main (int argc, char **argv) +{ + pthread_t thread; + int i; + + i = pthread_create (&thread, NULL, start1, NULL); /* _create_ */ + assert (i == 0); /* _create_behind_ */ + + sleep(1); + + start2 (NULL); + + i = pthread_join (thread, NULL); /* _delete_ */ + assert (i == 0); + + return 0; /* _success_ */ +} Index: gdb-6.6/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gdb-6.6/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp 2007-06-18 20:24:04.000000000 +0200 @@ -0,0 +1,110 @@ +# atomic-seq-threaded.exp -- Test case for stepping over RISC atomic code seqs. +# This variant testcases the code for stepping another thread while skipping +# over the atomic sequence in the former thread +# (STEPPING_PAST_SINGLESTEP_BREAKPOINT). +# Copyright (C) 2007 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +set testfile atomic-seq-threaded +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +foreach opts {{} {compiler=gcc4} {FAIL}} { + if {$opts eq "FAIL"} { + return -1 + } + if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $opts]] eq "" } { + break + } +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +gdb_load ${binfile} +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +# pthread_create () will not pass even on x86_64 with software watchpoint. +# Skip behind pthread_create () without any watchpoint active. + +set line [gdb_get_line_number "_create_behind_"] +gdb_test "tbreak $line" \ + "Breakpoint (\[0-9\]+) at .*$srcfile, line $line\..*" \ + "set breakpoint behind pthread_create ()" +gdb_test "c" \ + ".*/\\* _create_behind_ \\*/.*" \ + "run till behind pthread_create ()" + +# Without a watchpoint being software no single-stepping would be used. +set test "Start (software) watchpoint" +gdb_test_multiple "watch unused" $test { + -re "Watchpoint \[0-9\]+: unused.*$gdb_prompt $" { + pass $test + } + -re "Hardware watchpoint \[0-9\]+: unused.*$gdb_prompt $" { + # We do not test the goal but still the whole testcase should pass. + unsupported $test + } +} +gdb_test "set \$watchnum=\$bpnum" "" "Store the watchpoint number" + +# pthread_join () will not pass even on x86_64 with software watchpoint. +# Now pass the __sync_* () functions and remove the watchpoint. + +#set line [gdb_get_line_number "_delete_"] +#gdb_test "break $line" \ +# "Breakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \ +# "set breakpoint at _delete_" +#gdb_test "set \$deletenum=\$bpnum" "" "Store the _delete_ breakpoint number" +#set line1 [gdb_get_line_number "_delete1_"] +#gdb_test "break $line1" \ +# "Breakpoint \[0-9\]+ at .*$srcfile, line $line1\..*" \ +# "set breakpoint at _delete1_" +#gdb_test "set \$delete1num=\$bpnum" "" "Store the _delete1_ breakpoint number" +#set line2 [gdb_get_line_number "_delete2_"] +#gdb_test "break $line2" \ +# "Breakpoint \[0-9\]+ at .*$srcfile, line $line2\..*" \ +# "set breakpoint at _delete2_" +#gdb_test "set \$delete2num=\$bpnum" "" "Store the _delete2_ breakpoint number" +#gdb_test "c" \ +# ".*/\\* (_delete_|_delete1_|_delete2_) \\*/.*" \ +# "run till (_delete_|_delete1_|_delete2_)" +#gdb_test "delete \$watchnum" "" "Delete the watchpoint" +#gdb_test "delete \$deletenum" "" "Delete the _delete_ breakpoint" +#gdb_test "delete \$delete1num" "" "Delete the _delete1_ breakpoint" +#gdb_test "delete \$delete2num" "" "Delete the _delete2_ breakpoint" + +# Pass pthread_join () without the software watchpoint being active. + +set line [gdb_get_line_number "_success_"] +gdb_test "tbreak $line" \ + "Breakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \ + "set breakpoint at _success_" +set timeout 1800 +gdb_test "c" \ + ".*/\\* _success_ \\*/.*" \ + "run till _success_" + +gdb_test "c" \ + ".*Program exited normally\\..*" \ + "run till program exit"