#!/usr/bin/env bash
#
# This script will print out a conservative nr of threads.
# If a value is given it is returned capped to the nr of threads available.
# If no value or 0 is given, there are two cases:
# 1. with hyperthreading -> return nr of cores
# 2. no hyperthreading -> nr of threads / 2
#
get_nthreads_conservative() {
    local rval=0
    [[ $# -eq 1 ]] && rval="$1"

    local ostype="$(uname)"
    local ncores=0 #$(grep "^core id" /proc/cpuinfo | sort -u | wc -l)
    local nthrds=0 #$(grep "^core id" /proc/cpuinfo | wc -l)
    if [[ "$ostype" == "Linux" ]]; then
        ncores=$( grep "^core id" /proc/cpuinfo | sort -u | wc -l )
        nthrds=$( grep -c "^core id" /proc/cpuinfo )
    elif [[ "$ostype" == "Darwin" ]]; then
        ncores=$( sysctl -n hw.physicalcpu )
        nthrds=$( sysctl -n hw.logicalcpu )
    else
        echo "OS not supported: $ostype"
    fi
    local nhyper=$((nthrds/ncores))
    if (( rval == 0 )); then
        # 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_nthreads_conservative "$@"
