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