/*
 * 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::AudioTrackProxy> 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);
}
