/*
 * Copyright (c) 2011-2013 Advanced Micro Devices, Inc.
 * Copyright (c) 2013 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Steve Reinhardt
 */

#include "sim/global_event.hh"

std::mutex BaseGlobalEvent::globalQMutex;

BaseGlobalEvent::BaseGlobalEvent(Priority p, Flags f)
    : barrier(numMainEventQueues),
      barrierEvent(numMainEventQueues, NULL)
{
}


BaseGlobalEvent::~BaseGlobalEvent()
{
    // see GlobalEvent::BarrierEvent::~BarrierEvent() comments
    if (barrierEvent[0] != NULL) {
        for (int i = 0; i < numMainEventQueues; ++i)
            delete barrierEvent[i];
    }
}


void BaseGlobalEvent::schedule(Tick when)
{
    // This function is scheduling a global event, which actually is a
    // set of local events, one event on each eventq. Global events need
    // to have a total order. A thread cannot start executing events that
    // follow a global event till all other threads have executed that global
    // event as well. If global events were not in a total order, a deadlock
    // would occur for there will be two threads who would be waiting for
    // each other to execute the global events they themselves have executed.
    //
    // To ensure this total order, we do two things.
    // First, before scheduling any global event, a thread needs to acquire
    // the lock globalQMutex. This ensures that only one thread can schedule
    // global events at any given time.
    // Second, the local events corresponding to a global event are always
    // first inserted in to the asyncq, irrespective of whether or not the
    // thread scheduling the event owns the eventq on which the event is
    // being scheduled. Thus global events have the same order in the asyncq
    // of each thread. When they are inserted in the actual eventq, the
    // comparators in the Event class ensure that the total order is
    // maintained.

    globalQMutex.lock();

    for (int i = 0; i < numMainEventQueues; ++i) {
        mainEventQueue[i]->schedule(barrierEvent[i], when, true);
    }

    globalQMutex.unlock();
}

void BaseGlobalEvent::deschedule()
{
    EventQueue *q = curEventQueue();
    for (uint32_t i = 0; i < numMainEventQueues; ++i) {
        if (barrierEvent[i]->scheduled()) {
            curEventQueue(mainEventQueue[i]);
            mainEventQueue[i]->deschedule(barrierEvent[i]);
        }
    }

    curEventQueue(q);
}

void BaseGlobalEvent::reschedule(Tick when)
{
    // Read the comment in the schedule() function above.
    globalQMutex.lock();

    for (uint32_t i = 0; i < numMainEventQueues; ++i) {
        if (barrierEvent[i]->scheduled())
            mainEventQueue[i]->reschedule(barrierEvent[i], when);
        else
            mainEventQueue[i]->schedule(barrierEvent[i], when, true);
    }

    globalQMutex.unlock();
}

BaseGlobalEvent::BarrierEvent::~BarrierEvent()
{
    // if AutoDelete is set, local events will get deleted in event
    // loop, but we need to delete GlobalEvent object too... so let
    // the local event in slot 0 do it
    if (isFlagSet(AutoDelete) && _globalEvent->barrierEvent[0] == this) {
        // set backpointer to NULL so that global event knows not to
        // turn around and recursively delete local events
        _globalEvent->barrierEvent[0] = NULL;
        delete _globalEvent;
    }
}


void
GlobalEvent::BarrierEvent::process()
{
    // wait for all queues to arrive at barrier, then process event
    if (globalBarrier()) {
        _globalEvent->process();
    }

    // second barrier to force all queues to wait for event processing
    // to finish before continuing
    globalBarrier();
}


void
GlobalSyncEvent::BarrierEvent::process()
{
    // wait for all queues to arrive at barrier, then process event
    if (globalBarrier()) {
        _globalEvent->process();
    }

    // second barrier to force all queues to wait for event processing
    // to finish before continuing
    globalBarrier();
    curEventQueue()->handleAsyncInsertions();
}

void
GlobalSyncEvent::process()
{
    if (repeat) {
        schedule(curTick() + repeat);
    }
}

const char *
GlobalSyncEvent::description() const
{
    return "GlobalSyncEvent";
}
