# Modified by Linaro.
# Copyright (C) March 2023- Linaro Limited (or its affiliates). All rights reserved.
# 
# Modified by Arm.
# Copyright (C) 1995-2023 Arm Limited (or its affiliates). All rights reserved.
# 
# Copyright 2012 Free Software Foundation, Inc.
#
# Contributed by Intel Corp. <markus.t.metzger@intel.com>
#
# 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/>.
#
#
# Check that races are correctly reported and stored in the report history.
#
# The test has been constructed such that it produces a single read/write race
# on each test iteration.

load_lib pdbx.exp

set srcfile "race_glob_rw.c"

if { [prepare_for_testing history.exp "race_glob_rw.x" $srcfile [pdbx_cflags]] } {
	untested "compilation failed. requires icc 12.1 or later."
    return -1
}

if { [skip_python_tests] } { continue }

set ln_thread [gdb_get_line_number "bp.thread" $srcfile]
set ln_write  [gdb_get_line_number "bp.write"  $srcfile]
set ln_read   [gdb_get_line_number "bp.read"   $srcfile]

set loc_thread "$srcfile:$ln_thread"
set loc_write  "$srcfile:$ln_write"
set loc_read   "$srcfile:$ln_read"

set hex "0x\[0-9a-f\]+"

set expected "
 *\[0-9\]+: write shared, 4 bytes from .*$loc_write\r
 *\[0-9\]+: read shared, 4 bytes from .*$loc_read"
set expected_r "
 *\[0-9\]+: write $hex, 4 bytes from $hex\r
 *\[0-9\]+: read $hex, 4 bytes from $hex"

if ![runto_main] then { return -1 }

# The history is initially empty.
#
gdb_test_no_output "pdbx enable" "history, 1.1"
gdb_test "pdbx history" "0 races in 0 threads; 0 reads, 0 writes, 0 updates" "history, 1.2"
gdb_test_no_output "pdbx history list" "history, 1.3"

# Detect the first race.
#
gdb_test "continue" "data race detected\r$expected.*" "history, 2.1"
gdb_test "pdbx history" "1 races in 2 threads; 1 reads, 1 writes, 0 updates" "history, 2.2"
gdb_test "pdbx history list" " *0: shared - 2 threads, 1 reads, 1 writes, 0 updates" "history, 2.3"

# Detect the second race.
#
gdb_test "continue" "data race detected\r$expected.*" "history, 3.1"
gdb_test "pdbx history" "2 races in 2 threads; 2 reads, 2 writes, 0 updates" "history, 3.2"
gdb_test "pdbx history list" " *0: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *1: shared - 2 threads, 1 reads, 1 writes, 0 updates" "history, 3.3"


# Another three races.
#
gdb_test "continue" "data race detected\r$expected.*" "history, 4.1"
gdb_test "continue" "data race detected\r$expected.*" "history, 4.2"
gdb_test "continue" "data race detected\r$expected.*" "history, 4.3"
gdb_test "pdbx history" "5 races in 2 threads; 5 reads, 5 writes, 0 updates" "history, 4.4"
gdb_test "pdbx history list" " *0: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *1: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *2: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *3: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *4: shared - 2 threads, 1 reads, 1 writes, 0 updates" "history, 4.5"

# Show historic race reports.
#
gdb_test "pdbx history show" "$expected\r$expected\r$expected" "history, 5.1"
gdb_test "pdbx history show 0" "$expected" "history, 5.2"
gdb_test "pdbx history show /r 0" "$expected_r" "history, 5.3"
gdb_test "pdbx history show 1" "$expected" "history, 5.4"
gdb_test "pdbx history show 0-1" "$expected\r$expected" "history, 5.5"
gdb_test "pdbx history show /r 0-1" "$expected_r\r$expected_r" "history, 5.6"
gdb_test "pdbx history show 1-2" "$expected\r$expected" "history, 5.7"
gdb_test "pdbx history show 0-2" "$expected\r$expected\r$expected" "history, 5.8"
gdb_test "pdbx history show /r" "$expected_r\r$expected_r\r$expected_r" "history, 5.9"
gdb_test "pdbx history show /b 0" "ERROR: bad modifier: b\." "history, 5.10"
gdb_test "pdbx history show /rb 0" "ERROR: bad modifier: b\." "history, 5.11"
gdb_test "pdbx history show 5" "ERROR: no such element: 5\." "history, 5.12"
gdb_test "pdbx history show 1-5" "ERROR: no such element: 5\." "history, 5.13"
gdb_test "pdbx history show 2-1" "ERROR: bad range: 1 < 2\." "history, 5.14"

# Remove invalid elements. Shouldn't change the history.
#
gdb_test "pdbx history remove 5" "ERROR: no such element: 5\." "history, 6.1"
gdb_test "pdbx history remove 5-6" "ERROR: no such element: 5\." "history, 6.2"
gdb_test "pdbx history remove 2-1" "ERROR: bad range: 1 < 2\." "history, 6.3"
gdb_test "pdbx history" "5 races in 2 threads; 5 reads, 5 writes, 0 updates" "history, 6.4"
gdb_test "pdbx history list" " *0: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *1: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *2: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *3: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *4: shared - 2 threads, 1 reads, 1 writes, 0 updates" "history, 6.5"

# Remove a single race report from the middle.
#
gdb_test_no_output "pdbx history remove 1" "history, 7.1"
gdb_test "pdbx history" "4 races in 2 threads; 4 reads, 4 writes, 0 updates" "history, 7.2"
gdb_test "pdbx history list" " *0: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *1: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *2: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *3: shared - 2 threads, 1 reads, 1 writes, 0 updates" "history, 7.3"

# Remove a range of race reports.
#
gdb_test_no_output "pdbx history remove 0-1" "history, 8.1"
gdb_test "pdbx history" "2 races in 2 threads; 2 reads, 2 writes, 0 updates" "history, 8.2"
gdb_test "pdbx history list" " *0: shared - 2 threads, 1 reads, 1 writes, 0 updates\r
 *1: shared - 2 threads, 1 reads, 1 writes, 0 updates" "history, 8.3"

# Clear the report history.
#
gdb_test_no_output "pdbx history remove" "history, 9.1"
gdb_test "pdbx history" "0 races in 0 threads; 0 reads, 0 writes, 0 updates" "history, 9.2"
gdb_test_no_output "pdbx history list" "history, 9.3"
