OSDN Git Service

Modified MutexLock to use a pthread mutex on Android.
authorJorge E. Moreira <jemoreira@google.com>
Sat, 3 Dec 2016 01:03:54 +0000 (17:03 -0800)
committerNicolas Capens <capn@google.com>
Fri, 3 Feb 2017 20:37:17 +0000 (20:37 +0000)
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>
src/Common/MutexLock.hpp
src/Common/Resource.hpp
src/Main/SwiftConfig.hpp
src/OpenGL/libEGL/Display.cpp
src/OpenGL/libEGL/Display.h
src/Reactor/LLVMReactor.cpp
src/Renderer/Blitter.hpp
src/Renderer/Renderer.hpp

index 16835ed..044c156 100644 (file)
 
 #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
index 6d2577e..379b769 100644 (file)
@@ -45,7 +45,7 @@ namespace sw
        private:
                ~Resource();   // Always call destruct() instead
 
-               BackoffLock criticalSection;
+               MutexLock criticalSection;
                Event unblock;
                volatile int blocked;
 
index f8fd87e..233b438 100644 (file)
@@ -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;
 
index 31be0e9..b9ee799 100644 (file)
 #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();
 }
 
index 96e1453..93ab2cb 100644 (file)
@@ -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;
index d3da778..0d56858 100644 (file)
@@ -68,7 +68,7 @@ namespace
        llvm::Module *module = nullptr;
        llvm::Function *function = nullptr;
 
-       sw::BackoffLock codegenMutex;
+       sw::MutexLock codegenMutex;
 }
 
 namespace sw
index 366d5c3..02c0535 100644 (file)
@@ -93,7 +93,7 @@ namespace sw
                Routine *generate(BlitState &state);
 
                RoutineCache<BlitState> *blitCache;
-               BackoffLock criticalSection;
+               MutexLock criticalSection;
        };
 
        extern Blitter blitter;
index e4a83e1..49d0249 100644 (file)
@@ -465,7 +465,7 @@ namespace sw
                unsigned int qHead;
                unsigned int qSize;
 
-               BackoffLock schedulerMutex;
+               MutexLock schedulerMutex;
 
                #if PERF_HUD
                        int64_t vertexTime[16];