# Copyright (C) 1996-2013 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 3 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, see <http://www.gnu.org/licenses/>.

# This file was written by Daniel Jacobowitz <drow@mvista.com>
# (parts based on pthreads.exp by Fred Fish (fnf@cygnus.com).
#
# This test covers the various forms of "set scheduler-locking".


standard_testfile

# The number of threads, including the main thread.
set NUM 2

if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != "" } {
    return -1
}

# Now we can proceed with the real testing.

proc get_args { } {
    global list_count
    global gdb_prompt
    global NUM

    set pattern "(\[0-9\]+)"
    for {set i 1} {[expr $i < $NUM]} {incr i} {
	append pattern ", (\[0-9\]+)"
    }

    gdb_test_multiple "print args" "listed args ($list_count)" {
	-re "\\\$\[0-9\]+ = {$pattern}.*$gdb_prompt $" {
	    set list_count [expr $list_count + 1]
	    pass "listed args ($list_count)"

	    set result ""
	    for {set i 1} {[expr $i <= $NUM]} {incr i} {
		lappend result $expect_out($i,string)
	    }
	    return $result
	}
    }
}

proc stop_process { description } {
  global gdb_prompt

  # For this to work we must be sure to consume the "Continuing."
  # message first, or GDB's signal handler may not be in place.
  after 1000 {send_gdb "\003"}
  gdb_expect {
    -re "Program received signal SIGINT.*$gdb_prompt $"
      {
	pass $description
      }
    timeout
      {
	fail "$description (timeout)"
      }
  }
}

proc get_current_thread { description } {
    global gdb_prompt

    gdb_test_multiple "bt" "$description" {
	-re "thread_function \\(arg=0x(\[0-9\])\\).*$gdb_prompt $" {
	    pass $description
	    return $expect_out(1,string)
	}
    }
    return ""
}

proc my_continue { msg } {
    gdb_test_multiple "continue" "continuing ($msg)" {
	-re "Continuing" {
	    pass "continue ($msg)"
	}
    }

    stop_process "stop all threads ($msg)"

    # Make sure we're in one of the non-main looping threads.
    gdb_breakpoint [concat [gdb_get_line_number "schedlock.exp: main loop"] " if arg != 0"]
    gdb_continue_to_breakpoint "return to loop ($msg)"
    delete_breakpoints
}

proc step_ten_loops { msg } {
    global gdb_prompt

    for {set i 0} {[expr $i < 10]} {set i [expr $i + 1]} {
	set other_step 0
	gdb_test_multiple "step" "step to increment ($msg $i)" {
	    -re ".*myp\\) \\+\\+;\[\r\n\]+$gdb_prompt $" {
		pass "step to increment ($msg $i)"
	    }
	    -re "$gdb_prompt $" {
		if {$other_step == 0} {
		    set other_step 1
		    send_gdb "step\n"
		    exp_continue
		} else {
		    fail "step to increment ($msg $i)"
		    # FIXME cascade?
		}
	    }
	}
    }
}

# Start with a fresh gdb.

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir

# We'll need this when we send_gdb a ^C to GDB.  Need to do it before we
# run the program and gdb starts saving and restoring tty states.
# On Ultrix, we don't need it and it is really slow (because shell_escape
# doesn't use vfork).
if ![istarget "*-*-ultrix*"] then {
    gdb_test "shell stty intr '^C'" ".*"
}

gdb_load ${binfile}

gdb_test_no_output "set print sevenbit-strings"
gdb_test_no_output "set width 0"

runto_main

# See if scheduler locking is available on this target.
global gdb_prompt
gdb_test_multiple "set scheduler-locking off" "scheduler locking set to none" {
    -re "Target .* cannot support this command" {
	unsupported "target does not support scheduler locking"
	return
    }
    -re "$gdb_prompt $" {
	pass "scheduler locking set to none"
    }
    timeout {
	unsupported "target does not support scheduler locking (timeout)"
	return
    }
}

gdb_breakpoint [gdb_get_line_number "schedlock.exp: last thread start"]
gdb_continue_to_breakpoint "all threads started"

global list_count
set list_count 0

set start_args [get_args]

# First make sure that all threads are alive.
my_continue "initial"

set cont_args [get_args]

set bad 0
for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} {
  if {[lindex $start_args $i] == [lindex $cont_args $i]} {
    incr bad
  }
}
if { $bad == 0 } {
  pass "all threads alive"
} else {
  fail "all threads alive ($bad/$NUM did not run)"
}

# We can't change threads, unfortunately, in current GDB.  Use
# whichever we stopped in.
set curthread [get_current_thread "find current thread (1)"]




# Test stepping without scheduler locking.
gdb_test_no_output "set scheduler-locking off"

step_ten_loops "unlocked"

# Make sure we're still in the same thread.
set newthread [get_current_thread "find current thread (2)"]
if {$curthread == $newthread} {
    pass "step without lock does not change thread"
} else {
    fail "step without lock does not change thread (switched to thread $newthread)"
}

set start_args $cont_args
set cont_args [get_args]

set num_other_threads 0
for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} {
  if {[lindex $start_args $i] == [lindex $cont_args $i]} {
    if {$i == $curthread} {
      fail "current thread stepped (didn't run)"
    }
  } else {
    if {$i == $curthread} {
	if {[lindex $start_args $i] == [expr [lindex $cont_args $i] - 10]} {
	    pass "current thread stepped"
	} else {
	    fail "current thread stepped (wrong amount)"
	}
    } else {
      set num_other_threads [expr $num_other_threads + 1]
    }
  }
}
if {$num_other_threads > 0} {
  pass "other threads ran - unlocked"
} else {
  fail "other threads ran - unlocked"
}

# Test continue with scheduler locking
gdb_test "set scheduler-locking on" ""

my_continue "with lock"

# Make sure we're still in the same thread.
set newthread [get_current_thread "find current thread (3)"]
if {$curthread == $newthread} {
    pass "continue with lock does not change thread"
} else {
    fail "continue with lock does not change thread (switched to thread $newthread)"
}

set start_args $cont_args
set cont_args [get_args]

set num_other_threads 0
for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} {
  if {[lindex $start_args $i] == [lindex $cont_args $i]} {
    if {$i == $curthread} {
      fail "current thread ran (didn't run)"
    }
  } else {
    if {$i == $curthread} {
      pass "current thread ran"
    } else {
      incr num_other_threads
    }
  }
}
if {$num_other_threads > 0} {
  fail "other threads didn't run - locked"
} else {
  pass "other threads didn't run - locked"
}

# Test stepping with scheduler locking
step_ten_loops "locked"

# Make sure we're still in the same thread.
set newthread [get_current_thread "find current thread (2)"]
if {$curthread == $newthread} {
    pass "step with lock does not change thread"
} else {
    fail "step with lock does not change thread (switched to thread $newthread)"
}

set start_args $cont_args
set cont_args [get_args]

set num_other_threads 0
for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} {
  if {[lindex $start_args $i] == [lindex $cont_args $i]} {
    if {$i == $curthread} {
      fail "current thread stepped locked (didn't run)"
    }
  } else {
    if {$i == $curthread} {
	if {[lindex $start_args $i] == [expr [lindex $cont_args $i] - 10]} {
	    pass "current thread stepped locked"
	} else {
	    fail "current thread stepped locked (wrong amount)"
	}
    } else {
      incr num_other_threads
    }
  }
}
if {$num_other_threads > 0} {
  fail "other threads didn't run - step locked"
} else {
  pass "other threads didn't run - step locked"
}

return 0
