Commit f8faed6d by Jorge E. Moreira Committed by Nicolas Capens

Modified MutexLock to use a pthread mutex on Android.

The BackoffLock spins idle for a while when waiting for a locked mutex before yielding the core, thus wasting many CPU cycles. Modern pthread implementations have low overhead mutexes which make the thread sleep if the lock is already held, and efficiently resume them it becomes available. Change-Id: I26b64c86db620739671373fd0d82085744d34fa8 Reviewed-on: https://swiftshader-review.googlesource.com/8648Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent f8beb4be
......@@ -17,6 +17,48 @@
#include "Thread.hpp"
#ifdef __ANDROID__
// Use an actual mutex on Android. Since many processes may use SwiftShader
// at the same time it's best to just have the scheduler overhead.
#include <pthread.h>
namespace sw
{
class MutexLock
{
public:
MutexLock()
{
pthread_mutex_init(&mutex, NULL);
}
~MutexLock()
{
pthread_mutex_destroy(&mutex);
}
bool attemptLock()
{
return pthread_mutex_trylock(&mutex) == 0;
}
void lock()
{
pthread_mutex_lock(&mutex);
}
void unlock()
{
pthread_mutex_unlock(&mutex);
}
private:
pthread_mutex_t mutex;
};
}
#else // !__ANDROID__
namespace sw
{
class BackoffLock
......@@ -124,6 +166,27 @@ namespace sw
volatile int padding2[15];
};
};
using MutexLock = BackoffLock;
}
#endif // !__ANDROID__
class LockGuard
{
public:
explicit LockGuard(sw::MutexLock &mutex) : mutex(mutex)
{
mutex.lock();
}
~LockGuard()
{
mutex.unlock();
}
protected:
sw::MutexLock &mutex;
};
#endif // sw_MutexLock_hpp
......@@ -45,7 +45,7 @@ namespace sw
private:
~Resource(); // Always call destruct() instead
BackoffLock criticalSection;
MutexLock criticalSection;
Event unblock;
volatile int blocked;
......
......@@ -101,7 +101,7 @@ namespace sw
Thread *serverThread;
volatile bool terminate;
BackoffLock criticalSection; // Protects reading and writing the configuration settings
MutexLock criticalSection; // Protects reading and writing the configuration settings
bool newConfig;
......
......@@ -40,22 +40,6 @@
#include <vector>
#include <map>
class Guard
{
public:
explicit Guard(sw::BackoffLock* in) : mMutex(in)
{
mMutex->lock();
}
~Guard()
{
mMutex->unlock();
}
protected:
sw::BackoffLock* mMutex;
};
namespace egl
{
......@@ -469,7 +453,7 @@ EGLContext Display::createContext(EGLConfig configHandle, const egl::Context *sh
EGLSyncKHR Display::createSync(Context *context)
{
FenceSync *fenceSync = new egl::FenceSync(context);
Guard lk(&mSyncSetMutex);
LockGuard lock(mSyncSetMutex);
mSyncSet.insert(fenceSync);
return fenceSync;
}
......@@ -506,7 +490,7 @@ void Display::destroyContext(egl::Context *context)
void Display::destroySync(FenceSync *sync)
{
{
Guard lk(&mSyncSetMutex);
LockGuard lock(mSyncSetMutex);
mSyncSet.erase(sync);
}
delete sync;
......@@ -583,7 +567,7 @@ bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
bool Display::isValidSync(FenceSync *sync)
{
Guard lk(&mSyncSetMutex);
LockGuard lock(mSyncSetMutex);
return mSyncSet.find(sync) != mSyncSet.end();
}
......
......@@ -92,7 +92,7 @@ namespace egl
ContextSet mContextSet;
typedef std::set<FenceSync*> SyncSet;
sw::BackoffLock mSyncSetMutex;
sw::MutexLock mSyncSetMutex;
SyncSet mSyncSet;
gl::NameSpace<Image> mSharedImageNameSpace;
......
......@@ -68,7 +68,7 @@ namespace
llvm::Module *module = nullptr;
llvm::Function *function = nullptr;
sw::BackoffLock codegenMutex;
sw::MutexLock codegenMutex;
}
namespace sw
......
......@@ -93,7 +93,7 @@ namespace sw
Routine *generate(BlitState &state);
RoutineCache<BlitState> *blitCache;
BackoffLock criticalSection;
MutexLock criticalSection;
};
extern Blitter blitter;
......
......@@ -465,7 +465,7 @@ namespace sw
unsigned int qHead;
unsigned int qSize;
BackoffLock schedulerMutex;
MutexLock schedulerMutex;
#if PERF_HUD
int64_t vertexTime[16];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment