Last active
September 6, 2023 03:06
-
-
Save sequix/c5da2e76bcebd654003437a323cb114f to your computer and use it in GitHub Desktop.
Revisions
-
sequix revised this gist
Sep 6, 2023 . 1 changed file with 41 additions and 15 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ set -euo pipefail help() { printf "cpuset.sh version: 3.1\n" printf "usage:\n" printf "cpuset.sh union 0-1 2 3-4,5 => 0-5\n" printf "cpuset.sh intersect 0-9 4-6 4-5 => 4-5\n" @@ -20,6 +20,8 @@ expand() { local acc="" local lacc="" local src="$1" local rst declare -a rst for (( i=0; i<${#src}; i++ )); do c="${src:$i:1}" case "$c" in @@ -36,9 +38,9 @@ expand() { ;; ,) if [ -n "$lacc" ]; then rst+=($(seq "$lacc" "$acc")) elif [ -n "$acc" ]; then rst+=("$acc") fi acc="" lacc="" @@ -51,10 +53,11 @@ expand() { lc="$c" done if [ -n "$lacc" ]; then rst+=($(seq "$lacc" "$acc")) elif [ -n "$acc" ]; then rst+=("$acc") fi <<<"${rst[@]}" tr ' ' '\n' | sort -nu } expand_to_file() { @@ -65,7 +68,7 @@ expand_to_file() { echo "$filename" } shrink_internal() { local cpus=("$@") local n=${#cpus[@]} @@ -110,7 +113,7 @@ union() { for cpus; do files+=($(expand_to_file "$cpus")) done shrink_internal $(sort -nu "${files[@]}") rm -f "${files[@]}" } @@ -120,7 +123,7 @@ intersect() { for cpus; do files+=($(expand_to_file "$cpus")) done shrink_internal $(sort -n "${files[@]}" | uniq -c | awk "\$1==${#files[@]} {print \$2}") rm -f "${files[@]}" } @@ -131,17 +134,40 @@ minus() { local bf="" af=$(expand_to_file "$a") bf=$(expand_to_file "$b") shrink_internal $(sort -n "$af" "$bf" "$bf" | uniq -u) rm -f "$af" "$bf" } tomask() { local cpus cpus=($(expand "$1")) local n=${#cpus[@]} if [ $n -eq 0 ]; then echo 0 return fi local c=0 local ni=0 local nc="${cpus[0]}" local max="${cpus[$((n-1))]}" local rst="" local rst_c=0 for ((c=0; c<=max; c+=4)); do rst_c=0 while [ "$((c+3))" -ge "$nc" ]; do rst_c=$(( rst_c | (1<<(nc-c)) )) ni=$((ni+1)) if [ "$ni" -ge "$n" ]; then break fi nc=${cpus[$ni]} done rst="$(printf "%x" ${rst_c})${rst}" done echo "$rst" } todigit() { @@ -227,7 +253,7 @@ todigit() { esac base=$((base+4)) done shrink_internal "${rst[@]}" } main() { -
sequix created this gist
Sep 5, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,298 @@ #!/bin/bash set -euo pipefail help() { printf "cpuset.sh version: 3\n" printf "usage:\n" printf "cpuset.sh union 0-1 2 3-4,5 => 0-5\n" printf "cpuset.sh intersect 0-9 4-6 4-5 => 4-5\n" printf "cpuset.sh minus 0-9 4-5 => 0-3,6-9\n" printf "cpuset.sh shrink 0,1,2,3 => 0-3\n" printf 'cpuset.sh expand 0-3 => 0\\n1\\n2\\n3\\n\n' printf "cpuset.sh tomask 0-15 => ffff\n" printf "cpuset.sh todigit ffff => 0-15\n" } expand() { local i=0 local c="" local lc="" local acc="" local lacc="" local src="$1" for (( i=0; i<${#src}; i++ )); do c="${src:$i:1}" case "$c" in [0-9]) acc=$((acc*10+$c)) ;; -) if ! <<<"$lc" grep -q "[0-9]"; then echo "invalid hyphen in set $src" exit 1 fi lacc="$acc" acc="" ;; ,) if [ -n "$lacc" ]; then seq "$lacc" "$acc" elif [ -n "$acc" ]; then echo "$acc" fi acc="" lacc="" ;; *) echo "invalid character '$c' in set $src" exit 1 ;; esac lc="$c" done if [ -n "$lacc" ]; then seq "$lacc" "$acc" elif [ -n "$acc" ]; then echo "$acc" fi } expand_to_file() { local src="$1" local filename="" filename=$(mktemp) expand "$src" >"$filename" echo "$filename" } shrink() { local cpus=("$@") local n=${#cpus[@]} if [ $n -eq 0 ]; then return elif [ $n -eq 1 ]; then echo "${cpus[0]}" return fi local i=0 local j=1 local ci="${cpus[0]}" local cj="" local cj1="" local rst="" for ((j=1; j < $n; j++)); do cj="${cpus[$j]}" cj1="${cpus[$((j-1))]}" if [ "$cj" -ne "$((cj1+1))" ]; then if [ "$j" -eq "$((i+1))" ]; then rst="${rst}${ci}," else rst="${rst}${ci}-${cj1}," fi i="$j" ci="${cj}" fi done if [ "$j" -eq "$((i+1))" ]; then rst="${rst}${ci}" else rst="${rst}${ci}-${cpus[$((j-1))]}" fi echo $rst } union() { local files declare -a files for cpus; do files+=($(expand_to_file "$cpus")) done shrink $(sort -n "${files[@]}" | uniq) rm -f "${files[@]}" } intersect() { local files declare -a files for cpus; do files+=($(expand_to_file "$cpus")) done shrink $(sort -n "${files[@]}" | uniq -c | awk "\$1==${#files[@]} {print \$2}") rm -f "${files[@]}" } minus() { local a="$1" local b="$2" local af="" local bf="" af=$(expand_to_file "$a") bf=$(expand_to_file "$b") shrink $(sort -n "$af" "$bf" "$bf" | uniq -u) rm -f "$af" "$bf" } tomask() { local rst=0 declare -i rst for cpu in $(expand "$1"); do rst=$((rst | 1<<cpu)) done printf "%x\n" $rst } todigit() { local c="" local src="$1" local i=${#src} local base=0 local rst declare -a rst for ((i=i-1; i>=0; i--)); do c=${src:$i:1} case "$c" in 0) true ;; 1) rst+=($((base+0))) ;; 2) rst+=($((base+1))) ;; 3) rst+=($((base+0))) rst+=($((base+1))) ;; 4) rst+=($((base+2))) ;; 5) rst+=($((base+0))) rst+=($((base+2))) ;; 6) rst+=($((base+1))) rst+=($((base+2))) ;; 7) rst+=($((base+0))) rst+=($((base+1))) rst+=($((base+2))) ;; 8) rst+=($((base+3))) ;; 9) rst+=($((base+0))) rst+=($((base+3))) ;; a|A) rst+=($((base+1))) rst+=($((base+3))) ;; b|B) rst+=($((base+0))) rst+=($((base+1))) rst+=($((base+3))) ;; c|C) rst+=($((base+2))) rst+=($((base+3))) ;; d|D) rst+=($((base+0))) rst+=($((base+2))) rst+=($((base+3))) ;; e|E) rst+=($((base+1))) rst+=($((base+2))) rst+=($((base+3))) ;; f|F) rst+=($((base+0))) rst+=($((base+1))) rst+=($((base+2))) rst+=($((base+3))) ;; *) echo "invalid mask '$src'" exit 1 ;; esac base=$((base+4)) done shrink "${rst[@]}" } main() { if [ $# -eq 0 ]; then help exit 0 fi case "$1" in union) shift 1 if [ $# -eq 0 ]; then echo "at least 1 argument for union action" exit 1 fi union "$@" ;; intersect) shift 1 if [ $# -eq 0 ]; then echo "at least 1 argument for intersect action" exit 1 fi intersect "$@" ;; minus) if [ $# -ne 3 ]; then echo "expected exact 2 arguments for minus action" exit 1 fi minus "$2" "$3" ;; shrink) if [ $# -ne 2 ]; then echo "expected exact 1 argument for shrink action" exit 1 fi union "$2" ;; expand) if [ $# -ne 2 ]; then echo "expected exact 1 argument for expand action" exit 1 fi expand "$2" ;; tomask) if [ $# -ne 2 ]; then echo "expected exact 1 argument for tomask action" exit 1 fi tomask "$2" ;; todigit) if [ $# -ne 2 ]; then echo "expected exact 1 argument for todigit action" exit 1 fi todigit "$2" ;; *) echo "invalid action '$1'" help exit 1 ;; esac } main "$@"