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