#!/usr/bin/sh
###############################################################################
# @File         pvrhwperf
# @Title        HWPerf tool
# @Description  Script to execute the capture of HWPerf events at runtime from
#               the GPU.
#@Copyright     Copyright (c) Imagination Technologies Ltd. All Rights Reserved
#@License       Strictly Confidential.
###############################################################################

OS="LINUX"
TMP_ROOT="/tmp"
TXT_READER=more
CAT_LOG=no
RETAIN_TL_HEADERS=no

DEVICE="all"
DEVICES=0
MIN_DEVICE_ID=0
MAX_DEVICE_ID=15

HWPERF_FW_FILTER=""
HWPERF_HOST_FILTER=""
HWPERF_CLIENT_APIS="EGL OpenCL OpenGL OpenGLES Services Vulkan"
for API in ${HWPERF_CLIENT_APIS}; do
  eval "HWPERF_CLIENT_FILTER_$API=\"\""
done

HWPERF_RESET_STREAMS="false"

if [ x"$PVRHWPERF_TMP" != x ]; then
  if [ -d "$PVRHWPERF_TMP" ]; then
    TMP_ROOT="$PVRHWPERF_TMP"
  fi
fi

if [ -x "/system/bin/logcat" ]; then
  OS="ANDROID"
  BIN_DIR=/system/vendor/bin
  TMP_ROOT="/data/local/tmp"
  TXT_READER=cat
fi

if [ x"$OS" = xANDROID ]; then
  USERID=$USER_ID
else
  USERID=`id -u`
fi

TLD_RET=
EXEC_LINE=""
H2J_NAME="hwperfbin2jsont"
JSM_NAME="hwperfjsonmerge.py"

if [ x"$OS" = xLINUX ]; then
    PYTHON_BIN="`which \"python\"`"
fi

# FUNCTIONS FOR SAVING STATE OF FILTER FILES
preserve_state() {
  PVR_DBG_LEVEL_OLD="$PVRDebugLevel"

  for ID in $DEVICES; do
    eval "_FW_FILTER_FILE=\$HWPERF_FW_FILTER_FILE_$ID"
    if [ x"$HWPERF_FW_FILTER" != x ] && [ -f $_FW_FILTER_FILE ]; then
      eval "HWPERF_FW_FILTER_${ID}_OLD=\"\$(cat $_FW_FILTER_FILE)\""
    fi

    eval "_HOST_FILTER_FILE=\$HWPERF_HOST_FILTER_FILE_$ID"
    if [ x"$HWPERF_HOST_FILTER" != x ] && [ -f $_HOST_FILTER_FILE ]; then
      eval "HWPERF_HOST_FILTER_${ID}_OLD=\"\$(cat $_HOST_FILTER_FILE)\""
    fi
  done

  for API in ${HWPERF_CLIENT_APIS}; do
    eval "_CLIENT_FILTER=\$HWPERF_CLIENT_FILTER_$API"
    eval "_CLIENT_FILTER_FILE=\$HWPERF_CLIENT_FILTER_FILE_$API"
    if [ x"$_CLIENT_FILTER" != x ] && [ -f $_CLIENT_FILTER_FILE ]; then
      eval "HWPERF_CLIENT_FILTER_${API}_OLD=\$(cat \$_CLIENT_FILTER_FILE)"
    fi
  done
}

# FUNCTIONS FOR SAVING AND RESTORING STATE IF USING THE PVRDEBUG TOOL
preserve_state_tool() {
  PVR_DBG_LEVEL_OLD="$PVRDebugLevel"
  for ID in $DEVICES; do
    eval "_FW_FILTER_FILE=\$HWPERF_FW_FILTER_FILE_$ID"
    eval "HWPERF_FW_FILTER_${ID}_OLD=\"\$(pvrdebug -device $ID -nobanner -di $_FW_FILTER_FILE | grep -G 0x0*)\""
    eval "_HOST_FILTER_FILE=\$HWPERF_HOST_FILTER_FILE_$ID"
    eval "HWPERF_HOST_FILTER_${ID}_OLD=\"\$(pvrdebug -device $ID -nobanner -di $_HOST_FILTER_FILE | grep -G 0x0*)\""
  done
  _CLIENT_FILTER_FILE=$HWPERF_CLIENT_FILTER_FILE
  HWOERF_FILTER_CLIENT_OLD="$(pvrdebug -nobanner -di $_CLIENT_FILTER_FILE | grep -G 0x0*)"
}

# FUNCTIONS FOR REWRITING THE PREVIOUS STATE OF FILTER FILES
restore_state() {
  export PVRDebugLevel=$PVR_DBG_LEVEL_OLD

  for ID in $DEVICES; do
    eval "_FW_FILTER=\$HWPERF_FW_FILTER_${ID}_OLD"
    eval "_FW_FILTER_FILE=\$HWPERF_FW_FILTER_FILE_${ID}"
    if [ x"$_FW_FILTER" != x ]; then
      echo $_FW_FILTER > $_FW_FILTER_FILE
    fi

    eval "_HOST_FILTER=\$HWPERF_HOST_FILTER_${ID}_OLD"
    eval "_HOST_FILTER_FILE=\$HWPERF_HOST_FILTER_FILE_${ID}"

    if [ x"$_HOST_FILTER" != x ]; then
      echo $_HOST_FILTER > $_HOST_FILTER_FILE
    fi
  done

  for API in ${HWPERF_CLIENT_APIS}; do
    eval "_CLIENT_FILTER=\$HWPERF_CLIENT_FILTER_${API}_OLD"
    eval "_CLIENT_FILTER_FILE=\$HWPERF_CLIENT_FILTER_FILE_$API"
    if [ x"$_CLIENT_FILTER" != x ] && [ -f $_CLIENT_FILTER_FILE ]; then
      echo $_CLIENT_FILTER > $_CLIENT_FILTER_FILE
    fi
  done
}

# FUNCTIONS FOR REWRITING THE PREVIOUS STATE OF FILTER FILES IF USING THE PVRDEBUG TOOL
restore_state_tool() {
  export PVRDebugLevel=$PVR_DBG_LEVEL_OLD

  if [ $MODE=="fw" ]; then
    for ID in $DEVICES; do
      eval "_FW_FILTER=\$HWPERF_FW_FILTER_${ID}_OLD"
      eval "_FW_FILTER_FILE=\$HWPERF_FW_FILTER_FILE_${ID}"
      if [ x"$_FW_FILTER" != x ]; then
        pvrdebug -device $ID -diset $_FW_FILTER_FILE $_FW_FILTER
      fi
      done
  fi

  if [ $MODE=="host" ]; then
    for ID in $DEVICES; do
      eval "_HOST_FILTER=\$HWPERF_HOST_FILTER_${ID}_OLD"
      eval "_HOST_FILTER_FILE=\$HWPERF_HOST_FILTER_FILE_${ID}"
      if [ x"$_HOST_FILTER" != x ]; then
        pvrdebug -device $ID -diset $_HOST_FILTER_FILE $_HOST_FILTER
      fi
    done
  fi

  _CLIENT_FILTER=$HWPERF_CLIENT_FILTER_OLD
  _CLIENT_FILTER_FILE=$HWPERF_CLIENT_FILTER_FILE
  if [ x"$_CLIENT_FILTER" != x ]; then
    pvrdebug -diset $_CLIENT_FILTER_FILE $_CLIENT_FILTER
  fi
}

OUT1_JSON_FILE_PREFIX="hwperf_fw_"
OUT2_JSON_FILE_PREFIX="hwperf_host_"
OUT_JSON_MERGE_FILE_PREFIX="hwperf_merge_"
# PARAMETERS PARSING
args="$@ dummy"
next=
skip_next="true"
for argument in $args
do
  curr=$next
  next=$argument

   if [ "$manual_termination" = "true" ]; then
    continue
  fi

  if [ "$skip_next" = "true" ]; then
    skip_next="false"
    continue
  fi

  if [ "$auto_test" = "true" ]; then
    if [ x"$OS" = xLINUX ]; then
      AUTO_TEST_COMMAND="$AUTO_TEST_COMMAND $curr"
      continue
    else
      echo "Automatic HWPerf testing is not supported on this OS."
      auto_test="false"
      manual_termination="true"
      continue
    fi
  fi

  case "$curr" in
    -device)
         DEVICE=$next
         skip_next="true"
        ;;
    -t)  EXEC_LINE=$H2J_NAME
         OUT1_JSON_FILE_TMP=$OUT1_JSON_FILE_PREFIX"*.json"
         OUT1_JSON_FILE="./"
         OUT2_JSON_FILE_TMP=$OUT2_JSON_FILE_PREFIX"*.json"
         OUT2_JSON_FILE="./"
         OUT3_JSON_FILE_TMP="hwperf_client_*.json"
         OUT3_JSON_DIR="./"
        ;;
    -rt) EXEC_LINE="$H2J_NAME $ -raw"
         OUT1_JSON_FILE_TMP=$OUT1_JSON_FILE_PREFIX"*.raw.json"
         OUT1_JSON_FILE="./"
         OUT2_JSON_FILE_TMP=$OUT2_JSON_FILE_PREFIX"*.raw.json"
         OUT2_JSON_FILE="./"
         OUT3_JSON_FILE_TMP="hwperf_client_*.raw.json"
         OUT3_JSON_DIR="./"
        ;;
    -m) OUT_JSON_MERGE_FILE_TMP=$OUT_JSON_MERGE_FILE_PREFIX"*.json"
        OUT_JSON_MERGE_FILE="./"
        ;;
    -c)  CAT_LOG=yes ;;
    -h)  echo "+-----------------------------------------------------------------------------+"
         echo "| pvrhwperf : run pvrtld (Transport Layer Daemon) for gathering HWPerf data"
         echo "|"
         echo "|             The HWPerf output data (firmware, host and client) is generated"
         echo "|             per-device and is segregated accordingly in files named:"
         echo "|             * hwperf_fw_<DeviceID>.[bin/json]"
         echo "|             * hwperf_host_<DeviceID>.[bin/json]"
         echo "|             * hwperf_client_<DeviceID>_<PID>.[bin/json]"
         echo "|             where <DeviceID> is unique identifier for a GPU device."
         echo "+-----------------------------------------------------------------------------+"
         echo "| Usage:"
         echo "|     -device ID : Device ID (0-15 or \"all\") for which data will be captured"
         echo "|                  (default \"all\"). If not specified or \"all\", data from all"
         echo "|                  devices will be captured."
         echo "|     -t  : Call hwperfbin2jsont (if present), to process the generated"
         echo "|           *.bin output files, after pvrtld end."
         echo "|     -rt : Call hwperfbin2jsont, adding the -raw parameter, to process the"
         echo "|           generated *.bin output files, after pvrtld end."
         if [ x"$PYTHON_BIN" != x ]; then
            echo "|     -m  : Call hwperfjsonmerge.py (if present), to merge generated *.json"
            echo "|           files (python interpreter required)."
         fi
         echo "|     -c  : Prints the log files to the std output just after pvrtld execution."
         echo "|     -h  : Print this message."
         echo "|     -fw 0xFILTER              : Specify a 64-bit hexadecimal filter value for FW events"
         echo "|                                 (original value is restored afterwards)."
         echo "|     -host 0xFILTER            : Specify a 32-bit hexadecimal filter value for Server host"
         echo "|                                 events (original value is restored afterwards)."
         for API in ${HWPERF_CLIENT_APIS}; do
           # sed 's/.*/\L&/''
           printf "|     -client-%-8s 0xFILTER : Specify a 32-bit hexadecimal filter value for Client host\n" $API
           printf "|                                 ${API} events (original value is restored afterwards).\n"
         done
         echo "|     -- TEST                   : Specify a test to run automatically with the hwperf capture."
         echo "|     -r                        : Reset streams before capturing data."
         echo "|     -tlbin                    : In addition to regular data also retain packet headers"
         echo "|                                 in the binary file (generates *.tlbin files)."
         echo "+-----------------------------------------------------------------------------+"
         exit 0
        ;;
    -fw)
         HWPERF_FW_FILTER=$next
         MODE="fw"
         skip_next="true"
        ;;
    -host)
         HWPERF_HOST_FILTER=$next
         MODE="host"
         skip_next="true"
        ;;
    -client-EGL)
         HWPERF_CLIENT_FILTER_EGL=$next
         MODE="client"
         skip_next="true"
        ;;
    -client-OpenCL)
         HWPERF_CLIENT_FILTER_OpenCL=$next
         MODE="client"
         skip_next="true"
        ;;
    -client-OpenGL)
         HWPERF_CLIENT_FILTER_OpenGL=$next
         MODE="client"
         skip_next="true"
        ;;
    -client-OpenGLES)
         HWPERF_CLIENT_FILTER_OpenGLES=$next
         MODE="client"
         skip_next="true"
        ;;
    -client-Services)
         HWPERF_CLIENT_FILTER_Services=$next
         MODE="client"
         skip_next="true"
        ;;
    -client-Vulkan)
         HWPERF_CLIENT_FILTER_Vulkan=$next
         MODE="client"
         skip_next="true"
        ;;
    --)
         auto_test="true"
        ;;
    -r) HWPERF_RESET_STREAMS="true"
        ;;
    -tlbin) RETAIN_TL_HEADERS=yes
        ;;
    *)  echo "[Error] Argument '$curr' not recognized."
        echo "        Run '$0 -h' for more information."; exit 1 ;;
  esac
done


# ENVIRONMENT CHECK
if [ x"$OS" = xANDROID ]; then
  TLD_BIN="$BIN_DIR/pvrtld"
  H2J_BIN="$BIN_DIR/$H2J_NAME"
else
  TLD_BIN="`which \"pvrtld\"`"
  H2J_BIN="`which \"$H2J_NAME\"`"
  JSM_BIN="`which \"$JSM_NAME\"`"
fi

if [ x"$DEVICE" != xall ]; then
  if ! [ $DEVICE -ge $MIN_DEVICE_ID ] 2>/dev/null; then
    echo "[Error] invalid device id"
    exit 1
  fi
  if ! [ $DEVICE -le $MAX_DEVICE_ID ] 2>/dev/null; then
    echo "[Error] invalid device id"
    exit 1
  fi
  if [ ${DEVICE} -lt 10 ]; then
    DEVICE="0"${DEVICE}
  fi
fi

if [ ! -f "$TLD_BIN" ]; then
  echo "[Error] pvrtld not found"
  exit 1
fi

if [ x"$EXEC_LINE" != x ]; then
  if [ ! -f "$H2J_BIN" ]; then
    echo "[Error] hwperfbin2jsont not found"
    exit 1
  fi
fi

# ENVIRONMENT VARIABLES
WORK_DIR="$TMP_ROOT/hwperf/`date +%s`"
OUT1_JSON_FILE_TMP="$WORK_DIR/$OUT1_JSON_FILE_TMP"
OUT2_JSON_FILE_TMP="$WORK_DIR/$OUT2_JSON_FILE_TMP"
if [ -n "$OUT3_JSON_FILE_TMP" ]; then
  OUT3_JSON_FILE_TMP="$WORK_DIR/$OUT3_JSON_FILE_TMP"
fi
OUT_JSON_MERGE_FILE_TMP="$WORK_DIR/$OUT_JSON_MERGE_FILE_TMP"
CFG_FILE=$WORK_DIR/"tld.conf"
TLD_LOG_FILE=$WORK_DIR/"tld.log"
HWP_LOG_FILE=$WORK_DIR/"hwp.log"
OUT1_FILE_TMP=$WORK_DIR/"hwperf_fw_*.*bin"
OUT2_FILE_TMP=$WORK_DIR/"hwperf_host_*.*bin"
OUT3_FILE_TMP=$WORK_DIR/"hwperf_client_*.*bin"
OUT1_FILE="./"
OUT2_FILE="./"
OUT3_DIR="./"

if [ ! -d "$WORK_DIR" ]; then
  mkdir -p ${WORK_DIR}
fi

STDOUT_FILE_TMP="$WORK_DIR/hwperf_stdout.txt"
touch $STDOUT_FILE_TMP

# determine if any of the Client filters is enabled
HWPERF_CLIENT_FILTER_ENABLED="false"
for API in ${HWPERF_CLIENT_APIS}; do
  eval "_CLIENT_FILTER=\$HWPERF_CLIENT_FILTER_$API"
  if [ x"$_CLIENT_FILTER" != x ]; then
    HWPERF_CLIENT_FILTER_ENABLED="true"
    break
  fi
done

# check if any filter is enabled first so that we can terminate before any
# filter is set
if [ x"$HWPERF_FW_FILTER" != x ] || \
   [ x"$HWPERF_HOST_FILTER" != x ] || \
   [ "$HWPERF_CLIENT_FILTER_ENABLED" = "true" ]; then
  if [ x"$OS" = xANDROID ]; then
    USERID=$USER_ID
  else
    USERID=`id -u`
  fi

  # check if user is the root user
  if [ -d "/sys/kernel/debug/pvr" ]; then
    METHOD="file"
    DEBUG_DIR="/sys/kernel/debug/pvr"
  # check if user has a proc directory
  elif [ -d "/proc/pvr" ]; then
    METHOD="file"
    DEBUG_DIR="/proc/pvr"
  # check if user has the pvrdebug tool
  elif [ -f "/usr/local/bin/pvrdebug" ]; then
    METHOD="tool"
    DEBUG_DIR="/pvr"
  else
    echo "Error: No valid debug path"
    exit 1
  fi
fi

if [ x"$DEVICE" = xall ]; then
  MAX_DEVICE_ID=$(pvrdebug -devlist | grep -c "\-device")
  MAX_DEVICE_ID=$(expr ${MAX_DEVICE_ID} - 1)
  DEVICES=$(seq -w $MIN_DEVICE_ID $MAX_DEVICE_ID)
  # Make sure we have 0-prefixed device values if we have less than 10 devices
  if [ $MAX_DEVICE_ID -lt 10 ]; then
    DEVICE2=
    for d in ${DEVICES}
    do
      if [ -n "${DEVICE2}" ]; then
        DEVICE2="${DEVICE2} 0$d"
      else
        DEVICE2="0"$d
      fi
    done
    DEVICES=${DEVICE2}
  fi
else
  DEVICES=$DEVICE
  if [ ${DEVICE} -lt 10 ]; then
    DEVICES="0"${DEVICE}
  fi
fi

# needs to be executed before "preserve_state"
for ID in $DEVICES; do
  eval "HWPERF_FW_FILTER_FILE_$ID=\"$DEBUG_DIR/gpu$ID/apphint/HWPerfFWFilter\""
  eval "HWPERF_HOST_FILTER_FILE_$ID=\"$DEBUG_DIR/gpu$ID/apphint/HWPerfHostFilter\""
done
for API in $HWPERF_CLIENT_APIS; do
  eval "HWPERF_CLIENT_FILTER_FILE_$API=\"$DEBUG_DIR/apphint/HWPerfClientFilter_$API\""
done
# choosing how to preserve state
if [ x"$METHOD" = "xtool" ]; then
  preserve_state_tool
else
  preserve_state
fi

export PVRDebugLevel=0x00
# error handling block - restores the state of filter files if any errors occur.
for ID in $DEVICES; do
  eval "_FW_FILTER_FILE=\$HWPERF_FW_FILTER_FILE_$ID"
  eval "_HOST_FILTER_FILE=\$HWPERF_HOST_FILTER_FILE_$ID"

  if [ x"$HWPERF_FW_FILTER" != x ] || [ x"$HWPERF_HOST_FILTER" != x ]; then
    if [ x"$HWPERF_FW_FILTER" != x ]; then

      # using pvrdebug to set the firmware filter
      if [ x"$METHOD" = "xtool" ]; then
        pvrdebug -device $ID -hwp_fw $HWPERF_FW_FILTER
      else
        echo $HWPERF_FW_FILTER 2>/dev/null > $_FW_FILTER_FILE 2>/dev/null
      fi

      if [ $? != 0 ] && [ x"$DEVICE" != xall ]; then
        echo "[Error] Failed to set HW performance filter"
        echo "        Check if the parameters passed to the script are valid"
        if [ x"$METHOD" = "xtool" ]; then
          restore_state_tool
        else
          restore_state
        fi
      fi
    fi

    if [ x"$HWPERF_HOST_FILTER" != x ]; then

      # using pvrdebug to set the host filter
      if [ x"$METHOD" = "xtool" ]; then
        pvrdebug -device $ID -hwp_host $HWPERF_HOST_FILTER
      else
        echo $HWPERF_HOST_FILTER 2>/dev/null > $_HOST_FILTER_FILE 2>/dev/null
      fi

      if [ $? != 0 ] && [ x"$DEVICE" != xall ]; then
        echo "[Error] Failed to set host events filter"
        echo "        Check if the parameters passed to the script are valid"
        if [ x"$METHOD" = "xtool" ]; then
          restore_state_tool
        else
          restore_state
        fi
        exit 1
      fi
    fi
  fi
done

for API in $HWPERF_CLIENT_APIS; do
  eval "_CLIENT_FILTER=\$HWPERF_CLIENT_FILTER_$API"
  eval "_CLIENT_FILTER_FILE=\$HWPERF_CLIENT_FILTER_FILE_$API"

  if [ x"$_CLIENT_FILTER" != x ]; then
    if [ x"$METHOD" = "xtool" ]; then
      # unsupported
      restore_state_tool
      exit 1
    else
      echo $_CLIENT_FILTER 2>/dev/null > $_CLIENT_FILTER_FILE 2>/dev/null
    fi

    if [ $? != 0 ]; then
      echo "[Error] Failed to set $API client events filter"
      echo "        Check if the parameters passed to the script are valid"
      if [ x"$METHOD" = "xtool" ]; then
        restore_state_tool
      else
        restore_state
      fi
      exit 1
    fi
  fi
done

# ENVIRONMENT SETUP
# - Create working directory
mkdir -p $WORK_DIR

# - Create configuration file
echo "[pvrtld]
output_folder_name=$WORK_DIR
output_file_save_previous=yes" > $CFG_FILE

if [ "$RETAIN_TL_HEADERS" = "yes" ]; then
echo "omit_header=no" >> $CFG_FILE
else
echo "omit_header=yes" >> $CFG_FILE
fi

echo "
[tlctrl]
enabled=yes
wait_for_stream=yes
ctrl_stream=yes

[hwperf_fw_]
enabled=yes
discover=yes
wait_for_stream=yes
server_block_nodata=no" >> $CFG_FILE

# - Add the post processing command if the tool exists
if [ x"$H2J_BIN" != x ] && [ x"$EXEC_LINE" != x ]; then
echo "exec=\"$EXEC_LINE\"" >> $CFG_FILE
fi

if [ "$HWPERF_RESET_STREAMS" = "true" ]; then
echo "reset_on_open=\"yes\"" >> $CFG_FILE
fi

if [ x"$DEVICE" != xall ]; then
echo "device=$DEVICE" >> $CFG_FILE
fi

echo "
[hwperf_host_]
enabled=yes
discover=yes
wait_for_stream=yes" >> $CFG_FILE

# - Add the post processing command if the tool exists
if [ x"$H2J_BIN" != x ] && [ x"$EXEC_LINE" != x ]; then
echo "exec=\"$EXEC_LINE\"" >> $CFG_FILE
fi

if [ "$HWPERF_RESET_STREAMS" = "true" ]; then
echo "reset_on_open=\"yes\"" >> $CFG_FILE
fi

if [ x"$DEVICE" != xall ]; then
echo "device=$DEVICE" >> $CFG_FILE
fi

echo "
[hwperf_client_]
enabled=yes
discover=yes" >> $CFG_FILE

# - Add the post processing command if the tool exists
if [ x"$H2J_BIN" != x ] && [ x"$EXEC_LINE" != x ]; then
echo "exec=\"$EXEC_LINE\"" >> $CFG_FILE
fi

if [ "$HWPERF_RESET_STREAMS" = "true" ]; then
echo "reset_on_open=\"yes\"" >> $CFG_FILE
fi

if [ x"$DEVICE" != xall ]; then
echo "device=$DEVICE" >> $CFG_FILE
fi

# EXECUTION

if [ "$auto_test" = "true" ]; then
  echo "+-----------------------------------------------------------------------------+"
  echo "| Starting capture of HWPerf data... with the test: $AUTO_TEST_COMMAND"
  echo "+-----------------------------------------------------------------------------+"
else
  echo "+-----------------------------------------------------------------------------+"
  echo "| Starting capture of HWPerf data..."
  echo "+-----------------------------------------------------------------------------+"
fi
echo "| Using these temporary files:"
echo "| - TLDaemon configuration file:     $CFG_FILE"
echo "| - TLDaemon log file:               $TLD_LOG_FILE"
echo "| - HWPerf binary file(s):           $OUT1_FILE_TMP"
echo "| - HWPerfHost binary file(s):       $OUT2_FILE_TMP"
echo "| - HWPerfClient binary file(s):     $OUT3_FILE_TMP"
echo "| - STDOUT file(s):                  $STDOUT_FILE_TMP"
if [ x"$H2J_BIN" = x ] || [ x"$EXEC_LINE" = x ]; then
  echo "| - No JSON output selected"
else
  echo "| - HWPerf raw json file(s):         $OUT1_JSON_FILE_TMP"
  echo "| - HWPerfHost raw json file(s):     $OUT2_JSON_FILE_TMP"
  echo "| - HWPerfClient raw json file:      $OUT3_JSON_FILE_TMP"
  if [ x"$JSM_BIN" != x ] && [ x"$PYTHON_BIN" != x ] && [ x"$OUT_JSON_MERGE_FILE" != x ]; then
    echo "| - HWPerf merged json file(s):      $OUT_JSON_MERGE_FILE_TMP"
  fi
  echo "| - JSON conversion log file:        $TLD_LOG_FILE"
fi
echo "+-----------------------------------------------------------------------------+"


if [ "$auto_test" = "true" ]; then

  PIPE=/tmp/srv-input$$

  mkfifo "$PIPE"
  cat > $PIPE &

  more $PIPE

  # if auto test is true, TLD will run in the background
  cat $PIPE | $TLD_BIN -f=$CFG_FILE -q -s 2> $TLD_LOG_FILE &

  if [ -n $(pgrep pvrtld) ]; then # Check to see if pvrtld is running

    sleep 5
    eval $AUTO_TEST_COMMAND

    if [ $? -eq 0 ]; then # Check if passed test completed
      TLD_RET=$? # TLD can quit
      echo "Test completed."
      echo "x" > $PIPE # Pipe 'x' to quit hwperf
    else
      TLD_RET=$? # TLD quits with error code.
      echo "Test not completed."
      echo "x" > $PIPE # Pipe 'x' to quit hwperf
    fi
  else
      echo "TLD is not running\n"
  fi

  rm -f ${PIPE}

  $AUTO_TEST_COMMAND > $STDOUT_FILE_TMP 2>&1

else # No automatic test, so manual termination is used
  $TLD_BIN -f=$CFG_FILE -q -s 2> $TLD_LOG_FILE
  TLD_RET=$?
fi

# LAST MESSAGES
if [ "$TLD_RET" -ne "0" ]; then
  echo "+-----------------------------------------------------------------------------+"
  echo "| Capture process exited with error code $TLD_RET"
else
  out1filecnt=$(ls $OUT1_FILE_TMP 2>>$HWP_LOG_FILE | wc -l 2>>$HWP_LOG_FILE)
  out2filecnt=$(ls $OUT2_FILE_TMP 2>>$HWP_LOG_FILE | wc -l 2>>$HWP_LOG_FILE)
  out3filecnt=$(ls $OUT3_FILE_TMP 2>>$HWP_LOG_FILE | wc -l 2>>$HWP_LOG_FILE)
  if [ $out1filecnt -ne 0 ] || [ $out2filecnt -ne 0 ] || [ $out3filecnt -ne 0 ]; then
    if [ x"$OUT1_JSON_FILE" != x ]; then
      out1jsonlist=$(ls $OUT1_JSON_FILE_TMP 2>>$HWP_LOG_FILE)
      out1jsonfilecnt=$(ls $OUT1_JSON_FILE_TMP 2>>$HWP_LOG_FILE | wc -l 2>>$HWP_LOG_FILE)
    fi
    if [ x"$OUT2_JSON_FILE" != x ]; then
      out2jsonfilecnt=$(ls $OUT2_JSON_FILE_TMP 2>>$HWP_LOG_FILE | wc -l 2>>$HWP_LOG_FILE)
    fi
    if [ x"$JSM_BIN" != x ] && [ x"$PYTHON_BIN" != x ] && [ x"$OUT_JSON_MERGE_FILE" != x ]; then
      echo "+-----------------------------------------------------------------------------+"
      echo "| Merging JSON files..."
      echo "+-----------------------------------------------------------------------------+"
      for i in $out1jsonlist; do
        DEVICE_ID_POSTFIX=$(echo $i | sed -n /.*$OUT1_JSON_FILE_PREFIX/s/.*$OUT1_JSON_FILE_PREFIX//p)
        $PYTHON_BIN $JSM_BIN -d $WORK_DIR -f $OUT1_JSON_FILE_PREFIX$DEVICE_ID_POSTFIX \
                                            -s $OUT2_JSON_FILE_PREFIX$DEVICE_ID_POSTFIX \
                                            -o $WORK_DIR/$OUT_JSON_MERGE_FILE_PREFIX$DEVICE_ID_POSTFIX
      done
    fi
    echo "+-----------------------------------------------------------------------------+"
    echo "| Data captured, files moved to CWD."
	if [ $out1filecnt -ne 0 ]; then
      mv $OUT1_FILE_TMP $OUT1_FILE
	fi
	if [ x"$OUT1_JSON_FILE" != x ] && [ $out1jsonfilecnt -ne 0 ]; then
      mv $OUT1_JSON_FILE_TMP $OUT1_JSON_FILE
    fi
    if [ $out2filecnt -ne 0 ]; then
      mv $OUT2_FILE_TMP $OUT2_FILE
    fi
    if [ x"$OUT2_JSON_FILE" != x ] && [ $out2jsonfilecnt -ne 0 ]; then
	  mv $OUT2_JSON_FILE_TMP $OUT2_JSON_FILE
    fi
    if [ x"$OUT_JSON_MERGE_FILE" != x ]; then
      if [ $(ls $OUT_JSON_MERGE_FILE_TMP | wc -l 2>>$HWP_LOG_FILE) -ne 0 ]; then
        mv $OUT_JSON_MERGE_FILE_TMP $OUT_JSON_MERGE_FILE
      fi
    fi
    if ls $OUT3_FILE_TMP >>$HWP_LOG_FILE 2>&1; then
      mv $OUT3_FILE_TMP $OUT3_DIR
      if [ -n "$OUT3_JSON_FILE_TMP" ] && ls $OUT3_JSON_FILE_TMP >>$HWP_LOG_FILE 2>&1; then
        mv $OUT3_JSON_FILE_TMP $OUT3_JSON_DIR
      fi
    fi
  else
    echo "+-----------------------------------------------------------------------------+"
    echo "| No data captured, binary files do not exist."
  fi
fi

# Give time for the Log file to be flushed to disk
sync
if [ "$CAT_LOG" = "yes" ]; then
  echo "+-----------------------------------------------------------------------------+"
  echo "| TLDaemon debug log file..."
  echo "| $TXT_READER $TLD_LOG_FILE"
  echo "+-----------------------------------------------------------------------------+"
  $TXT_READER $TLD_LOG_FILE
  echo "+-----------------------------------------------------------------------------+"
  echo "| pvrhwperf debug log file..."
  echo "| $TXT_READER $HWP_LOG_FILE"
  echo "+-----------------------------------------------------------------------------+"
  $TXT_READER $HWP_LOG_FILE
fi
echo "+-----------------------------------------------------------------------------+"

# previous filters are restored after the HWPerf data is captured
if [ x"$METHOD" = "xtool" ]; then
  restore_state_tool
else
  restore_state
fi
