Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/bash
- # -*- coding: utf-8 -*-
- quiet_run() {
- "$@" >/dev/null 2>&1
- }
- c_locale_run() {
- LC_ALL="C.UTF-8" LANG="C.UTF-8" LANGUAGE="C" "$@"
- }
- is_int() {
- c_locale_run quiet_run printf "%d" "$1"
- }
- is_float() {
- c_locale_run quiet_run printf "%f" "$1"
- }
- log() {
- DATE_MAIN=`date +"%F %T.%N"`
- echo "[""$DATE_MAIN"" ""$LOG_IDENTITY""-""$BASHPID""]" "$@"
- }
- parse_args() {
- LOG_IDENTITY="Uninitialized"
- while getopts ":s:f:n:k:r:i:" OPT
- do
- case "$OPT" in
- s)
- FAIL=false
- mkdir -p -- "$OPTARG" || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as table path."
- exit 1
- else
- TABLE_PATH="$OPTARG"
- fi
- ;;
- f)
- FAIL=false
- is_int "$OPTARG" || FAIL=true
- [[ "$OPTARG" -ge "2" ]] || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as number of philosopers."
- exit 1
- else
- PHILOSOPHERS_COUNT="$OPTARG"
- fi
- ;;
- n)
- FAIL=false
- is_int "$OPTARG" || FAIL=true
- [[ "$OPTARG" -ge "0" ]] || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as maximum number meals."
- exit 1
- else
- MAX_MEALS="$OPTARG"
- fi
- ;;
- k)
- FAIL=false
- is_float "$OPTARG" || FAIL=true
- if (( $(echo "$OPTARG<0" | bc) )); then
- FAIL=true
- fi
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as eating time."
- exit 1
- else
- EATING_TIME="$OPTARG"
- fi
- ;;
- r)
- FAIL=false
- is_float "$OPTARG" || FAIL=true
- if (( $(echo "$OPTARG<0" | bc) )); then
- FAIL=true
- fi
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as sleeping time."
- exit 1
- else
- SLEEPING_TIME="$OPTARG"
- fi
- ;;
- i)
- FAIL=false
- is_int "$OPTARG" || FAIL=true
- [[ "$OPTARG" -ge "1" ]] || FAIL=true
- if "$FAIL"
- then
- log "Cannot parse \`\`""$OPTARG""'' as philosopher ID."
- exit 1
- else
- PHILOSOPHER_ID="$OPTARG"
- LOG_IDENTITY="FID#""$PHILOSOPHER_ID"
- fi
- ;;
- \:)
- log "\`\`""-$OPTARG""'' requires some value."
- exit 1
- ;;
- \?)
- log "\`\`""-$OPTARG""'' is not a valid argument."
- exit 1
- ;;
- esac
- done
- mkdir -p "$TABLE_PATH""stol"
- TABLE_PATH=${TABLE_PATH:-`realpath -- "$TABLE_PATH""stol"`}
- PHILOSOPHERS_COUNT=${PHILOSOPHERS_COUNT:-5}
- MAX_MEALS=${MAX_MEALS:-7}
- SLEEPING_TIME=${SLEEPING_TIME:-0}
- EATING_TIME={ EATING_TIME:-0}
- PHILOSOPHER_ID=${PHILOSOPHER_ID:-0}
- TABLE_LOCK="$TABLE_PATH""/fifio"
- if [[ "$PHILOSOPHER_ID" -gt "$PHILOSOPHERS_COUNT" ]]
- then
- log "Philosopher ID greater than number of philosophers (\`\`""$PHILOSOPHER_ID""'' vs \`\`""$PHILOSOPHERS_COUNT""'')."
- exit 1
- fi
- MESSAGE=""
- MESSAGE="$MESSAGE""Script file: "`realpath -- "$0"`"; "
- MESSAGE="$MESSAGE""Execution arguments: """$@"""; "
- if [[ "$PHILOSOPHER_ID" -eq "0" ]]
- then
- LOG_IDENTITY="Main"
- MESSAGE="$MESSAGE""Context: ""$LOG_IDENTITY""; "
- else
- MESSAGE="$MESSAGE""Context: ""$LOG_IDENTITY""; "
- if [[ "$PHILOSOPHER_ID" -eq "$PHILOSOPHERS_COUNT" ]]
- then
- FORK_B="$PHILOSOPHER_ID"
- FORK_A="1"
- else
- FORK_A="$PHILOSOPHER_ID"
- FORK_B=$[PHILOSOPHER_ID+1]
- fi
- FORK_A_PATH=`realpath -- "$TABLE_PATH""/""$FORK_A"`
- FORK_B_PATH=`realpath -- "$TABLE_PATH""/""$FORK_B"`
- fi
- MESSAGE="$MESSAGE""Table path: \`\`""$TABLE_PATH""''; "
- if [[ "$PHILOSOPHER_ID" -ne "0" ]]
- then
- MESSAGE="$MESSAGE""Primary fork: ""$FORK_A_PATH""; "
- MESSAGE="$MESSAGE""Secondary fork: ""$FORK_B_PATH""; "
- fi
- MESSAGE="$MESSAGE""Philosophers count: ""$PHILOSOPHERS_COUNT""; "
- MESSAGE="$MESSAGE""Maximum meals: ""$MAX_MEALS""; "
- if [[ "$EATING_TIME" -eq "0" ]]
- then
- MESSAGE="$MESSAGE""Eating time: randomized; "
- else
- MESSAGE="$MESSAGE""Eating time: ""$EATING_TIME""s; "
- fi
- if [[ "$SLEEPING_TIME" -eq "0" ]]
- then
- MESSAGE="$MESSAGE""Sleeping time: randomized; "
- else
- MESSAGE="$MESSAGE""Sleeping time: ""$SLEEPING_TIME""s; "
- fi
- log "^^^START^^^ ""$MESSAGE"
- }
- parse_args "$@"
- random_time() {
- echo "0.""$RANDOM"
- }
- do_eat() {
- log "Eating Meal#""$1"" started, it will take ""$2""s"
- sleep "$2"
- log "Eating Meal#""$1"" finished"
- }
- sleep_after() {
- log "Sleeping after Meal#""$1"" started, it will take ""$2""s"
- sleep "$2"
- log "Sleeping after Meal#""$1"" finished"
- }
- run_philosopher() {
- parse_args "$@"
- HALF_TIME=$[(MAX_MEALS+1)/2]
- MEALS_CONSUMED=0
- for MEAL_ID in `seq 1 "$MAX_MEALS"`
- do
- ACTUAL_EATING_TIME=${EATING_TIME:-`random_time`}
- ACTUAL_SLEEPING_TIME=${SLEEPING_TIME:-`random_time`}
- log "Trying to acquire Fork WID#""$FORK_A (trying to put exclusive lock on fork "$FORK_A")"
- (
- flock -x 9
- log "Fork WID#""$FORK_A"" acquired successfully(exclusive lock put on fork "$FORK_A")"
- log "Trying to acquire Fork WID#""$FORK_B(trying to put exclusive lock on fork "$FORK_B")"
- (
- flock -x 10
- log "Fork WID#""$FORK_B"" acquired successfully(exclusive lock put on fork "$FORK_B")"
- do_eat "$MEAL_ID" "$ACTUAL_EATING_TIME"
- ) 10>"$FORK_B_PATH"
- log "Putting Fork WID#""$FORK_A"" back(exclusive lock droped from fork "$FORK_B")"
- ) 9>"$FORK_A_PATH"
- log "Putting Fork WID#""$FORK_B"" back(exclusive lock droped from fork "$FORK_B")"
- MEALS_CONSUMED=$[MEALS_CONSUMED+1]
- sleep_after "$MEAL_ID" "$ACTUAL_SLEEPING_TIME"
- if [[ "$MEAL_ID" -eq "$HALF_TIME" ]]
- then
- log "---POŁOWA--- Meals consumed: ""$MEALS_CONSUMED"
- echo > "$TABLE_LOCK"
- read line < "$TABLE_LOCK""1"
- log "Barrier is passed."
- fi
- done
- log "___STOP___ Meals consumed: ""$MEALS_CONSUMED"
- }
- mkfifo "$TABLE_LOCK"
- mkfifo "$TABLE_LOCK""1"
- a=( $(shuf -e $(seq 1 "$PHILOSOPHERS_COUNT")) )
- for i in "${a[@]}"
- do
- log `hostname`" STARTUJE FILOZOF... -s "$TABLE_PATH" -f "$PHILOSOPHERS_COUNT" -n "$MAX_MEALS" -k "$EATING_TIME" -r "$SLEEPING_TIME" -i "$i""
- run_philosopher -s "$TABLE_PATH" -f "$PHILOSOPHERS_COUNT" -n "$MAX_MEALS" -k "$EATING_TIME" -r "$SLEEPING_TIME" -i "$i" &
- done
- for i in `seq 1 "$PHILOSOPHERS_COUNT"`
- do
- read line < "$TABLE_LOCK"
- done
- for i in `seq 1 "$PHILOSOPHERS_COUNT"`
- do
- echo > "$TABLE_LOCK""1"
- done
- wait
- log "___STOP___"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement