source `dirname $0`/util.sh

# We want to test two things here:
# 1) Terminating rr when the next tracee event is a reschedule
# 2) Terminating rr when the syscallbuf contains events that need to be flushed
# To test both of these, we need to set the reschedule threshold high enough
# that our signal is delivered before the first reschedule after sending
# the SYNC_TOKEN. We also need to set the reschedule threshold low enough
# that a reschedule occurs before chew_cpu's spin() loop finishes. Currently
# that loop has 2^30 iterations, so 100M events per reschedule sounds good.
RECORD_ARGS="-c100000000"

EXE=chew_cpu$bitness
SYNC_TOKEN=spinning
WAIT_SECS=1

record $EXE &

echo "Waiting for token '$SYNC_TOKEN' from tracee ..."
until grep -q $SYNC_TOKEN record.out; do
        sleep 0
done

rrpid=$(parent_pid_of $(pidof $EXE-$nonce))

# It's possible for this signal to be acted on before chew_cpu actually
# reaches the spin() loop, e.g. with syscallbuf disabled it might be delivered
# before rr has finished handling the syscalls of atomic_puts. But scheduling
# variations should ensure that sometimes we reach spin() first.
echo "  done.  Delivering SIGTERM to $rrpid ..."
kill -TERM $rrpid

echo "  done."

# Wait for 'record' to actually terminate. Otherwise we might start
# replaying before the trace file has been completely written, and we might
# fail to see the tracee write EXIT-SUCCESS.
wait

if [[ "record.out" == $(grep -l "EXIT-SUCCESS" record.out) ]]; then
        failed "error during recording: tracer not interrupted in time."
fi

echo "Replaying ..."
replay
check ""
