/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * 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 "sles_allinclusive.h"
#include <bionic_pthread.h>


// Use this macro to validate a pthread_t before passing it into __pthread_gettid.
// One of the common reasons for deadlock is trying to lock a mutex for an object
// which has been destroyed (which does memset to 0x00 or 0x55 as the final step).
// To avoid crashing with a SIGSEGV right before we're about to log a deadlock warning,
// we check that the pthread_t is probably valid.  Note that it is theoretically
// possible for something to look like a valid pthread_t but not actually be valid.
// So we might still crash, but only in the case where a deadlock was imminent anyway.
#define LIKELY_VALID(ptr) (((ptr) != (pthread_t) 0) && ((((size_t) (ptr)) & 3) == 0))


/** \brief Exclusively lock an object */

#ifdef USE_DEBUG
void object_lock_exclusive_(IObject *thiz, const char *file, int line)
{
    int ok;
    ok = pthread_mutex_trylock(&thiz->mMutex);
    if (0 != ok) {
        // not android_atomic_acquire_load because we don't care about relative load/load ordering
        int32_t oldGeneration = thiz->mGeneration;
        // wait up to a total of 250 ms
        static const unsigned backoffs[] = {10, 20, 30, 40, 50, 100};
        unsigned i = 0;
        for (;;) {
            // the Android version is in ms not timespec, and isn't named pthread_mutex_timedlock_np
            ok = pthread_mutex_lock_timeout_np(&thiz->mMutex, backoffs[i]);
            if (0 == ok) {
                break;
            }
            if (EBUSY == ok) {
                // this is the expected return value for timeout, and will be handled below
            } else if (EDEADLK == ok) {
                // we don't use the kind of mutex that can return this error, but just in case
                SL_LOGE("%s:%d: recursive lock detected", file, line);
            } else {
                // some other return value
                SL_LOGE("%s:%d: pthread_mutex_lock_timeout_np returned %d", file, line, ok);
            }
            // is anyone else making forward progress?
            int32_t newGeneration = thiz->mGeneration;
            if (newGeneration != oldGeneration) {
                // if we ever see forward progress then lock without timeout (more efficient)
                goto forward_progress;
            }
            // no, then continue trying to lock but with increasing timeouts
            if (++i >= (sizeof(backoffs) / sizeof(backoffs[0]))) {
                // the extra block avoids a C++ compiler error about goto past initialization
                {
                    pthread_t me = pthread_self();
                    pthread_t owner = thiz->mOwner;
                    // unlikely, but this could result in a memory fault if owner is corrupt
                    pid_t ownerTid = LIKELY_VALID(owner) ? __pthread_gettid(owner) : -1;
                    SL_LOGW("%s:%d: pthread %p (tid %d) sees object %p was locked by pthread %p"
                            " (tid %d) at %s:%d\n", file, line, *(void **)&me, gettid(), thiz,
                            *(void **)&owner, ownerTid, thiz->mFile, thiz->mLine);
                }
forward_progress:
                // attempt one more time without timeout; maybe this time we will be successful
                ok = pthread_mutex_lock(&thiz->mMutex);
                assert(0 == ok);
                break;
            }
        }
    }
    // here if mutex was successfully locked
    pthread_t zero;
    memset(&zero, 0, sizeof(pthread_t));
    if (0 != memcmp(&zero, &thiz->mOwner, sizeof(pthread_t))) {
        pthread_t me = pthread_self();
        pthread_t owner = thiz->mOwner;
        pid_t ownerTid = LIKELY_VALID(owner) ? __pthread_gettid(owner) : -1;
        if (pthread_equal(pthread_self(), owner)) {
            SL_LOGE("%s:%d: pthread %p (tid %d) sees object %p was recursively locked by pthread"
                    " %p (tid %d) at %s:%d\n", file, line, *(void **)&me, gettid(), thiz,
                    *(void **)&owner, ownerTid, thiz->mFile, thiz->mLine);
        } else {
            SL_LOGE("%s:%d: pthread %p (tid %d) sees object %p was left unlocked in unexpected"
                    " state by pthread %p (tid %d) at %s:%d\n", file, line, *(void **)&me, gettid(),
                    thiz, *(void **)&owner, ownerTid, thiz->mFile, thiz->mLine);
        }
        assert(false);
    }
    thiz->mOwner = pthread_self();
    thiz->mFile = file;
    thiz->mLine = line;
    // not android_atomic_inc because we are already holding a mutex
    ++thiz->mGeneration;
}
#else
void object_lock_exclusive(IObject *thiz)
{
    int ok;
    ok = pthread_mutex_lock(&thiz->mMutex);
    assert(0 == ok);
}
#endif


/** \brief Exclusively unlock an object and do not report any updates */

#ifdef USE_DEBUG
void object_unlock_exclusive_(IObject *thiz, const char *file, int line)
{
    assert(pthread_equal(pthread_self(), thiz->mOwner));
    assert(NULL != thiz->mFile);
    assert(0 != thiz->mLine);
    memset(&thiz->mOwner, 0, sizeof(pthread_t));
    thiz->mFile = file;
    thiz->mLine = line;
    int ok;
    ok = pthread_mutex_unlock(&thiz->mMutex);
    assert(0 == ok);
}
#else
void object_unlock_exclusive(IObject *thiz)
{
    int ok;
    ok = pthread_mutex_unlock(&thiz->mMutex);
    assert(0 == ok);
}
#endif


/** \brief Exclusively unlock an object and report updates to the specified bit-mask of
 *  attributes
 */

#ifdef USE_DEBUG
void object_unlock_exclusive_attributes_(IObject *thiz, unsigned attributes,
    const char *file, int line)
#else
void object_unlock_exclusive_attributes(IObject *thiz, unsigned attributes)
#endif
{

#ifdef USE_DEBUG
    assert(pthread_equal(pthread_self(), thiz->mOwner));
    assert(NULL != thiz->mFile);
    assert(0 != thiz->mLine);
#endif

    int ok;

    // make SL object IDs be contiguous with XA object IDs
    SLuint32 objectID = IObjectToObjectID(thiz);
    SLuint32 index = objectID;
    if ((XA_OBJECTID_ENGINE <= index) && (index <= XA_OBJECTID_CAMERADEVICE)) {
        ;
    } else if ((SL_OBJECTID_ENGINE <= index) && (index <= SL_OBJECTID_METADATAEXTRACTOR)) {
        index -= SL_OBJECTID_ENGINE - XA_OBJECTID_CAMERADEVICE - 1;
    } else {
        assert(false);
        index = 0;
    }

    // first synchronously handle updates to attributes here, while object is still locked.
    // This appears to be a loop, but actually typically runs through the loop only once.
    unsigned asynchronous = attributes;
    while (attributes) {
        // this sequence is carefully crafted to be O(1); tread carefully when making changes
        unsigned bit = ctz(attributes);
        // ATTR_INDEX_MAX == next bit position after the last attribute
        assert(ATTR_INDEX_MAX > bit);
        // compute the entry in the handler table using object ID and bit number
        AttributeHandler handler = handlerTable[index][bit];
        if (NULL != handler) {
            asynchronous &= ~(*handler)(thiz);
        }
        attributes &= ~(1 << bit);
    }

    // any remaining attributes are handled asynchronously in the sync thread
    if (asynchronous) {
        unsigned oldAttributesMask = thiz->mAttributesMask;
        thiz->mAttributesMask = oldAttributesMask | asynchronous;
        if (oldAttributesMask) {
            asynchronous = ATTR_NONE;
        }
    }

#ifdef ANDROID
    // FIXME hack to safely handle a post-unlock PrefetchStatus callback and/or AudioTrack::start()
    slPrefetchCallback prefetchCallback = NULL;
    void *prefetchContext = NULL;
    SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE;
    android::sp<android::AudioTrack> audioTrack;
    if (SL_OBJECTID_AUDIOPLAYER == objectID) {
        CAudioPlayer *ap = (CAudioPlayer *) thiz;
        prefetchCallback = ap->mPrefetchStatus.mDeferredPrefetchCallback;
        prefetchContext  = ap->mPrefetchStatus.mDeferredPrefetchContext;
        prefetchEvents   = ap->mPrefetchStatus.mDeferredPrefetchEvents;
        ap->mPrefetchStatus.mDeferredPrefetchCallback = NULL;
        // clearing these next two fields is not required, but avoids stale data during debugging
        ap->mPrefetchStatus.mDeferredPrefetchContext  = NULL;
        ap->mPrefetchStatus.mDeferredPrefetchEvents   = SL_PREFETCHEVENT_NONE;
        if (ap->mDeferredStart) {
            audioTrack = ap->mAudioTrack;
            ap->mDeferredStart = false;
        }
    }
#endif

#ifdef USE_DEBUG
    memset(&thiz->mOwner, 0, sizeof(pthread_t));
    thiz->mFile = file;
    thiz->mLine = line;
#endif
    ok = pthread_mutex_unlock(&thiz->mMutex);
    assert(0 == ok);

#ifdef ANDROID
    // FIXME call the prefetch status callback while not holding the mutex on AudioPlayer
    if (NULL != prefetchCallback) {
        // note these are synchronous by the application's thread as it is about to return from API
        assert(prefetchEvents != SL_PREFETCHEVENT_NONE);
        CAudioPlayer *ap = (CAudioPlayer *) thiz;
        // spec requires separate callbacks for each event
        if (SL_PREFETCHEVENT_STATUSCHANGE & prefetchEvents) {
            (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
                    SL_PREFETCHEVENT_STATUSCHANGE);
        }
        if (SL_PREFETCHEVENT_FILLLEVELCHANGE & prefetchEvents) {
            (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext,
                    SL_PREFETCHEVENT_FILLLEVELCHANGE);
        }
    }

    // call AudioTrack::start() while not holding the mutex on AudioPlayer
    if (audioTrack != 0) {
        audioTrack->start();
        audioTrack.clear();
    }
#endif

    // first update to this interface since previous sync
    if (ATTR_NONE != asynchronous) {
        unsigned id = thiz->mInstanceID;
        if (0 != id) {
            --id;
            assert(MAX_INSTANCE > id);
            IEngine *thisEngine = &thiz->mEngine->mEngine;
            // FIXME atomic or here
            interface_lock_exclusive(thisEngine);
            thisEngine->mChangedMask |= 1 << id;
            interface_unlock_exclusive(thisEngine);
        }
    }

}


/** \brief Wait on the condition variable associated with the object; see pthread_cond_wait */

#ifdef USE_DEBUG
void object_cond_wait_(IObject *thiz, const char *file, int line)
{
    // note that this will unlock the mutex, so we have to clear the owner
    assert(pthread_equal(pthread_self(), thiz->mOwner));
    assert(NULL != thiz->mFile);
    assert(0 != thiz->mLine);
    memset(&thiz->mOwner, 0, sizeof(pthread_t));
    thiz->mFile = file;
    thiz->mLine = line;
    // alas we don't know the new owner's identity
    int ok;
    ok = pthread_cond_wait(&thiz->mCond, &thiz->mMutex);
    assert(0 == ok);
    // restore my ownership
    thiz->mOwner = pthread_self();
    thiz->mFile = file;
    thiz->mLine = line;
}
#else
void object_cond_wait(IObject *thiz)
{
    int ok;
    ok = pthread_cond_wait(&thiz->mCond, &thiz->mMutex);
    assert(0 == ok);
}
#endif


/** \brief Signal the condition variable associated with the object; see pthread_cond_signal */

void object_cond_signal(IObject *thiz)
{
    int ok;
    ok = pthread_cond_signal(&thiz->mCond);
    assert(0 == ok);
}


/** \brief Broadcast the condition variable associated with the object;
 *  see pthread_cond_broadcast
 */

void object_cond_broadcast(IObject *thiz)
{
    int ok;
    ok = pthread_cond_broadcast(&thiz->mCond);
    assert(0 == ok);
}
