+2015-01-09  Pedro Alves  <palves@redhat.com>
+
+       * gdb.base/annota1.exp (thread_test): Use srcfile and binfile from
+       the global scope.  Set a breakpoint after all threads are started
+       rather than stepping over two source lines.  Expect the prompt.
+       * gdb.base/watch_thread_num.c (threads_started_barrier): New
+       global.
+       (NUM): Now 15.
+       (main): Use threads_started_barrier to wait for all threads to
+       start.  Main thread no longer calls thread_function.  Exit after
+       180 seconds.
+       (loop): New function.
+       (thread_function): Wait on threads_started_barrier barrier.  Call
+       'loop' at each iteration.
+       * gdb.base/watch_thread_num.exp: Continue to breakpoint after all
+       threads have started, instead of hardcoding number of "next"
+       steps.  Use an access watchpoint instead of a write watchpoint.
+
 2015-01-09  Pedro Alves  <palves@redhat.com>
 
        * gdb.threads/ia64-sigill.c (threads_started_barrier): New global.
 
 }
 
 proc thread_test {} {
-    global subdir srcdir testfile
+    global subdir srcdir testfile srcfile binfile
     global gdb_prompt old_gdb_prompt
     set srcfile watch_thread_num.c
     set binfile [standard_output_file ${testfile}-watch_thread_num]
            return
        }
 
+       set linenum [gdb_get_line_number "all threads started"]
+       gdb_breakpoint "$linenum"
+
        set gdb_prompt \
            "\r\n\032\032pre-prompt\r\n$gdb_prompt \r\n\032\032prompt\r\n"
 
            }
        }
 
-       gdb_test_multiple "next 2" "new thread" {
-           -re ".*\032\032new-thread" {
+       gdb_test_multiple "continue" "new thread" {
+           -re "\032\032new-thread.*\r\n$gdb_prompt$" {
                pass "new thread"
            }
        }
 
 
 void *thread_function (void *arg); /* Pointer to function executed by each thread */
 
-#define NUM 5
+static pthread_barrier_t threads_started_barrier;
+
+#define NUM 15
+
+static int num_threads = NUM;
 
 static unsigned int shared_var = 1;
 
     void *thread_result;
     long i;
 
+    pthread_barrier_init (&threads_started_barrier, NULL, NUM + 1);
+
     for (i = 0; i < NUM; i++)
       {
         res = pthread_create (&threads[i],
                             (void *) i);
       }
 
-    thread_result = thread_function ((void *) i);
+    pthread_barrier_wait (&threads_started_barrier);
+
+    sleep (180); /* all threads started */
 
     exit (EXIT_SUCCESS);
 }
 
+void
+loop (void)
+{
+}
+
 void *thread_function (void *arg) {
     int my_number = (long) arg;
+
+    pthread_barrier_wait (&threads_started_barrier);
+
     /* Don't run forever.  Run just short of it :)  */
     while (shared_var > 0)
       {
         shared_var++;
        usleep (1); /* Loop increment.  */
+       loop ();
       }
 
     pthread_exit (NULL);
 
 gdb_test "watch shared_var thread 0" "Unknown thread 0\." "Watchpoint on invalid thread"
 gdb_test "watch shared_var thread" "A syntax error in expression, near `thread'\." "Invalid watch syntax"
 
-gdb_test "Next 5" ".*"
+set bpexitline [gdb_get_line_number "all threads started"]
+gdb_breakpoint "$bpexitline"
+gdb_continue_to_breakpoint "all threads started"
 
-gdb_test "break thread_function" "Breakpoint \[0-9\].*" \
-  "Set breakpoint at thread_function"
+gdb_test "break loop" "Breakpoint \[0-9\].*" \
+  "Set breakpoint at loop"
 
-gdb_test "continue" ".*Breakpoint 2.*" "Stopped in thread_function"
+gdb_test "continue" ".*Breakpoint .*loop.*" "Stopped in loop"
 
 gdb_test_multiple "thread" "Thread command" {
     -re ".*Current thread is (\[0-9\]*).*$gdb_prompt $" {
 
 set thread_num "$expect_out(1,string)"
 
-gdb_test_no_output "disable 2" "Disable breakpoint 2"
-gdb_test "watch shared_var thread $thread_num" "Hardware watchpoint 3: shared_var" "Watchpoint on shared variable"
-gdb_test "info breakpoint 3" "stop only in thread $thread_num"
+delete_breakpoints
 
-for {set i 1} {$i <= 10} {incr i 1} {
+# We use an access watchpoint rather than a write watchpoint, because
+# GDB can drop the latter when multiple threads trigger events
+# simultaneously, on targets with continuable watchpoints, such as
+# x86.  See PR breakpoints/10116.
+
+gdb_test "awatch shared_var thread $thread_num" \
+    "Hardware access \\(read/write\\) watchpoint .*: shared_var.*" \
+    "Watchpoint on shared variable"
+
+gdb_test "info breakpoint \$bpnum" \
+    "stop only in thread $thread_num" \
+    "info breakpoint shows watchpoint is thread-specific"
+
+for {set i 1} {$i <= 5} {incr i} {
     set watchpoint "Watchpoint triggered iteration $i"
     set check "Check thread that triggered iteration $i"
 
-    gdb_test "continue" "Hardware watchpoint 3: shared_var.*" $watchpoint
+    set test $watchpoint
+    gdb_test_multiple "continue" $test {
+       -re "infrun:" {
+           # Avoid timeouts when debugging GDB.
+           exp_continue
+       }
+       -re "Hardware access \\(read/write\\) watchpoint .*: shared_var.*$gdb_prompt $" {
+           pass $test
+       }
+    }
     gdb_test "thread" ".*Current thread is $thread_num .*" $check
 }