/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks is distributed in the hope that it will be
    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

#include "tbb/compat/condition_variable"
#include "tbb/mutex.h"
#include "tbb/recursive_mutex.h"
#include "tbb/tick_count.h"
#include "tbb/atomic.h"

#include "harness.h"

// This test deliberately avoids a "using tbb" statement,
// so that the error of putting types in the wrong namespace will be caught.

using namespace std;

template<typename M>
struct Counter {
    typedef M mutex_type;
    M mutex;
    volatile long value; 
    void flog_once_lock_guard( size_t mode );
    void flog_once_unique_lock( size_t mode );
};

template<typename M>
void Counter<M>::flog_once_lock_guard(size_t mode)
/** Increments counter once for each iteration in the iteration space. */
{
    if( mode&1 ) {
        // Try acquire and release with implicit lock_guard
        // precondition: if mutex_type is not a recursive mutex, the calling thread does not own the mutex m.
        // if the prcondition is not met, either dead-lock incorrect 'value' would result in.
        lock_guard<M> lg(mutex);
        value = value+1;
    } else {
        // Try acquire and release with adopt lock_quard
        // precodition: the calling thread owns the mutex m.
        // if the prcondition is not met, incorrect 'value' would result in because the thread unlocks
        // mutex that it does not own.
        mutex.lock();
        lock_guard<M> lg( mutex, adopt_lock );
        value = value+1;
    }
}

template<typename M>
void Counter<M>::flog_once_unique_lock(size_t mode)
/** Increments counter once for each iteration in the iteration space. */
{
    switch( mode&7 ) {
    case 0:
        {// implicitly acquire and release mutex with unique_lock
          unique_lock<M> ul( mutex );
          value = value+1;
          ASSERT( ul==true, NULL );
        }
        break;
    case 1:
        {// unique_lock with defer_lock
          unique_lock<M> ul( mutex, defer_lock );
          ASSERT( ul.owns_lock()==false, NULL );
          ul.lock();
          value = value+1;
          ASSERT( ul.owns_lock()==true, NULL );
        }
        break;
    case 2:
        {// unique_lock::try_lock() with try_to_lock
          unique_lock<M> ul( mutex, try_to_lock );
          if( !ul )
              while( !ul.try_lock() )
                  __TBB_Yield();
          value = value+1;
        }
        break;
    case 3:
        {// unique_lock::try_lock_for() with try_to_lock
          unique_lock<M> ul( mutex, defer_lock );
          tbb::tick_count::interval_t i(1.0);
          while( !ul.try_lock_for( i ) )
              ;
          value = value+1;
          ASSERT( ul.owns_lock()==true, NULL );
        }
        break;
    case 4:
        {
          unique_lock<M> ul_o4;
          {// unique_lock with adopt_lock
            mutex.lock();
            unique_lock<M> ul( mutex, adopt_lock );
            value = value+1;
            ASSERT( ul.owns_lock()==true, NULL );
            ASSERT( ul.mutex()==&mutex, NULL );
            ASSERT( ul_o4.owns_lock()==false, NULL );
            ASSERT( ul_o4.mutex()==NULL, NULL );
            swap( ul, ul_o4 );
            ASSERT( ul.owns_lock()==false, NULL );
            ASSERT( ul.mutex()==NULL, NULL );
            ASSERT( ul_o4.owns_lock()==true, NULL );
            ASSERT( ul_o4.mutex()==&mutex, NULL );
            ul_o4.unlock();
          }
          ASSERT( ul_o4.owns_lock()==false, NULL );
        }
        break;
    case 5:
        {
          unique_lock<M> ul_o5;
          {// unique_lock with adopt_lock
            mutex.lock();
            unique_lock<M> ul( mutex, adopt_lock );
            value = value+1;
            ASSERT( ul.owns_lock()==true, NULL );
            ASSERT( ul.mutex()==&mutex, NULL );
            ASSERT( ul_o5.owns_lock()==false, NULL );
            ASSERT( ul_o5.mutex()==NULL, NULL );
            ul_o5.swap( ul );
            ASSERT( ul.owns_lock()==false, NULL );
            ASSERT( ul.mutex()==NULL, NULL );
            ASSERT( ul_o5.owns_lock()==true, NULL );
            ASSERT( ul_o5.mutex()==&mutex, NULL );
            ul_o5.unlock();
          }
          ASSERT( ul_o5.owns_lock()==false, NULL );
        }
        break;
    default:
        {// unique_lock with adopt_lock, and release()
          mutex.lock();
          unique_lock<M> ul( mutex, adopt_lock );
          ASSERT( ul==true, NULL );
          value = value+1;
          M* old_m = ul.release();
          old_m->unlock();
          ASSERT( ul.owns_lock()==false, NULL );
        }
        break;
    }
}

static tbb::atomic<size_t> Order;

template<typename State, long TestSize>
struct WorkForLocks: NoAssign {
    static const size_t chunk = 100;
    State& state;
    WorkForLocks( State& state_ ) : state(state_) {}
    void operator()( int ) const {
        size_t step;
        while( (step=Order.fetch_and_add<tbb::acquire>(chunk))<TestSize ) {
            for( size_t i=0; i<chunk && step<TestSize; ++i, ++step ) {
                state.flog_once_lock_guard(step);
                state.flog_once_unique_lock(step);
            }
        }
    }
};

template<typename M>
void TestLocks( const char* name, int nthread ) {
    REMARK("testing %s in TestLocks\n",name);
    Counter<M> counter;
    counter.value = 0;
    Order = 0;
    const long test_size = 100000;
    NativeParallelFor( nthread, WorkForLocks<Counter<M>, test_size>(counter) );

    if( counter.value!=2*test_size )
        REPORT("ERROR for %s in TestLocks: counter.value=%ld != 2 * %ld=test_size\n",name,counter.value,test_size);
}

static tbb::atomic<int> barrier;

// Test if the constructor works and if native_handle() works
template<typename M>
struct WorkForCondVarCtor: NoAssign {
    condition_variable& my_cv;
    M& my_mtx;
    WorkForCondVarCtor( condition_variable& cv_, M& mtx_ ) : my_cv(cv_), my_mtx(mtx_) {}
    void operator()( int tid ) const {
        ASSERT( tid<=1, NULL ); // test with 2 threads.
        condition_variable::native_handle_type handle = my_cv.native_handle();
        if( tid&1 ) {
            my_mtx.lock();
            ++barrier;
#if _WIN32||_WIN64
            if( !tbb::interface5::internal::internal_condition_variable_wait( *handle, &my_mtx ) ) {
                int ec = GetLastError();
                ASSERT( ec!=WAIT_TIMEOUT, NULL );
                throw_exception( tbb::internal::eid_condvar_wait_failed );
            }
#else
            if( pthread_cond_wait( handle, my_mtx.native_handle() ) )
                throw_exception( tbb::internal::eid_condvar_wait_failed );
#endif
            ++barrier;
            my_mtx.unlock();
        } else {
            bool res;
            while( (res=my_mtx.try_lock())==true && barrier==0 ) {
                my_mtx.unlock();
                __TBB_Yield();
            }
            if( res ) my_mtx.unlock();
            do {
#if _WIN32||_WIN64
                tbb::interface5::internal::internal_condition_variable_notify_one( *handle );
#else
                pthread_cond_signal( handle );
#endif
                __TBB_Yield();
            } while ( barrier<2 );
        }
    }
};

static condition_variable* test_cv;
static tbb::atomic<int> n_waiters;

// Test if the destructor works 
template<typename M>
struct WorkForCondVarDtor: NoAssign {
    int nthread;
    M& my_mtx;
    WorkForCondVarDtor( int n, M& mtx_ ) : nthread(n), my_mtx(mtx_) {}
    void operator()( int tid ) const {
        if( tid==0 ) {
            unique_lock<M> ul( my_mtx, defer_lock );
            test_cv = new condition_variable;

            while( n_waiters<nthread-1 )
                __TBB_Yield();
            ul.lock();
            test_cv->notify_all();
            ul.unlock();
            while( n_waiters>0 )
                __TBB_Yield();
            delete test_cv;
        } else {
            while( test_cv==NULL )
                __TBB_Yield();
            unique_lock<M> ul(my_mtx);
            ++n_waiters;
            test_cv->wait( ul );
            --n_waiters;
        }
    }
};

static const int max_ticket  = 100;
static const int short_delay = 10;
static const int long_delay  = 100;

tbb::atomic<int> n_signaled;
tbb::atomic<int> n_done, n_done_1, n_done_2;
tbb::atomic<int> n_timed_out;

static bool false_to_true;

struct TestPredicateFalseToTrue {
    TestPredicateFalseToTrue() {}
    bool operator()() { return false_to_true; }
};

struct TestPredicateFalse {
    TestPredicateFalse() {}
    bool operator()() { return false; }
};

struct TestPredicateTrue {
    TestPredicateTrue() {}
    bool operator()() { return true; }
};

// Test timed wait and timed wait with pred
template<typename M>
struct WorkForCondVarTimedWait: NoAssign {
    int nthread;
    condition_variable& test_cv;
    M& my_mtx;
    WorkForCondVarTimedWait( int n_, condition_variable& cv_, M& mtx_ ) : nthread(n_), test_cv(cv_), my_mtx(mtx_) {}
    void operator()( int tid ) const {
        tbb::tick_count t1, t2;

        unique_lock<M> ul( my_mtx, defer_lock );

        ASSERT( n_timed_out==0, NULL );
        ++barrier;
        while( barrier<nthread ) __TBB_Yield();

        // test if a thread times out with wait_for()
        for( int i=1; i<10; ++i ) {
            tbb::tick_count::interval_t intv((double)i*0.0001 /*seconds*/);
            ul.lock();
            cv_status st = no_timeout;
            __TBB_TRY {
                /** Some version of glibc return EINVAL instead 0 when spurious wakeup occurs on pthread_cond_timedwait() **/
                st = test_cv.wait_for( ul, intv );
            } __TBB_CATCH( std::runtime_error& ) {}
            ASSERT( ul, "mutex should have been reacquired" );
            ul.unlock();
            if( st==timeout )
                ++n_timed_out;
        }

        ASSERT( n_timed_out>0, "should have been timed-out at least once\n" );
        ++n_done_1;
        while( n_done_1<nthread ) __TBB_Yield();

        for( int i=1; i<10; ++i ) {
            tbb::tick_count::interval_t intv((double)i*0.0001 /*seconds*/);
            ul.lock();
            __TBB_TRY {
                /** Some version of glibc return EINVAL instead 0 when spurious wakeup occurs on pthread_cond_timedwait() **/
                ASSERT( false==test_cv.wait_for( ul, intv, TestPredicateFalse()), "incorrect return value" );
            } __TBB_CATCH( std::runtime_error& ) {}
            ASSERT( ul, "mutex should have been reacquired" );
            ul.unlock();
        }

        if( tid==0 )
            n_waiters = 0;
        // barrier
        ++n_done_2;
        while( n_done_2<nthread ) __TBB_Yield();

        // at this point, we know wait_for() successfully times out.
        // so test if a thread blocked on wait_for() could receive a signal before its waiting time elapses.
        if( tid==0 ) {
            // signaler
            n_signaled = 0;
            ASSERT( n_waiters==0, NULL );
            ++n_done_2; // open gate 1

            while( n_waiters<(nthread-1) ) __TBB_Yield(); // wait until all other threads block on cv. flag_1

            ul.lock();
            test_cv.notify_all();
            n_waiters = 0;
            ul.unlock();

            while( n_done_2<2*nthread ) __TBB_Yield();
            ASSERT( n_signaled>0, "too small an interval?" );
            n_signaled = 0;

        } else {
            while( n_done_2<nthread+1 ) __TBB_Yield(); // gate 1

            // sleeper
            tbb::tick_count::interval_t intv((double)2.0 /*seconds*/);
            ul.lock();
            ++n_waiters; // raise flag 1/(nthread-1) 
            t1 = tbb::tick_count::now();
            cv_status st = test_cv.wait_for( ul, intv ); // gate 2
            t2 = tbb::tick_count::now();
            ul.unlock();
            if( st==no_timeout ) {
                ++n_signaled;
                ASSERT( (t2-t1).seconds()<intv.seconds(), "got a signal after timed-out?" );
            }
        }

        ASSERT( n_done==0, NULL );
        ++n_done_2;

        if( tid==0 ) {
            ASSERT( n_waiters==0, NULL );
            ++n_done; // open gate 3

            while( n_waiters<(nthread-1) ) __TBB_Yield(); // wait until all other threads block on cv.
            for( int i=0; i<2*short_delay; ++i ) __TBB_Yield();  // give some time to waiters so that all of them in the waitq 
            ul.lock();
            false_to_true = true;
            test_cv.notify_all(); // open gate 4
            ul.unlock();

            while( n_done<nthread ) __TBB_Yield(); // wait until all other threads wake up.
            ASSERT( n_signaled>0, "too small an interval?" );
        } else {

            while( n_done<1 ) __TBB_Yield(); // gate 3

            tbb::tick_count::interval_t intv((double)2.0 /*seconds*/);
            ul.lock();
            ++n_waiters;
            // wait_for w/ predciate
            t1 = tbb::tick_count::now();
            ASSERT( test_cv.wait_for( ul, intv, TestPredicateFalseToTrue())==true, NULL ); // gate 4
            t2 = tbb::tick_count::now();
            ul.unlock();
            if( (t2-t1).seconds()<intv.seconds() )
                ++n_signaled;
            ++n_done;
        }
    }
};

tbb::atomic<int> ticket_for_sleep, ticket_for_wakeup, signaled_ticket, wokeup_ticket;
tbb::atomic<unsigned> n_visit_to_waitq;
unsigned max_waitq_length;

template<typename M>
struct WorkForCondVarWaitAndNotifyOne: NoAssign {
    int nthread;
    condition_variable& test_cv;
    M& my_mtx;
    WorkForCondVarWaitAndNotifyOne( int n_, condition_variable& cv_, M& mtx_ ) : nthread(n_), test_cv(cv_), my_mtx(mtx_) {}
    void operator()( int tid ) const {
        if( tid&1 ) {
            // exercise signal part
            while( ticket_for_wakeup<max_ticket ) {
                int my_ticket = ++ticket_for_wakeup; // atomically grab the next ticket
                if( my_ticket>max_ticket )
                    break;

                for( ;; ) {
                    unique_lock<M> ul( my_mtx, defer_lock );
                    ul.lock();
                    if( n_waiters>0 && my_ticket<=ticket_for_sleep && my_ticket==(wokeup_ticket+1) ) {
                        signaled_ticket = my_ticket;
                        test_cv.notify_one();
                        ++n_signaled;
                        ul.unlock();
                        break;
                    }
                    ul.unlock();
                    __TBB_Yield();
                }
    
                // give waiters time to go to sleep.
                for( int m=0; m<short_delay; ++m )
                    __TBB_Yield();
            }
        } else {
            while( ticket_for_sleep<max_ticket ) {
                unique_lock<M> ul( my_mtx, defer_lock );
                ul.lock();
                // exercise wait part
                int my_ticket = ++ticket_for_sleep; // grab my ticket
                if( my_ticket>max_ticket ) break;

                // each waiter should go to sleep at least once
                unsigned nw = ++n_waiters;
                for( ;; ) {
                    // update to max_waitq_length 
                    if( nw>max_waitq_length ) max_waitq_length = nw;
                    ++n_visit_to_waitq;
                    test_cv.wait( ul );
                    // if( ret==false ) ++n_timedout;
                    ASSERT( ul, "mutex should have been locked" );
                    --n_waiters;
                    if( signaled_ticket==my_ticket ) {
                        wokeup_ticket = my_ticket;
                        break;
                    }
                    if( n_waiters>0 )
                        test_cv.notify_one();
                    nw = ++n_waiters; // update to max_waitq_length occurs above
                }

                ul.unlock();
                __TBB_Yield(); // give other threads chance to run.
            }
        }
        ++n_done;
        spin_wait_until_eq( n_done, nthread );
        ASSERT( n_signaled==max_ticket, "incorrect number of notifications sent" );
    }
};

struct TestPredicate1 {
    int target;
    TestPredicate1( int i_ ) : target(i_) {}
    bool operator()( ) { return signaled_ticket==target; }
};

template<typename M>
struct WorkForCondVarWaitPredAndNotifyAll: NoAssign {
    int nthread;
    condition_variable& test_cv;
    M& my_mtx;
    int multiple;
    WorkForCondVarWaitPredAndNotifyAll( int n_, condition_variable& cv_, M& mtx_, int m_ ) : 
        nthread(n_), test_cv(cv_), my_mtx(mtx_), multiple(m_) {}
    void operator()( int tid ) const {
        if( tid&1 ) {
            while( ticket_for_sleep<max_ticket ) {
                unique_lock<M> ul( my_mtx, defer_lock );
                // exercise wait part
                int my_ticket = ++ticket_for_sleep; // grab my ticket
                if( my_ticket>max_ticket ) 
                    break;

                ul.lock();
                ++n_visit_to_waitq;
                unsigned nw = ++n_waiters;
                if( nw>max_waitq_length ) max_waitq_length = nw;
                test_cv.wait( ul, TestPredicate1( my_ticket ) );
                wokeup_ticket = my_ticket;
                --n_waiters;
                ASSERT( ul, "mutex should have been locked" );
                ul.unlock();

                __TBB_Yield(); // give other threads chance to run.
            }
        } else {
            // exercise signal part
            while( ticket_for_wakeup<max_ticket ) {
                int my_ticket = ++ticket_for_wakeup; // atomically grab the next ticket
                if( my_ticket>max_ticket )
                    break;

                for( ;; ) {
                    unique_lock<M> ul( my_mtx );
                    if( n_waiters>0 && my_ticket<=ticket_for_sleep && my_ticket==(wokeup_ticket+1) ) {
                        signaled_ticket = my_ticket;
                        test_cv.notify_all();
                        ++n_signaled;
                        ul.unlock();
                        break;
                    }
                    ul.unlock();
                    __TBB_Yield();
                }
    
                // give waiters time to go to sleep.
                for( int m=0; m<long_delay*multiple; ++m )
                    __TBB_Yield();
            }
        }
        ++n_done;
        spin_wait_until_eq( n_done, nthread );
        ASSERT( n_signaled==max_ticket, "incorrect number of notifications sent" );
    }
};

void InitGlobalCounters()
{
      ticket_for_sleep = ticket_for_wakeup = signaled_ticket = wokeup_ticket = 0;
      n_waiters = 0;
      n_signaled = 0;
      n_done = n_done_1 = n_done_2 = 0;
      n_visit_to_waitq = 0;
      n_timed_out = 0;
}

template<typename M>
void TestConditionVariable( const char* name, int nthread )
{
    REMARK("testing %s in TestConditionVariable\n",name);
    Counter<M> counter;
    M mtx;

    ASSERT( nthread>1, "at least two threads are needed for testing condition_variable" );
    REMARK(" - constructor\n" );
    // Test constructor.
    {
      condition_variable cv1;
#if _WIN32||_WIN64
      condition_variable::native_handle_type handle = cv1.native_handle();
      ASSERT( uintptr_t(&handle->cv_event)==uintptr_t(&handle->cv_native), NULL );
#endif
      M mtx1;
      barrier = 0;
      NativeParallelFor( 2, WorkForCondVarCtor<M>( cv1, mtx1 ) );
    }

    REMARK(" - destructor\n" );
    // Test destructor.
    {
      M mtx2;
      test_cv = NULL;
      n_waiters = 0;
      NativeParallelFor( nthread, WorkForCondVarDtor<M>( nthread, mtx2 ) );
    }

    REMARK(" - timed_wait (i.e., wait_for)\n");
    // Test timed wait.
    {
      condition_variable cv_tw;
      M mtx_tw;
      barrier = 0;
      InitGlobalCounters();
      int nthr = nthread>4?4:nthread;
      NativeParallelFor( nthr, WorkForCondVarTimedWait<M>( nthr, cv_tw, mtx_tw ) );
    }

    REMARK(" - wait with notify_one\n");
    // Test wait and notify_one
    do {
        condition_variable cv3;
        M mtx3;
        InitGlobalCounters();
        NativeParallelFor( nthread, WorkForCondVarWaitAndNotifyOne<M>( nthread, cv3, mtx3 ) );
    } while( n_visit_to_waitq==0 || max_waitq_length==0 );

    REMARK(" - predicated wait with notify_all\n");
    // Test wait_pred and notify_all
    int delay_multiple = 1;
    do {
        condition_variable cv4;
        M mtx4;
        InitGlobalCounters();
        NativeParallelFor( nthread, WorkForCondVarWaitPredAndNotifyAll<M>( nthread, cv4, mtx4, delay_multiple ) );
        if( max_waitq_length<unsigned(nthread/2) )
            ++delay_multiple;
    } while( n_visit_to_waitq<=0 || max_waitq_length<unsigned(nthread/2) ); 
}

#if TBB_USE_EXCEPTIONS
static tbb::atomic<int> err_count;

#define TRY_AND_CATCH_RUNTIME_ERROR(op,msg) \
        try {                             \
            op;                           \
            ++err_count;                  \
        } catch( std::runtime_error& e ) {ASSERT( strstr(e.what(), msg) , NULL );} catch(...) {++err_count;}

template<typename M>
void TestUniqueLockException( const char * name ) {
    REMARK("testing %s TestUniqueLockException\n",name);
    M mtx;
    unique_lock<M> ul_0;
    err_count = 0;

    TRY_AND_CATCH_RUNTIME_ERROR( ul_0.lock(), "Operation not permitted" );
    TRY_AND_CATCH_RUNTIME_ERROR( ul_0.try_lock(), "Operation not permitted" );

    unique_lock<M> ul_1( mtx );

    TRY_AND_CATCH_RUNTIME_ERROR( ul_1.lock(), "Resource deadlock" );
    TRY_AND_CATCH_RUNTIME_ERROR( ul_1.try_lock(), "Resource deadlock" );

    ul_1.unlock();
    TRY_AND_CATCH_RUNTIME_ERROR( ul_1.unlock(), "Operation not permitted" );

    ASSERT( !err_count, "Some exceptions are not thrown or incorrect ones are thrown" );
}

template<typename M>
void TestConditionVariableException( const char * name ) {
    REMARK("testing %s in TestConditionVariableException; yet to be implemented\n",name);
}
#endif /* TBB_USE_EXCEPTIONS */

template<typename Mutex, typename RecursiveMutex>
void DoCondVarTest()
{
    for( int p=MinThread; p<=MaxThread; ++p ) {
        REMARK( "testing with %d threads\n", p );
        TestLocks<Mutex>( "mutex", p );
        TestLocks<RecursiveMutex>( "recursive_mutex", p );

        if( p<=1 ) continue;

        // for testing condition_variable, at least one sleeper and one notifier are needed
        TestConditionVariable<Mutex>( "mutex", p );
    }
#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN
    REPORT("Known issue: exception handling tests are skipped.\n");
#elif TBB_USE_EXCEPTIONS
    TestUniqueLockException<Mutex>( "mutex" );
    TestUniqueLockException<RecursiveMutex>( "recursive_mutex" );
    TestConditionVariableException<Mutex>( "mutex" );
#endif /* TBB_USE_EXCEPTIONS */
}
