Commit | Line | Data |
---|---|---|
dc621c35 DE |
1 | /* This testcase is part of GDB, the GNU debugger. |
2 | ||
618f726f | 3 | Copyright 2009-2016 Free Software Foundation, Inc. |
dc621c35 DE |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 3 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | ||
18 | Check that watchpoints get propagated to all existing threads when the | |
19 | watchpoint is created. | |
20 | */ | |
21 | ||
22 | #include <stdio.h> | |
23 | #include <unistd.h> | |
24 | #include <stdlib.h> | |
25 | #include <stdint.h> | |
26 | #include <pthread.h> | |
27 | ||
28 | #ifndef NR_THREADS | |
29 | #define NR_THREADS 4 | |
30 | #endif | |
31 | ||
32 | #ifndef X_INCR_COUNT | |
33 | #define X_INCR_COUNT 10 | |
34 | #endif | |
35 | ||
36 | void *thread_function (void *arg); /* Function executed by each thread. */ | |
37 | ||
38 | pthread_mutex_t x_mutex; | |
39 | int x; | |
40 | ||
41 | /* Used to hold threads back until watchthreads2.exp is ready. */ | |
42 | int test_ready = 0; | |
43 | ||
44 | int | |
45 | main () | |
46 | { | |
47 | int res; | |
48 | pthread_t threads[NR_THREADS]; | |
49 | int i; | |
50 | ||
51 | pthread_mutex_init (&x_mutex, NULL); | |
52 | ||
53 | for (i = 0; i < NR_THREADS; ++i) | |
54 | { | |
55 | res = pthread_create (&threads[i], | |
56 | NULL, | |
57 | thread_function, | |
58 | (void *) (intptr_t) i); | |
59 | if (res != 0) | |
60 | { | |
61 | fprintf (stderr, "error in thread %d create\n", i); | |
62 | abort (); | |
63 | } | |
64 | } | |
65 | ||
66 | for (i = 0; i < NR_THREADS; ++i) | |
67 | { | |
68 | res = pthread_join (threads[i], NULL); | |
69 | if (res != 0) | |
70 | { | |
71 | fprintf (stderr, "error in thread %d join\n", i); | |
72 | abort (); | |
73 | } | |
74 | } | |
75 | ||
76 | exit (EXIT_SUCCESS); | |
77 | } | |
78 | ||
79 | /* Easy place for a breakpoint. | |
80 | watchthreads2.exp uses this to track when all threads are running | |
81 | instead of, for example, the program keeping track | |
82 | because we don't need the program to know when all threads are running, | |
83 | instead we need gdb to know when all threads are running. | |
84 | There is a delay between when a thread has started and when the thread | |
85 | has been registered with gdb. */ | |
86 | ||
87 | void | |
88 | thread_started () | |
89 | { | |
90 | } | |
91 | ||
92 | void * | |
93 | thread_function (void *arg) | |
94 | { | |
95 | int i; | |
96 | ||
97 | thread_started (); | |
98 | ||
99 | /* Don't start incrementing X until watchthreads2.exp is ready. */ | |
100 | while (! test_ready) | |
101 | usleep (1); | |
102 | ||
103 | for (i = 0; i < X_INCR_COUNT; ++i) | |
104 | { | |
105 | pthread_mutex_lock (&x_mutex); | |
106 | /* For debugging. */ | |
107 | printf ("Thread %ld changing x %d -> %d\n", (long) arg, x, x + 1); | |
108 | /* The call to usleep is so that when the watchpoint triggers, | |
109 | the pc is still on the same line. */ | |
110 | ++x; usleep (1); /* X increment. */ | |
111 | pthread_mutex_unlock (&x_mutex); | |
112 | } | |
113 | ||
114 | pthread_exit (NULL); | |
115 | } |