#!/bin/sh
# DF-4064 phase 2: make fxp_stat_timer actually FIRE while the ifnet
# serializer is held by a *non-stopper* (tight `ifconfig fxp0` state dumps =
# netisr-held serializer sections), so fxp_tick parks in lwkt_serialize_enter;
# any subsequent up/down entry then wedges netisr in callout_stop ('costp')
# against the parked tick ('slize').  AB-BA.
LOG=/root/fxp_race2.log
CON=/dev/console
echo "=== fxp race2 start $(date) ===" > $CON
echo "=== fxp race2 start ===" > $LOG
# U: arms fxp_stat_timer (callout_reset at end of fxp_init), period > 1s
( while :; do ifconfig fxp0 up 2>/dev/null; sleep 1.3; done ) &
# D: stopper entries, period > 1s (phase drifts vs U)
( while :; do ifconfig fxp0 down 2>/dev/null; sleep 1.3; done ) &
# M: non-stopper serializer load (SIOCGIFMEDIA etc. via state dumps)
( while :; do ifconfig fxp0 >/dev/null 2>&1; done ) &
( while :; do ifconfig fxp0 >/dev/null 2>&1; done ) &
i=0
while [ $i -lt 420 ]; do
  sleep 1
  if ps -axao wchan 2>/dev/null | grep -q costp; then
    echo "=== WEDGE DETECTED t=${i}s (stopper in costp) ===" > $CON
    echo "=== WEDGE DETECTED t=${i}s ===" >> $LOG
    ps -axao pid,stat,wchan,comm > $CON 2>&1
    ps -axao pid,stat,wchan,comm >> $LOG 2>&1
    echo "=== END WEDGE SNAPSHOT ===" > $CON
    exit 0
  fi
  i=$((i+1))
  if [ $((i % 10)) -eq 0 ]; then echo "...t=${i}s" > $CON; fi
done
echo "=== NO WEDGE in 420s ===" > $CON
echo "=== NO WEDGE in 420s ===" >> $LOG
