/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */


#include "oscl_scheduler_readyq.h"


#include "oscl_scheduler_ao.h"
#include "oscl_scheduler.h"
#include "oscl_tickcount.h"
#include "oscl_scheduler_tuneables.h"

////////////////////////////////////////
// Ready Queue & Timer Queue Support
////////////////////////////////////////

//scheduler has an allocator but there's no way to use
//it here since this allocator must be a template argument
//to oscl priority queue.
OsclAny* OsclReadyAlloc::allocate_fl(const uint32 size, const char * file_name, const int line_num)
{
    OsclAny*p = iBasicAlloc.allocate_fl(size, file_name, line_num);
    OsclError::LeaveIfNull(p);
    return p;
}
OsclAny* OsclReadyAlloc::allocate(const uint32 size)
{
    OsclAny*p = iBasicAlloc.ALLOCATE(size);
    OsclError::LeaveIfNull(p);
    return p;
}
void OsclReadyAlloc::deallocate(OsclAny* p)
{
    iBasicAlloc.deallocate(p);
}

//evalute "priority of a is less than priority of b"
int OsclTimerCompare::compare(TOsclReady& a, TOsclReady& b)
{
    //Sort by time to run.  Earlier "time to run" has precedence.
    if (a->iPVReadyQLink.iTimeToRunTicks != b->iPVReadyQLink.iTimeToRunTicks)
    {
        //calculate a>b, taking possible rollover into account.
        uint32 delta = b->iPVReadyQLink.iTimeToRunTicks - a->iPVReadyQLink.iTimeToRunTicks;
        return (delta > OsclExecScheduler::iTimeCompareThreshold);
    }

    //Now sort by priority
    return OsclReadyCompare::compare(a, b);
}

//evalute "priority of a is less than priority of b"
int OsclReadyCompare::compare(TOsclReady& a, TOsclReady& b)
{
    //Sort by AO priority.  Higher priority has precedence.
    if (a->iPVReadyQLink.iAOPriority != b->iPVReadyQLink.iAOPriority)
        return (a->iPVReadyQLink.iAOPriority < b->iPVReadyQLink.iAOPriority);

    //if there was a priority tie, impose a FIFO order.

    //This section allows switching between "fair scheduling" and linear
    //behavior.  We always use fair scheduling, but for testing it can be helpful to
    //swap in the linear behavior.
#if PV_SCHED_FAIR_SCHEDULING
    //Sort by FIFO order, to create fair scheduling.
    //AOs that have been queued the longest have precedence.
    return (a->iPVReadyQLink.iSeqNum >= b->iPVReadyQLink.iSeqNum);
#else
    //Sort by the order when AO was added to scheduler, to simulate
    //Symbian native ActiveScheduler behavior.
    //AOs that were added earlier have precedence.
    return (a->iAddedNum > b->iAddedNum);
#endif

}

////////////////////////////////////////
//OsclReadyQ
////////////////////////////////////////
void OsclReadyQ::Construct(int nreserve)
{
    iSeqNumCounter = 0;
    if (nreserve > 0)
        c.reserve(nreserve);
    iCallback = NULL;
}

void OsclReadyQ::ThreadLogon()
{
    iSem.Create();
    iCrit.Create();
}

void OsclReadyQ::ThreadLogoff()
{
    iSem.Close();
    iCrit.Close();
}

//
//Note: all semaphore errors are fatal, since they can cause
// scheduler to spin or hang.
//

PVActiveBase* OsclReadyQ::WaitAndPopTop()
//block until an AO is ready and pop the highest pri AO.
{
    switch (iSem.Wait())
    {
        case OsclProcStatus::SUCCESS_ERROR:
            return PopTopAfterWait();

        default:
            OsclError::Leave(OsclErrSystemCallFailed);
            return NULL;
    }
}

PVActiveBase* OsclReadyQ::WaitAndPopTop(uint32 aTimeoutVal)
//block until an AO is ready or timeout is reached.
{
    switch (iSem.Wait(aTimeoutVal))
    {
        case OsclProcStatus::WAIT_TIMEOUT_ERROR:
            //timeout reached, no AO ready.
            return NULL;

        case OsclProcStatus::SUCCESS_ERROR:
            //an AO is ready-- pop it.
            return PopTopAfterWait();

        default:
            //no timeout and no AO.
            OsclError::Leave(OsclErrSystemCallFailed);
            return NULL;
    }
}

bool OsclReadyQ::IsIn(TOsclReady b)
//tell if elemement is in this q
{
    iCrit.Lock();
    bool isin = (b->iPVReadyQLink.iIsIn == this);
    iCrit.Unlock();
    return isin;
}

PVActiveBase* OsclReadyQ::PopTop()
//deque and return highest pri element.
{
    iCrit.Lock();

    PVActiveBase*elem = (size() > 0) ? top() : NULL;
    if (elem)
    {
        elem->iPVReadyQLink.iIsIn = NULL;

        pop();

        //this call won't block-- it will just decrement the sem.
        if (iSem.Wait() != OsclProcStatus::SUCCESS_ERROR)
            OsclError::Leave(OsclErrSystemCallFailed);
    }

    iCrit.Unlock();
    return elem;
}

PVActiveBase* OsclReadyQ::PopTopAfterWait()
//deque and return highest pri element.  used when we have
//already done a sem wait prior to this call, so there is no sem
//decrement here.
{
    iCrit.Lock();

    PVActiveBase*elem = (size() > 0) ? top() : NULL;

    if (elem)
    {
        elem->iPVReadyQLink.iIsIn = NULL;
        pop();
    }
    else
    {//there should always be an element available after a sem wait.
        OSCL_ASSERT(0);
    }

    iCrit.Unlock();

    return elem;
}

PVActiveBase* OsclReadyQ::Top()
//return highest pri element without removing.
{
    iCrit.Lock();
    PVActiveBase* elem = (size() > 0) ? top() : NULL;
    iCrit.Unlock();
    return elem;
}

void OsclReadyQ::Remove(TOsclReady a)
//remove the given element
{
    iCrit.Lock();

    a->iPVReadyQLink.iIsIn = NULL;

    int32 nfound = remove(a);

    if (nfound > 0)
    {
        //this call won't block-- it will just decrement the sem.
        if (iSem.Wait() != OsclProcStatus::SUCCESS_ERROR)
            OsclError::Leave(OsclErrSystemCallFailed);
    }

    iCrit.Unlock();
}

int32 OsclReadyQ::PendComplete(PVActiveBase *pvbase, int32 aReason)
//Complete an AO request
{
    iCrit.Lock();

    //make sure this AO is not already queued.
    int32 err;
    if (pvbase->IsInAnyQ())
    {
        err = OsclErrInvalidState;//EExecAlreadyAdded
    }
    //make sure the AO has a request active
    else if (!pvbase->iBusy
             || pvbase->iStatus != OSCL_REQUEST_PENDING)
    {
        err = OsclErrCorrupt;//EExecStrayEvent;
    }
    else
    {
        //Add to pri queue
        pvbase->iPVReadyQLink.iIsIn = this;
        pvbase->iPVReadyQLink.iTimeQueuedTicks = OsclTickCount::TickCount();
        pvbase->iPVReadyQLink.iSeqNum = ++iSeqNumCounter;//for the FIFO sort
        push(pvbase);

        //increment the sem
        if (iSem.Signal() != OsclProcStatus::SUCCESS_ERROR)
        {
            err = OsclErrSystemCallFailed;
        }
        else
        {
            //update the AO status
            pvbase->iStatus = aReason;

            //make scheduler callback if needed.
            //note: this needs to happen under the lock since we're updating
            //the callback pointer.
            if (iCallback)
            {
                iCallback->OsclSchedulerReadyCallback(iCallbackContext);
                iCallback = NULL;
            }
            err = OsclErrNone;
        }
    }

    iCrit.Unlock();
    return err;
}

int32 OsclReadyQ::WaitForRequestComplete(PVActiveBase* pvbase)
//Wait on a particular request to complete
{
    int32 nwait = 0;//count the number of request sem waits.

    for (bool complete = false; !complete;)
    {
        //Wait on any request to complete.
        if (iSem.Wait() != OsclProcStatus::SUCCESS_ERROR)
            return OsclErrSystemCallFailed;

        nwait++;

        //Some request was complete but it might not be the one of interest,
        //so check for completion again.
        complete = IsIn(pvbase);
    }

    //Restore the request semaphore value since we may have decremented it without
    //removing anything from the ReadyQ.
    while (nwait > 0)
    {
        if (iSem.Signal() != OsclProcStatus::SUCCESS_ERROR)
            return OsclErrSystemCallFailed;

        nwait--;
    }

    return OsclErrNone;
}

void OsclReadyQ::RegisterForCallback(OsclSchedulerObserver* aCallback, OsclAny* aCallbackContext)
{
    //Use the Q lock to avoid thread contention over
    //callback pointer.
    iCrit.Lock();

    //Callback right away if ready Q is non-empty.
    if (size() && aCallback)
    {
        iCallback = NULL;
        aCallback->OsclSchedulerReadyCallback(aCallbackContext);
    }
    else
    {
        //save the new pointers.  Callback will happen when timer Q or ready Q is
        //updated.
        iCallback = aCallback;
        iCallbackContext = aCallbackContext;
    }
    iCrit.Unlock();
}

void OsclReadyQ::TimerCallback(uint32 aDelayMicrosec)
//Inform scheduler observer of a change in the shortest timer interval
{
    //lock when updating callback pointer.
    iCrit.Lock();
    OsclSchedulerObserver* callback = iCallback;
    iCallback = NULL;
    iCrit.Unlock();

    //Timer callback happens outside the lock, to allow code
    //to register for additional callback.
    if (callback)
        callback->OsclSchedulerTimerCallback(iCallbackContext, aDelayMicrosec / 1000);
}

////////////////////////////////////////
//OsclTimerQ
////////////////////////////////////////
void OsclTimerQ::Construct(int nreserve)
{
    iSeqNumCounter = 0;
    if (nreserve > 0)
        c.reserve(nreserve);
}

bool OsclTimerQ::IsIn(TOsclReady b)
//tell if element is in this q
{
    return (b->iPVReadyQLink.iIsIn == this);
}

PVActiveBase* OsclTimerQ::PopTop()
//deque and return highest pri element.
{
    PVActiveBase*elem = (size() > 0) ? top() : NULL;
    if (elem)
        Pop(elem);

    return elem;
}

PVActiveBase* OsclTimerQ::Top()
//return highest pri element without removing.
{
    return (size() > 0) ? top() : NULL;
}

void OsclTimerQ::Pop(TOsclReady b)
//remove queue top.
{
    b->iPVReadyQLink.iIsIn = NULL;
    pop();
}

void OsclTimerQ::Remove(TOsclReady a)
{
    a->iPVReadyQLink.iIsIn = NULL;
    remove(a);
}

void OsclTimerQ::Add(TOsclReady b)
{
    b->iPVReadyQLink.iIsIn = this;
    b->iPVReadyQLink.iTimeQueuedTicks = OsclTickCount::TickCount();
    b->iPVReadyQLink.iSeqNum = ++iSeqNumCounter;//for the FIFO sort

    push(b);
}








