/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */

#define MAX_SEM_VAL 1

/* Semaphore value. */
int sem_value = MAX_SEM_VAL;

/* Endpoint. */
chan endpoint = [0] of {bit};

/* Users in critical section. */
byte users = 0;

inline do_wait(procnum)
{
    int oldval;

    /* Atomic decrement. */
    atomic {
        oldval = sem_value;
        sem_value--;
    }

    /* Conditional wait. */
    if
    :: (oldval <= 0) -> endpoint ? 1;
    :: (oldval > 0) -> skip;
    fi
}

inline do_try_wait(procnum)
{
    int observed_val;

    do
    :: true;
       observed_val = sem_value;
       if
       :: (observed_val <= 0) ->
           return 0;
           break;
       :: (observed_val > 0) ->
               /* Atomic compare and set: compare observed value, set
                * (observed_value - 1). */
               atomic {
                  if
                  :: (sem_value == observed_val) ->
                         sem_value = observed_val - 1;
                         return 1;
                         break;
                  :: (sem_value != observed_val) -> skip;
                  fi;
               };
       fi
    od
}

inline do_signal(procnum)
{
    int new_val;

    /* Atomic decrement. */
    atomic {
        sem_value++;
        new_val = sem_value;
    }

    /* Conditional wake. */
    if
    :: (new_val <= 0) -> endpoint ! 1;
    :: (new_val > 0) -> skip;
    fi
}

proctype wait_cpu(byte procnum)
{
    do
    :: true;
progress_wait:;
        /* Lock. */
        printf("%d getting the lock.\n", procnum);
        do_wait(procnum);
        printf("%d got the lock.\n", procnum);

        /* Use a common resource. */
        users++;
        assert(users <= MAX_SEM_VAL);
        users--;

        /* Release. */
        printf("%d releasing the lock\n", procnum);
        do_signal(procnum);
        printf("%d released the lock.\n", procnum);
    od
}

proctype trywait_cpu(byte procnum)
{
    byte x;
    do
    :: true;
progress_trywait:;
        /* Lock. */
        printf("%d trying to get the lock.\n", procnum);
        x = do_try_wait(procnum);
        if
        :: (x == 0) ->
            printf("%d failed to get the lock.\n", procnum);
        :: (x == 1) ->
            printf("%d got the lock.\n", procnum);

            /* Use a common resource. */
            users++;
            assert(users <= MAX_SEM_VAL);
            users--;

            /* Release. */
            printf("%d releasing the lock\n", procnum);
            do_signal(procnum);
            printf("%d released the lock.\n", procnum);
        fi
    od
}

init {
    atomic {
        run wait_cpu(1);
        run trywait_cpu(2);
        run trywait_cpu(3);
        run wait_cpu(4);
    }
}
