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/8648
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/Common/MutexLock.hpp b/src/Common/MutexLock.hpp
index 16835ed..044c156 100644
--- a/src/Common/MutexLock.hpp
+++ b/src/Common/MutexLock.hpp
@@ -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 @@
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
diff --git a/src/Common/Resource.hpp b/src/Common/Resource.hpp
index 6d2577e..379b769 100644
--- a/src/Common/Resource.hpp
+++ b/src/Common/Resource.hpp
@@ -45,7 +45,7 @@
private:
~Resource(); // Always call destruct() instead
- BackoffLock criticalSection;
+ MutexLock criticalSection;
Event unblock;
volatile int blocked;
diff --git a/src/Main/SwiftConfig.hpp b/src/Main/SwiftConfig.hpp
index f8fd87e..233b438 100644
--- a/src/Main/SwiftConfig.hpp
+++ b/src/Main/SwiftConfig.hpp
@@ -101,7 +101,7 @@
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;
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index 31be0e9..b9ee799 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -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 @@
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::destroySync(FenceSync *sync)
{
{
- Guard lk(&mSyncSetMutex);
+ LockGuard lock(mSyncSetMutex);
mSyncSet.erase(sync);
}
delete sync;
@@ -583,7 +567,7 @@
bool Display::isValidSync(FenceSync *sync)
{
- Guard lk(&mSyncSetMutex);
+ LockGuard lock(mSyncSetMutex);
return mSyncSet.find(sync) != mSyncSet.end();
}
diff --git a/src/OpenGL/libEGL/Display.h b/src/OpenGL/libEGL/Display.h
index 96e1453..93ab2cb 100644
--- a/src/OpenGL/libEGL/Display.h
+++ b/src/OpenGL/libEGL/Display.h
@@ -92,7 +92,7 @@
ContextSet mContextSet;
typedef std::set<FenceSync*> SyncSet;
- sw::BackoffLock mSyncSetMutex;
+ sw::MutexLock mSyncSetMutex;
SyncSet mSyncSet;
gl::NameSpace<Image> mSharedImageNameSpace;
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index d3da778..0d56858 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -68,7 +68,7 @@
llvm::Module *module = nullptr;
llvm::Function *function = nullptr;
- sw::BackoffLock codegenMutex;
+ sw::MutexLock codegenMutex;
}
namespace sw
diff --git a/src/Renderer/Blitter.hpp b/src/Renderer/Blitter.hpp
index 366d5c3..02c0535 100644
--- a/src/Renderer/Blitter.hpp
+++ b/src/Renderer/Blitter.hpp
@@ -93,7 +93,7 @@
Routine *generate(BlitState &state);
RoutineCache<BlitState> *blitCache;
- BackoffLock criticalSection;
+ MutexLock criticalSection;
};
extern Blitter blitter;
diff --git a/src/Renderer/Renderer.hpp b/src/Renderer/Renderer.hpp
index e4a83e1..49d0249 100644
--- a/src/Renderer/Renderer.hpp
+++ b/src/Renderer/Renderer.hpp
@@ -465,7 +465,7 @@
unsigned int qHead;
unsigned int qSize;
- BackoffLock schedulerMutex;
+ MutexLock schedulerMutex;
#if PERF_HUD
int64_t vertexTime[16];