Commit | Line | Data |
---|---|---|
4c38e0a4 | 1 | # Copyright (C) 1996, 1997, 2002, 2003, 2007, 2008, 2009, 2010 |
9b254dd1 | 2 | # Free Software Foundation, Inc. |
0312286c DJ |
3 | |
4 | # This program is free software; you can redistribute it and/or modify | |
5 | # it under the terms of the GNU General Public License as published by | |
e22f8b7c | 6 | # the Free Software Foundation; either version 3 of the License, or |
0312286c | 7 | # (at your option) any later version. |
e22f8b7c | 8 | # |
0312286c DJ |
9 | # This program is distributed in the hope that it will be useful, |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. | |
e22f8b7c | 13 | # |
0312286c | 14 | # You should have received a copy of the GNU General Public License |
e22f8b7c | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
0312286c | 16 | |
0312286c DJ |
17 | # This file was written by Daniel Jacobowitz <drow@mvista.com> |
18 | # (parts based on pthreads.exp by Fred Fish (fnf@cygnus.com). | |
19 | # | |
20 | # This test covers the various forms of "set scheduler-locking". | |
21 | ||
22 | if $tracelevel then { | |
23 | strace $tracelevel | |
24 | } | |
25 | ||
0312286c DJ |
26 | |
27 | set testfile "schedlock" | |
28 | set srcfile ${testfile}.c | |
29 | set binfile ${objdir}/${subdir}/${testfile} | |
30 | ||
18ecae38 DJ |
31 | # The number of threads, including the main thread. |
32 | set NUM 2 | |
33 | ||
b5ab8ff3 | 34 | if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { |
0312286c DJ |
35 | return -1 |
36 | } | |
37 | ||
38 | # Now we can proceed with the real testing. | |
39 | ||
40 | proc get_args { } { | |
9db70545 MS |
41 | global list_count |
42 | global gdb_prompt | |
43 | global NUM | |
e09490f1 | 44 | |
9db70545 MS |
45 | set pattern "(\[0-9\]+)" |
46 | for {set i 1} {[expr $i < $NUM]} {incr i} { | |
47 | append pattern ", (\[0-9\]+)" | |
48 | } | |
0312286c | 49 | |
9db70545 MS |
50 | gdb_test_multiple "print args" "listed args ($list_count)" { |
51 | -re "\\\$\[0-9\]+ = {$pattern}.*$gdb_prompt $" { | |
52 | set list_count [expr $list_count + 1] | |
53 | pass "listed args ($list_count)" | |
e09490f1 | 54 | |
9db70545 MS |
55 | set result "" |
56 | for {set i 1} {[expr $i <= $NUM]} {incr i} { | |
57 | lappend result $expect_out($i,string) | |
58 | } | |
59 | return $result | |
e09490f1 | 60 | } |
9db70545 | 61 | } |
0312286c DJ |
62 | } |
63 | ||
64 | proc stop_process { description } { | |
65 | global gdb_prompt | |
66 | ||
67 | # For this to work we must be sure to consume the "Continuing." | |
68 | # message first, or GDB's signal handler may not be in place. | |
69 | after 1000 {send_gdb "\003"} | |
70 | gdb_expect { | |
71 | -re "Program received signal SIGINT.*$gdb_prompt $" | |
72 | { | |
73 | pass $description | |
74 | } | |
75 | timeout | |
76 | { | |
77 | fail "$description (timeout)" | |
78 | } | |
79 | } | |
80 | } | |
81 | ||
82 | proc get_current_thread { description } { | |
9db70545 | 83 | global gdb_prompt |
0312286c | 84 | |
9db70545 MS |
85 | gdb_test_multiple "bt" "$description" { |
86 | -re "thread_function \\(arg=0x(\[0-9\])\\).*$gdb_prompt $" { | |
87 | pass $description | |
88 | return $expect_out(1,string) | |
89 | } | |
90 | } | |
91 | return "" | |
0312286c DJ |
92 | } |
93 | ||
94 | proc my_continue { msg } { | |
9db70545 MS |
95 | gdb_test_multiple "continue" "continuing ($msg)" { |
96 | -re "Continuing" { | |
97 | pass "continue ($msg)" | |
98 | } | |
99 | } | |
0312286c | 100 | |
9db70545 | 101 | stop_process "stop all threads ($msg)" |
0312286c | 102 | |
9db70545 MS |
103 | # Make sure we're in one of the non-main looping threads. |
104 | gdb_breakpoint [concat [gdb_get_line_number "schedlock.exp: main loop"] " if arg != 0"] | |
105 | gdb_continue_to_breakpoint "return to loop ($msg)" | |
106 | delete_breakpoints | |
0312286c DJ |
107 | } |
108 | ||
109 | proc step_ten_loops { msg } { | |
110 | global gdb_prompt | |
111 | ||
112 | for {set i 0} {[expr $i < 10]} {set i [expr $i + 1]} { | |
0312286c | 113 | set other_step 0 |
9db70545 | 114 | gdb_test_multiple "step" "step to increment ($msg $i)" { |
0312286c DJ |
115 | -re ".*myp\\) \\+\\+;\[\r\n\]+$gdb_prompt $" { |
116 | pass "step to increment ($msg $i)" | |
117 | } | |
118 | -re "$gdb_prompt $" { | |
119 | if {$other_step == 0} { | |
120 | set other_step 1 | |
121 | send_gdb "step\n" | |
122 | exp_continue | |
123 | } else { | |
124 | fail "step to increment ($msg $i)" | |
125 | # FIXME cascade? | |
126 | } | |
127 | } | |
0312286c DJ |
128 | } |
129 | } | |
130 | } | |
131 | ||
132 | # Start with a fresh gdb. | |
133 | ||
134 | gdb_exit | |
135 | gdb_start | |
136 | gdb_reinitialize_dir $srcdir/$subdir | |
137 | ||
138 | # We'll need this when we send_gdb a ^C to GDB. Need to do it before we | |
139 | # run the program and gdb starts saving and restoring tty states. | |
140 | # On Ultrix, we don't need it and it is really slow (because shell_escape | |
141 | # doesn't use vfork). | |
142 | if ![istarget "*-*-ultrix*"] then { | |
143 | gdb_test "shell stty intr '^C'" "" | |
144 | } | |
145 | ||
146 | gdb_load ${binfile} | |
147 | ||
148 | gdb_test "set print sevenbit-strings" "" | |
149 | gdb_test "set width 0" "" | |
150 | ||
151 | runto_main | |
152 | ||
153 | # See if scheduler locking is available on this target. | |
0312286c | 154 | global gdb_prompt |
9db70545 MS |
155 | gdb_test_multiple "set scheduler-locking off" "scheduler locking set to none" { |
156 | -re "Target .* cannot support this command" { | |
157 | unsupported "target does not support scheduler locking" | |
158 | return | |
0312286c | 159 | } |
9db70545 MS |
160 | -re "$gdb_prompt $" { |
161 | pass "scheduler locking set to none" | |
0312286c | 162 | } |
9db70545 MS |
163 | timeout { |
164 | unsupported "target does not support scheduler locking (timeout)" | |
165 | return | |
0312286c DJ |
166 | } |
167 | } | |
168 | ||
169 | gdb_breakpoint [gdb_get_line_number "schedlock.exp: last thread start"] | |
170 | gdb_continue_to_breakpoint "all threads started" | |
171 | ||
172 | global list_count | |
173 | set list_count 0 | |
174 | ||
175 | set start_args [get_args] | |
176 | ||
177 | # First make sure that all threads are alive. | |
178 | my_continue "initial" | |
179 | ||
180 | set cont_args [get_args] | |
181 | ||
e09490f1 | 182 | set bad 0 |
18ecae38 | 183 | for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { |
0312286c | 184 | if {[lindex $start_args $i] == [lindex $cont_args $i]} { |
e09490f1 | 185 | incr bad |
0312286c DJ |
186 | } |
187 | } | |
e09490f1 | 188 | if { $bad == 0 } { |
18ecae38 DJ |
189 | pass "all threads alive" |
190 | } else { | |
e09490f1 | 191 | fail "all threads alive ($bad/$NUM did not run)" |
18ecae38 | 192 | } |
0312286c DJ |
193 | |
194 | # We can't change threads, unfortunately, in current GDB. Use | |
195 | # whichever we stopped in. | |
196 | set curthread [get_current_thread "find current thread (1)"] | |
197 | ||
198 | ||
199 | ||
200 | ||
201 | # Test stepping without scheduler locking. | |
202 | gdb_test "set scheduler-locking off" "" | |
203 | ||
204 | step_ten_loops "unlocked" | |
205 | ||
206 | # Make sure we're still in the same thread. | |
207 | set newthread [get_current_thread "find current thread (2)"] | |
208 | if {$curthread == $newthread} { | |
209 | pass "step without lock does not change thread" | |
210 | } else { | |
211 | fail "step without lock does not change thread (switched to thread $newthread)" | |
212 | } | |
213 | ||
214 | set start_args $cont_args | |
215 | set cont_args [get_args] | |
216 | ||
a25fbfec | 217 | set num_other_threads 0 |
18ecae38 | 218 | for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { |
0312286c DJ |
219 | if {[lindex $start_args $i] == [lindex $cont_args $i]} { |
220 | if {$i == $curthread} { | |
221 | fail "current thread stepped (didn't run)" | |
0312286c DJ |
222 | } |
223 | } else { | |
224 | if {$i == $curthread} { | |
225 | if {[lindex $start_args $i] == [expr [lindex $cont_args $i] - 10]} { | |
226 | pass "current thread stepped" | |
227 | } else { | |
228 | fail "current thread stepped (wrong amount)" | |
229 | } | |
230 | } else { | |
a25fbfec | 231 | set num_other_threads [expr $num_other_threads + 1] |
0312286c DJ |
232 | } |
233 | } | |
234 | } | |
a25fbfec | 235 | if {$num_other_threads > 0} { |
18ecae38 | 236 | pass "other threads ran - unlocked" |
a25fbfec | 237 | } else { |
18ecae38 | 238 | fail "other threads ran - unlocked" |
a25fbfec | 239 | } |
0312286c DJ |
240 | |
241 | # Test continue with scheduler locking | |
242 | gdb_test "set scheduler-locking on" "" | |
243 | ||
244 | my_continue "with lock" | |
245 | ||
246 | # Make sure we're still in the same thread. | |
247 | set newthread [get_current_thread "find current thread (3)"] | |
248 | if {$curthread == $newthread} { | |
249 | pass "continue with lock does not change thread" | |
250 | } else { | |
251 | fail "continue with lock does not change thread (switched to thread $newthread)" | |
252 | } | |
253 | ||
254 | set start_args $cont_args | |
255 | set cont_args [get_args] | |
256 | ||
18ecae38 DJ |
257 | set num_other_threads 0 |
258 | for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { | |
0312286c DJ |
259 | if {[lindex $start_args $i] == [lindex $cont_args $i]} { |
260 | if {$i == $curthread} { | |
261 | fail "current thread ran (didn't run)" | |
0312286c DJ |
262 | } |
263 | } else { | |
264 | if {$i == $curthread} { | |
265 | pass "current thread ran" | |
266 | } else { | |
18ecae38 | 267 | incr num_other_threads |
0312286c DJ |
268 | } |
269 | } | |
270 | } | |
18ecae38 DJ |
271 | if {$num_other_threads > 0} { |
272 | fail "other threads didn't run - locked" | |
273 | } else { | |
274 | pass "other threads didn't run - locked" | |
275 | } | |
0312286c DJ |
276 | |
277 | # Test stepping with scheduler locking | |
278 | step_ten_loops "locked" | |
279 | ||
280 | # Make sure we're still in the same thread. | |
281 | set newthread [get_current_thread "find current thread (2)"] | |
282 | if {$curthread == $newthread} { | |
283 | pass "step with lock does not change thread" | |
284 | } else { | |
285 | fail "step with lock does not change thread (switched to thread $newthread)" | |
286 | } | |
287 | ||
288 | set start_args $cont_args | |
289 | set cont_args [get_args] | |
290 | ||
18ecae38 DJ |
291 | set num_other_threads 0 |
292 | for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} { | |
0312286c DJ |
293 | if {[lindex $start_args $i] == [lindex $cont_args $i]} { |
294 | if {$i == $curthread} { | |
295 | fail "current thread stepped locked (didn't run)" | |
0312286c DJ |
296 | } |
297 | } else { | |
298 | if {$i == $curthread} { | |
299 | if {[lindex $start_args $i] == [expr [lindex $cont_args $i] - 10]} { | |
300 | pass "current thread stepped locked" | |
301 | } else { | |
302 | fail "current thread stepped locked (wrong amount)" | |
303 | } | |
304 | } else { | |
18ecae38 | 305 | incr num_other_threads |
0312286c DJ |
306 | } |
307 | } | |
308 | } | |
18ecae38 DJ |
309 | if {$num_other_threads > 0} { |
310 | fail "other threads didn't run - step locked" | |
311 | } else { | |
312 | pass "other threads didn't run - step locked" | |
313 | } | |
0312286c DJ |
314 | |
315 | return 0 |