/*
    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 "thread_monitor.h"
#include "harness.h"
#include "harness_memory.h"

class ThreadState {
    void loop();
public:
    static __RML_DECL_THREAD_ROUTINE routine( void* arg ) {
        static_cast<ThreadState*>(arg)->loop();
        return 0;
    }
    typedef rml::internal::thread_monitor thread_monitor;
    thread_monitor monitor;
    volatile int request;
    volatile int ack;
    volatile unsigned clock;
    volatile unsigned stamp;
    ThreadState() : request(-1), ack(-1), clock(0) {}
};


void ThreadState::loop() {
    for(;;) {
        ++clock;
        if( ack==request ) {
            thread_monitor::cookie c;
            monitor.prepare_wait(c);
            if( ack==request ) {
                REMARK("%p: request=%d ack=%d\n", this, request, ack );
                monitor.commit_wait(c);
            } else
                monitor.cancel_wait();
        } else {
            // Throw in delay occasionally
            switch( request%8 ) {
                case 0: 
                case 1:
                case 5:
                    rml::internal::thread_monitor::yield();
            }
            int r = request;
            ack = request;
            if( !r ) return;
        }
    }
}

// Linux on Itanium seems to require at least 1<<18 bytes per stack.
const size_t MinStackSize = 1<<18;
const size_t MaxStackSize = 1<<22;

int TestMain () {
    for( int p=MinThread; p<=MaxThread; ++p ) {
        ThreadState* t = new ThreadState[p];
        for( size_t stack_size = MinStackSize; stack_size<=MaxStackSize; stack_size*=2 ) {
            REMARK("launching %d threads\n",p);
            for( int i=0; i<p; ++i )
                rml::internal::thread_monitor::launch( ThreadState::routine, t+i, stack_size ); 
            for( int k=1000; k>=0; --k ) {
                if( k%8==0 ) {
                    // Wait for threads to wait.
                    for( int i=0; i<p; ++i ) {
                        unsigned count = 0;
                        do {
                            t[i].stamp = t[i].clock;
                            rml::internal::thread_monitor::yield();
                            if( ++count>=1000 ) {
                                REPORT("Warning: thread %d not waiting\n",i);
                                break;
                            }
                        } while( t[i].stamp!=t[i].clock );
                    }
                }
                REMARK("notifying threads\n");
                for( int i=0; i<p; ++i ) {
                    // Change state visible to launched thread
                    t[i].request = k;
                    t[i].monitor.notify();
                }
                REMARK("waiting for threads to respond\n");
                for( int i=0; i<p; ++i ) 
                    // Wait for thread to respond 
                    while( t[i].ack!=k ) 
                        rml::internal::thread_monitor::yield();
            }
        }
        delete[] t;
    }

    return Harness::Done;
}
