#!/usr/bin/env bash
# get OS type
# this should only be "Linux" or "Darwin" (check_prerequisites.sh)
export OSTYPE=$(uname -s)

#-----------------------------------------------
# get nr of cpus and cores on the machine
# support for both macos and linux
#-----------------------------------------------
# OS dependent functions
_get_ncores_Darwin()   { sysctl -n hw.physicalcpu; }
_get_nthreads_Darwin() { sysctl -n hw.logicalcpu; }
_get_ncores_Linux()    { grep "^core id" /proc/cpuinfo | sort -u | wc -l; }
_get_nthreads_Linux()  { grep -c "^core id" /proc/cpuinfo; }

# get the nr of physical cores
get_ncores() { _get_ncores_$OSTYPE; }

# get total nr of threads
get_nthreads_total() { _get_nthreads_$OSTYPE; }

# get hyperthreading (threads per core)
get_hyperthreading() {
    local ncores=$(get_ncores)
    local nth=$(get_nthreads_total)
    echo $((nth/ncores))
}

#---------------------------------------------------------------------------
# get nr of threads given a suggestion
# it will be capped by the total nr of threads available
get_nthreads() {
    local nt=$(get_nthreads_total)
    local nreq=$nt
    [[ $#    -eq 0   ]] || nreq=$1
    [[ $nreq -gt $nt ]] && nreq=$nt
    [[ $nreq -lt 1   ]] && nreq=1
    echo $nreq
}

# get a conservative nr of threads
# 1. input > 0
#    returned a capped value (by max nr of threads available)
# 2. input == 0
#    if hyperthreading, return nr of cores
#    else return nr of cores/2
# ensure that it returns at least 1
get_nthreads_conservative() {
    local rval=0
    [[ $# -eq 1 ]] && rval="$1"
    
    local nthrds=$(get_nthreads_total)
    local ncores=$(get_ncores)
    local nhyper=$(get_hyperthreading)

    if (( rval == 0 )); then
        # NJOBMAX is zero - set it based on hardware
        
        # if hyperthreading, use the nr of cores
        if (( nhyper > 1 )); then
            rval=$ncores
        else
            # no hyperthreading - use the nr of cores/2
            rval=$((ncores/2))
        fi
    else
        # nr of threads is already given - cap it at max value
        (( rval > nthrds )) && rval=$nthrds            
    fi
    # make sure it is at least 1
    (( rval > 0 )) || rval=1
    echo $rval
}

get_bogomips() {
    if [[ "$OSTYPE" == "Linux" ]]; then
        grep "^bogomips" /proc/cpuinfo | head -n 1 | cut -d ":" -f 2
    else
        echo "N/A"
    fi
}

export -f _get_ncores_Darwin
export -f _get_nthreads_Darwin
export -f _get_ncores_Linux
export -f _get_nthreads_Linux

export -f get_ncores
export -f get_nthreads_total
export -f get_hyperthreading

export -f get_nthreads
export -f get_nthreads_conservative

export -f get_bogomips
