Move Chan out of VkQueue.hpp and into System/Synchronization.hpp

This is a pure move with no changes.

The goal here is to centralize the concurrent synchronization primitives, and not have them scattered around the codebase.

Bug: b/133127573
Change-Id: I6abdfc34bf13ce455983610ff0c686778e0e9e4c
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31677
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Ben Clayton <headlessclayton@gmail.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b270abe..1e43eca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1603,6 +1603,7 @@
     ${SOURCE_DIR}/System/Resource.hpp
     ${SOURCE_DIR}/System/Socket.cpp
     ${SOURCE_DIR}/System/Socket.hpp
+    ${SOURCE_DIR}/System/Synchronization.hpp
     ${SOURCE_DIR}/System/Thread.cpp
     ${SOURCE_DIR}/System/Thread.hpp
     ${SOURCE_DIR}/System/Timer.cpp
diff --git a/build/Visual Studio 15 2017 Win64/libvk_swiftshader.vcxproj b/build/Visual Studio 15 2017 Win64/libvk_swiftshader.vcxproj
index 58c0ddc..189af17 100644
--- a/build/Visual Studio 15 2017 Win64/libvk_swiftshader.vcxproj
+++ b/build/Visual Studio 15 2017 Win64/libvk_swiftshader.vcxproj
@@ -263,6 +263,7 @@
     <ClInclude Include="$(SolutionDir)src\System\Resource.hpp" />

     <ClCompile Include="$(SolutionDir)src\System\Socket.cpp" />

     <ClInclude Include="$(SolutionDir)src\System\Socket.hpp" />

+    <ClInclude Include="$(SolutionDir)src\System\Synchronization.hpp" />

     <ClCompile Include="$(SolutionDir)src\System\Thread.cpp" />

     <ClInclude Include="$(SolutionDir)src\System\Thread.hpp" />

     <ClCompile Include="$(SolutionDir)src\System\Timer.cpp" />

diff --git a/build/Visual Studio 15 2017 Win64/libvk_swiftshader.vcxproj.filters b/build/Visual Studio 15 2017 Win64/libvk_swiftshader.vcxproj.filters
index f2db70a..0550e3d 100644
--- a/build/Visual Studio 15 2017 Win64/libvk_swiftshader.vcxproj.filters
+++ b/build/Visual Studio 15 2017 Win64/libvk_swiftshader.vcxproj.filters
@@ -342,6 +342,9 @@
     <ClInclude Include="$(SolutionDir)src\System\Socket.hpp">

       <Filter>src\System</Filter>

     </ClInclude>

+    <ClInclude Include="$(SolutionDir)src\System\Synchronization.hpp">

+      <Filter>src\System</Filter>

+    </ClInclude>

     <ClInclude Include="$(SolutionDir)src\System\Thread.hpp">

       <Filter>src\System</Filter>

     </ClInclude>

diff --git a/src/System/Synchronization.hpp b/src/System/Synchronization.hpp
new file mode 100644
index 0000000..797af8e
--- /dev/null
+++ b/src/System/Synchronization.hpp
@@ -0,0 +1,112 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Synchronization_hpp
+#define sw_Synchronization_hpp
+
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+
+namespace sw
+{
+
+// Chan is a thread-safe FIFO queue of type T.
+// Chan takes its name after Golang's chan.
+template <typename T>
+class Chan
+{
+public:
+	Chan();
+
+	// take returns the next item in the chan, blocking until an item is
+	// available.
+	T take();
+
+	// tryTake returns a <T, bool> pair.
+	// If the chan is not empty, then the next item and true are returned.
+	// If the chan is empty, then a default-initialized T and false are returned.
+	std::pair<T, bool> tryTake();
+
+	// put places an item into the chan, blocking if the chan is bounded and
+	// full.
+	void put(const T &v);
+
+	// Returns the number of items in the chan.
+	// Note: that this may change as soon as the function returns, so should
+	// only be used for debugging.
+	size_t count();
+
+private:
+	std::queue<T> queue;
+	std::mutex mutex;
+	std::condition_variable added;
+	std::condition_variable removed;
+};
+
+template <typename T>
+Chan<T>::Chan() {}
+
+template <typename T>
+T Chan<T>::take()
+{
+	std::unique_lock<std::mutex> lock(mutex);
+	if (queue.size() == 0)
+	{
+		// Chan empty. Wait for item to be added.
+		added.wait(lock, [this] { return queue.size() > 0; });
+	}
+	T out = queue.front();
+	queue.pop();
+	lock.unlock();
+	removed.notify_one();
+	return out;
+}
+
+template <typename T>
+std::pair<T, bool> Chan<T>::tryTake()
+{
+	std::unique_lock<std::mutex> lock(mutex);
+	if (queue.size() == 0)
+	{
+		return std::make_pair(T{}, false);
+	}
+	T out = queue.front();
+	queue.pop();
+	lock.unlock();
+	removed.notify_one();
+	return std::make_pair(out, true);
+}
+
+template <typename T>
+void Chan<T>::put(const T &item)
+{
+	std::unique_lock<std::mutex> lock(mutex);
+	queue.push(item);
+	lock.unlock();
+	added.notify_one();
+}
+
+template <typename T>
+size_t Chan<T>::count()
+{
+	std::unique_lock<std::mutex> lock(mutex);
+	auto out = queue.size();
+	lock.unlock();
+	return out;
+}
+
+} // namespace sw
+
+#endif // sw_Synchronization_hpp
diff --git a/src/Vulkan/VkQueue.hpp b/src/Vulkan/VkQueue.hpp
index 9dda990..2fdb552 100644
--- a/src/Vulkan/VkQueue.hpp
+++ b/src/Vulkan/VkQueue.hpp
@@ -17,10 +17,11 @@
 
 #include "VkObject.hpp"
 #include "Device/Renderer.hpp"
-#include <queue>
 #include <thread>
 #include <vulkan/vk_icd.h>
 
+#include "System/Synchronization.hpp"
+
 namespace sw
 {
 	class Context;
@@ -30,91 +31,6 @@
 namespace vk
 {
 
-// Chan is a thread-safe FIFO queue of type T.
-// Chan takes its name after Golang's chan.
-template <typename T>
-class Chan
-{
-public:
-	Chan();
-
-	// take returns the next item in the chan, blocking until an item is
-	// available.
-	T take();
-
-	// tryTake returns a <T, bool> pair.
-	// If the chan is not empty, then the next item and true are returned.
-	// If the chan is empty, then a default-initialized T and false are returned.
-	std::pair<T, bool> tryTake();
-
-	// put places an item into the chan, blocking if the chan is bounded and
-	// full.
-	void put(const T &v);
-
-	// Returns the number of items in the chan.
-	// Note: that this may change as soon as the function returns, so should
-	// only be used for debugging.
-	size_t count();
-
-private:
-	std::queue<T> queue;
-	std::mutex mutex;
-	std::condition_variable added;
-	std::condition_variable removed;
-};
-
-template <typename T>
-Chan<T>::Chan() {}
-
-template <typename T>
-T Chan<T>::take()
-{
-	std::unique_lock<std::mutex> lock(mutex);
-	if (queue.size() == 0)
-	{
-		// Chan empty. Wait for item to be added.
-		added.wait(lock, [this] { return queue.size() > 0; });
-	}
-	T out = queue.front();
-	queue.pop();
-	lock.unlock();
-	removed.notify_one();
-	return out;
-}
-
-template <typename T>
-std::pair<T, bool> Chan<T>::tryTake()
-{
-	std::unique_lock<std::mutex> lock(mutex);
-	if (queue.size() == 0)
-	{
-		return std::make_pair(T{}, false);
-	}
-	T out = queue.front();
-	queue.pop();
-	lock.unlock();
-	removed.notify_one();
-	return std::make_pair(out, true);
-}
-
-template <typename T>
-void Chan<T>::put(const T &item)
-{
-	std::unique_lock<std::mutex> lock(mutex);
-	queue.push(item);
-	lock.unlock();
-	added.notify_one();
-}
-
-template <typename T>
-size_t Chan<T>::count()
-{
-	std::unique_lock<std::mutex> lock(mutex);
-	auto out = queue.size();
-	lock.unlock();
-	return out;
-}
-
 class Queue
 {
 	VK_LOADER_DATA loaderData = { ICD_LOADER_MAGIC };
@@ -152,8 +68,8 @@
 	void submitQueue(const Task& task);
 
 	std::unique_ptr<sw::Renderer> renderer;
-	Chan<Task> pending;
-	Chan<VkSubmitInfo*> toDelete;
+	sw::Chan<Task> pending;
+	sw::Chan<VkSubmitInfo*> toDelete;
 	std::thread queueThread;
 };
 
diff --git a/src/Vulkan/vulkan.vcxproj b/src/Vulkan/vulkan.vcxproj
index 153f4a0..60becd3 100644
--- a/src/Vulkan/vulkan.vcxproj
+++ b/src/Vulkan/vulkan.vcxproj
@@ -279,6 +279,7 @@
     <ClInclude Include="..\System\Resource.hpp" />

     <ClInclude Include="..\System\SharedLibrary.hpp" />

     <ClInclude Include="..\System\Socket.hpp" />

+    <ClInclude Include="..\System\Synchronization.hpp" />

     <ClInclude Include="..\System\Thread.hpp" />

     <ClInclude Include="..\System\Timer.hpp" />

     <ClInclude Include="..\System\Types.hpp" />

diff --git a/src/Vulkan/vulkan.vcxproj.filters b/src/Vulkan/vulkan.vcxproj.filters
index feca9b6..98105bc 100644
--- a/src/Vulkan/vulkan.vcxproj.filters
+++ b/src/Vulkan/vulkan.vcxproj.filters
@@ -503,6 +503,9 @@
     <ClInclude Include="..\System\Socket.hpp">

       <Filter>Header Files\System</Filter>

     </ClInclude>

+    <ClInclude Include="..\System\Synchronization.hpp">

+      <Filter>Header Files\System</Filter>

+    </ClInclude>

     <ClInclude Include="..\System\Thread.hpp">

       <Filter>Header Files\System</Filter>

     </ClInclude>