diff --git a/runtime/experiments/bash_libraries/framework.sh b/runtime/experiments/bash_libraries/framework.sh index 946aeae..5ec283d 100644 --- a/runtime/experiments/bash_libraries/framework.sh +++ b/runtime/experiments/bash_libraries/framework.sh @@ -22,9 +22,10 @@ __framework_sh__usage() { echo "" echo "Options:" echo " -t,--target= Execute as client against remote URL" - echo " -s,--serve= Serve with scheduling policy, but do not run client" - echo " -d,--debug= Debug under GDB with scheduling policy, but do not run client" - echo " -p,--perf= Run under perf with scheduling policy. Run on baremetal Linux host!" + echo " -s,--serve Serve but do not run client" + echo " -d,--debug Debug under GDB but do not run client" + echo " -p,--perf Run under perf. Limited to running on a baremetal Linux host!" + echo " -h,--help Display usage information" } # Declares application level global state @@ -36,7 +37,6 @@ __framework_sh__initialize_globals() { # Globals used by parse_arguments declare -g __framework_sh__target="" - declare -g __framework_sh__policy="" declare -g __framework_sh__role="" # Configure environment variables @@ -45,7 +45,6 @@ __framework_sh__initialize_globals() { local -r binary_directory="$(cd "$__framework_sh__application_directory" && cd ../../bin && pwd)" export PATH=$binary_directory:$PATH export LD_LIBRARY_PATH=$binary_directory:$LD_LIBRARY_PATH - export SLEDGE_NWORKERS=5 } # Parses arguments from the user and sets associates global state @@ -62,49 +61,31 @@ __framework_sh__parse_arguments() { __framework_sh__target="${i#*=}" shift ;; - -s=* | --serve=*) + -s | --serve) if [[ "$__framework_sh__role" == "client" ]]; then echo "Cannot use -s,--serve with -t,--target" __framework_sh__usage return 1 fi __framework_sh__role=server - __framework_sh__policy="${i#*=}" - if [[ ! $__framework_sh__policy =~ ^(EDF|FIFO)$ ]]; then - echo "\"$__framework_sh__policy\" is not a valid policy. EDF or FIFO allowed" - __framework_sh__usage - return 1 - fi shift ;; - -d=* | --debug=*) + -d | --debug) if [[ "$__framework_sh__role" == "client" ]]; then echo "Cannot use -d,--debug with -t,--target" __framework_sh__usage return 1 fi __framework_sh__role=debug - __framework_sh__policy="${i#*=}" - if [[ ! $__framework_sh__policy =~ ^(EDF|FIFO)$ ]]; then - echo "\"$__framework_sh__policy\" is not a valid policy. EDF or FIFO allowed" - __framework_sh__usage - return 1 - fi shift ;; - -p=* | --perf=*) + -p | --perf) if [[ "$__framework_sh__role" == "perf" ]]; then echo "Cannot use -p,--perf with -t,--target" __framework_sh__usage return 1 fi __framework_sh__role=perf - __framework_sh__policy="${i#*=}" - if [[ ! $__framework_sh__policy =~ ^(EDF|FIFO)$ ]]; then - echo "\"$__framework_sh__policy\" is not a valid policy. EDF or FIFO allowed" - __framework_sh__usage - return 1 - fi shift ;; -h | --help) @@ -127,7 +108,6 @@ __framework_sh__parse_arguments() { # Set globals as read only declare -r __framework_sh__target - declare -r __framework_sh__policy declare -r __framework_sh__role } @@ -167,52 +147,44 @@ __framework_sh__log_environment() { echo "*************" } -# $1 - Scheduler Variant (EDF|FIFO) -# $2 - Results Directory -# $3 - How to run (foreground|background) -# $4 - JSON specification +# $1 - Results Directory +# $2 - How to run (foreground|background) +# $3 - JSON specification __framework_sh__start_runtime() { printf "Starting Runtime: " - if (($# != 4)); then + if (($# != 3)); then printf "[ERR]\n" panic "invalid number of arguments \"$1\"" return 1 - elif ! [[ $1 =~ ^(EDF|FIFO)$ ]]; then - printf "[ERR]\n" - panic "expected EDF or FIFO was \"$1\"" - return 1 - elif ! [[ -d "$2" ]]; then + elif ! [[ -d "$1" ]]; then printf "[ERR]\n" - panic "directory \"$2\" does not exist" + panic "directory \"$1\" does not exist" return 1 - elif ! [[ $3 =~ ^(foreground|background)$ ]]; then + elif ! [[ $2 =~ ^(foreground|background)$ ]]; then printf "[ERR]\n" - panic "expected foreground or background was \"$3\"" + panic "expected foreground or background was \"$2\"" return 1 - elif [[ ! -f "$4" || "$4" != *.json ]]; then + elif [[ ! -f "$3" || "$3" != *.json ]]; then printf "[ERR]\n" - panic "\"$4\" does not exist or is not a JSON" + panic "\"$3\" does not exist or is not a JSON" return 1 fi local -r scheduler="$1" - local -r results_directory="$2" - local -r how_to_run="$3" - local -r specification="$4" + local -r how_to_run="$2" + local -r specification="$3" local -r log_name=log.txt - local log="$results_directory/${log_name}" + local log="$RESULTS_DIRECTORY/${log_name}" __framework_sh__log_environment >> "$log" case "$how_to_run" in "background") - SLEDGE_SCHEDULER="$scheduler" \ - sledgert "$specification" >> "$log" 2>> "$log" & + sledgert "$specification" >> "$log" 2>> "$log" & ;; "foreground") - SLEDGE_SCHEDULER="$scheduler" \ - sledgert "$specification" + sledgert "$specification" ;; esac @@ -221,24 +193,21 @@ __framework_sh__start_runtime() { } __framework_sh__run_server() { - if (($# != 2)); then - panic "invalid number of arguments \"$1\"" - return 1 - elif ! [[ $1 =~ ^(EDF|FIFO)$ ]]; then - panic "expected EDF or FIFO was \"$1\"" + if (($# != 1)); then + printf "[ERR]\n" + panic "Invalid number of arguments. Saw $#. Expected 1." return 1 - elif ! [[ $2 =~ ^(foreground|background)$ ]]; then + elif ! [[ $1 =~ ^(foreground|background)$ ]]; then printf "[ERR]\n" panic "expected foreground or background was \"$3\"" return 1 fi - local -r scheduler="$1" - local -r how_to_run="$2" + local -r how_to_run="$1" - __framework_sh__start_runtime "$scheduler" "$RESULTS_DIRECTORY" "$how_to_run" "$__framework_sh__application_directory/spec.json" || { + __framework_sh__start_runtime "$RESULTS_DIRECTORY" "$how_to_run" "$__framework_sh__application_directory/spec.json" || { echo "__framework_sh__start_runtime RC: $?" - panic "Error calling __framework_sh__start_runtime $scheduler $RESULTS_DIRECTORY $how_to_run $__framework_sh__application_directory/spec.json" + panic "Error calling __framework_sh__start_runtime $RESULTS_DIRECTORY $how_to_run $__framework_sh__application_directory/spec.json" return 1 } @@ -246,13 +215,9 @@ __framework_sh__run_server() { } __framework_sh__run_perf() { - if (($# != 1)); then - printf "[ERR]\n" - panic "invalid number of arguments \"$1\"" - return 1 - elif ! [[ $1 =~ ^(EDF|FIFO)$ ]]; then + if (($# != 0)); then printf "[ERR]\n" - panic "expected EDF or FIFO was \"$1\"" + panic "Invalid number of arguments. Saw $#. Expected 0." return 1 fi @@ -261,30 +226,23 @@ __framework_sh__run_perf() { exit 1 fi - local -r scheduler="$1" - - SLEDGE_SCHEDULER="$scheduler" perf record -g -s sledgert "$__framework_sh__application_directory/spec.json" + perf record -g -s sledgert "$__framework_sh__application_directory/spec.json" } # Starts the Sledge Runtime under GDB __framework_sh__run_debug() { - # shellcheck disable=SC2155 - local project_directory=$(cd ../.. && pwd) - if (($# != 1)); then + if (($# != 0)); then printf "[ERR]\n" - panic "invalid number of arguments \"$1\"" - return 1 - elif ! [[ $1 =~ ^(EDF|FIFO)$ ]]; then - printf "[ERR]\n" - panic "expected EDF or FIFO was \"$1\"" + panic "Invalid number of arguments. Saw $#. Expected 0." return 1 fi - local -r scheduler="$1" + # shellcheck disable=SC2155 + local project_directory=$(cd ../.. && pwd) if [[ "$project_directory" != "/sledge/runtime" ]]; then printf "It appears that you are not running in the container. Substituting path to match host environment\n" - SLEDGE_SCHEDULER="$scheduler" gdb \ + gdb \ --eval-command="handle SIGUSR1 nostop" \ --eval-command="handle SIGPIPE nostop" \ --eval-command="set pagination off" \ @@ -292,7 +250,7 @@ __framework_sh__run_debug() { --eval-command="run $__framework_sh__application_directory/spec.json" \ sledgert else - SLEDGE_SCHEDULER="$scheduler" gdb \ + gdb \ --eval-command="handle SIGUSR1 nostop" \ --eval-command="handle SIGPIPE nostop" \ --eval-command="set pagination off" \ @@ -315,8 +273,10 @@ __framework_sh__run_both() { local -ar schedulers=(EDF FIFO) for scheduler in "${schedulers[@]}"; do printf "Running %s\n" "$scheduler" + export SLEDGE_SCHEDULER="$scheduler" + __framework_sh__create_and_export_results_directory "$scheduler" - __framework_sh__run_server "$scheduler" background || { + __framework_sh__run_server background || { panic "Error calling __framework_sh__run_server" return 1 } @@ -337,13 +297,22 @@ __framework_sh__run_both() { return 0 } +# Optionally accepts a subdirectory +# This is intended to namespace distinct runtime configs run in a single command __framework_sh__create_and_export_results_directory() { + if (($# > 1)); then + printf "[ERR]\n" + panic "Invalid number of arguments. Saw $#. Expected 0 or 1." + return 1 + fi + + local -r subdirectory=${1:-""} local dir="" # If we are running both client, and server, we need to namespace by scheduler since we run both variants case "$__framework_sh__role" in "both") - dir="$__framework_sh__application_directory/res/$__framework_sh__timestamp/$scheduler" + dir="$__framework_sh__application_directory/res/$__framework_sh__timestamp/$subdirectory" ;; "client" | "server" | "debug" | "perf") dir="$__framework_sh__application_directory/res/$__framework_sh__timestamp" @@ -382,13 +351,13 @@ main() { __framework_sh__run_both ;; server) - __framework_sh__run_server "$__framework_sh__policy" foreground + __framework_sh__run_server foreground ;; debug) - __framework_sh__run_debug "$__framework_sh__policy" + __framework_sh__run_debug ;; perf) - __framework_sh__run_perf "$__framework_sh__policy" + __framework_sh__run_perf ;; client) __framework_sh__run_client