Fix potential data race in mutex lock implementation.

Writing or reading an ordinary volatile boolean does not provide memory
ordering guarantees. Use atomic<bool> with release and acquire semantics
instead. On x86 this should have no impact on the generated code, since
it architecturally offers strong memory ordering guarantees.

Bug chromium:710753

Change-Id: I5aa2a6eeecfcd691a0aa8d06fd067f9d59ab13c3
Reviewed-on: https://swiftshader-review.googlesource.com/9328
Reviewed-by: Corentin Wallez <cwallez@google.com>
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 044c156..d9f4034 100644
--- a/src/Common/MutexLock.hpp
+++ b/src/Common/MutexLock.hpp
@@ -59,6 +59,8 @@
 
 #else   // !__ANDROID__
 
+#include <atomic>
+
 namespace sw
 {
 	class BackoffLock
@@ -73,7 +75,7 @@
 		{
 			if(!isLocked())
 			{
-				if(atomicExchange(&mutex, 1) == 0)
+				if(mutex.exchange(true) == false)
 				{
 					return true;
 				}
@@ -148,12 +150,12 @@
 
 		void unlock()
 		{
-			mutex = 0;
+			mutex.store(false, std::memory_order_release);
 		}
 
 		bool isLocked()
 		{
-			return mutex != 0;
+			return mutex.load(std::memory_order_acquire);
 		}
 
 	private:
@@ -162,7 +164,7 @@
 			// Ensure that the mutex variable is on its own 64-byte cache line to avoid false sharing
 			// Padding must be public to avoid compiler warnings
 			volatile int padding1[16];
-			volatile int mutex;
+			std::atomic<bool> mutex;
 			volatile int padding2[15];
 		};
 	};