Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f7fc27d authored by Jason Sams's avatar Jason Sams
Browse files

Replace spins with proper pthread conditions.

parent f8cd5d99
Loading
Loading
Loading
Loading
+3 −7
Original line number Diff line number Diff line
@@ -130,14 +130,10 @@ void * Context::threadProc(void *vrsc)
     rsc->mRunning = true;
     bool mDraw = true;
     while (!rsc->mExit) {
         mDraw |= gIO->playCoreCommands(rsc);
         mDraw |= gIO->playCoreCommands(rsc, !mDraw);
         mDraw &= (rsc->mRootScript.get() != NULL);

         if (!mDraw || !rsc->mRootScript.get()) {
             usleep(10000);
             continue;
         }

         if (rsc->mRootScript.get()) {
         if (mDraw) {
             mDraw = rsc->runRootScript();
             eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
         }
+85 −12
Original line number Diff line number Diff line
@@ -37,16 +37,8 @@ bool LocklessCommandFifo::init(uint32_t sizeInBytes)
        return false;
    }

    int status = pthread_mutex_init(&mMutex, NULL);
    if (status) {
        LOGE("LocklessFifo mutex init failure");
        free(mBuffer);
        return false;
    }
    status = pthread_cond_init(&mCondition, NULL);
    if (status) {
        LOGE("LocklessFifo condition init failure");
        pthread_mutex_destroy(&mMutex);
    if (!mSignalToControl.init() || !mSignalToWorker.init()) {
        LOGE("Signal setup failed");
        free(mBuffer);
        return false;
    }
@@ -106,6 +98,7 @@ void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes)
    mPut += ((sizeInBytes + 3) & ~3) + 4;
    //dumpState("commit 2");

    mSignalToWorker.set();
}

void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes)
@@ -118,7 +111,7 @@ void LocklessCommandFifo::flush()
{
    //dumpState("flush 1");
    while(mPut != mGet) {
        usleep(1);
        mSignalToControl.wait();
    }
    //dumpState("flush 2");
}
@@ -126,8 +119,10 @@ void LocklessCommandFifo::flush()
const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData)
{
    while(1) {
        //dumpState("get");
        while(isEmpty()) {
            usleep(10);
            mSignalToControl.set();
            mSignalToWorker.wait();
        }
        //dumpState("get 3");

@@ -149,6 +144,9 @@ void LocklessCommandFifo::next()
{
    uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];
    mGet += ((bytes + 3) & ~3) + 4;
    if (isEmpty()) {
        mSignalToControl.set();
    }
    //dumpState("next");
}

@@ -179,4 +177,79 @@ void LocklessCommandFifo::dumpState(const char *s) const
    LOGE("%s  put %p, get %p,  buf %p,  end %p", s, mPut, mGet, mBuffer, mEnd);
}

LocklessCommandFifo::Signal::Signal()
{
    mSet = true;
}

LocklessCommandFifo::Signal::~Signal()
{
    pthread_mutex_destroy(&mMutex);
    pthread_cond_destroy(&mCondition);
}

bool LocklessCommandFifo::Signal::init()
{
    int status = pthread_mutex_init(&mMutex, NULL);
    if (status) {
        LOGE("LocklessFifo mutex init failure");
        return false;
    }

    status = pthread_cond_init(&mCondition, NULL);
    if (status) {
        LOGE("LocklessFifo condition init failure");
        pthread_mutex_destroy(&mMutex);
        return false;
    }

    return true;
}

void LocklessCommandFifo::Signal::set()
{
    int status;

    status = pthread_mutex_lock(&mMutex);
    if (status) {
        LOGE("LocklessCommandFifo: error %i locking for set condition.", status);
        return;
    }

    mSet = true;

    status = pthread_cond_signal(&mCondition);
    if (status) {
        LOGE("LocklessCommandFifo: error %i on set condition.", status);
    }

    status = pthread_mutex_unlock(&mMutex);
    if (status) {
        LOGE("LocklessCommandFifo: error %i unlocking for set condition.", status);
    }
}

void LocklessCommandFifo::Signal::wait()
{
    int status;

    status = pthread_mutex_lock(&mMutex);
    if (status) {
        LOGE("LocklessCommandFifo: error %i locking for condition.", status);
        return;
    }

    if (!mSet) {
        status = pthread_cond_wait(&mCondition, &mMutex);
        if (status) {
            LOGE("LocklessCommandFifo: error %i waiting on condition.", status);
        }
    }
    mSet = false;

    status = pthread_mutex_unlock(&mMutex);
    if (status) {
        LOGE("LocklessCommandFifo: error %i unlocking for condition.", status);
    }
}
+20 −2
Original line number Diff line number Diff line
@@ -41,14 +41,32 @@ public:


protected:
    class Signal {
    public:
        Signal();
        ~Signal();

        bool init();

        void set();
        void wait();

    protected:
        bool mSet;
        pthread_mutex_t mMutex;
        pthread_cond_t mCondition;
    };

    uint8_t * volatile mPut;
    uint8_t * volatile mGet;
    uint8_t * mBuffer;
    uint8_t * mEnd;
    uint8_t mSize;

    pthread_mutex_t mMutex;
    pthread_cond_t mCondition;
    Signal mSignalToWorker;
    Signal mSignalToControl;



public:
    void * reserve(uint32_t bytes);
+3 −2
Original line number Diff line number Diff line
@@ -34,16 +34,17 @@ ThreadIO::~ThreadIO()
{
}

bool ThreadIO::playCoreCommands(Context *con)
bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand)
{
    //LOGE("playCoreCommands 1");
    uint32_t cmdID = 0;
    uint32_t cmdSize = 0;
    bool ret = false;
    while(!mToCore.isEmpty()) {
    while(!mToCore.isEmpty() || waitForCommand) {
        ret = true;
        //LOGE("playCoreCommands 2");
        const void * data = mToCore.get(&cmdID, &cmdSize);
        waitForCommand = false;
        //LOGE("playCoreCommands 3 %i %i", cmdID, cmdSize);

        gPlaybackFuncs[cmdID](con, data);
+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ public:

    // Plays back commands from the client.
    // Returns true if any commands were processed.
    bool playCoreCommands(Context *con);
    bool playCoreCommands(Context *con, bool waitForCommand);


    LocklessCommandFifo mToCore;