فهرست منبع

Extract 'SafeBinaryMutex' to separate header

    This change simply extracts 'SafeBinaryMutex' from 'mutex.h' to
    'safe_binary_mutex.h', in an effort to reduce the compilation
    speed impact of including `mutex.h`.
vittorioromeo 1 سال پیش
والد
کامیت
71e0082ab0
4فایلهای تغییر یافته به همراه128 افزوده شده و 80 حذف شده
  1. 1 0
      core/io/resource_loader.cpp
  2. 3 0
      core/io/resource_loader.h
  3. 0 80
      core/os/mutex.h
  4. 124 0
      core/os/safe_binary_mutex.h

+ 1 - 0
core/io/resource_loader.cpp

@@ -36,6 +36,7 @@
 #include "core/object/script_language.h"
 #include "core/os/condition_variable.h"
 #include "core/os/os.h"
+#include "core/os/safe_binary_mutex.h"
 #include "core/string/print_string.h"
 #include "core/string/translation.h"
 #include "core/variant/variant_parser.h"

+ 3 - 0
core/io/resource_loader.h

@@ -39,6 +39,9 @@
 
 class ConditionVariable;
 
+template <int Tag>
+class SafeBinaryMutex;
+
 class ResourceFormatLoader : public RefCounted {
 	GDCLASS(ResourceFormatLoader, RefCounted);
 

+ 0 - 80
core/os/mutex.h

@@ -70,56 +70,6 @@ public:
 	}
 };
 
-// A very special kind of mutex, used in scenarios where these
-// requirements hold at the same time:
-// - Must be used with a condition variable (only binary mutexes are suitable).
-// - Must have recursive semnantics (or simulate, as this one does).
-// The implementation keeps the lock count in TS. Therefore, only
-// one object of each version of the template can exists; hence the Tag argument.
-// Tags must be unique across the Godot codebase.
-// Also, don't forget to declare the thread_local variable on each use.
-template <int Tag>
-class SafeBinaryMutex {
-	friend class MutexLock<SafeBinaryMutex>;
-
-	using StdMutexType = THREADING_NAMESPACE::mutex;
-
-	mutable THREADING_NAMESPACE::mutex mutex;
-	static thread_local uint32_t count;
-
-public:
-	_ALWAYS_INLINE_ void lock() const {
-		if (++count == 1) {
-			mutex.lock();
-		}
-	}
-
-	_ALWAYS_INLINE_ void unlock() const {
-		DEV_ASSERT(count);
-		if (--count == 0) {
-			mutex.unlock();
-		}
-	}
-
-	_ALWAYS_INLINE_ bool try_lock() const {
-		if (count) {
-			count++;
-			return true;
-		} else {
-			if (mutex.try_lock()) {
-				count++;
-				return true;
-			} else {
-				return false;
-			}
-		}
-	}
-
-	~SafeBinaryMutex() {
-		DEV_ASSERT(!count);
-	}
-};
-
 template <class MutexT>
 class MutexLock {
 	friend class ConditionVariable;
@@ -131,24 +81,6 @@ public:
 			lock(p_mutex.mutex) {}
 };
 
-// This specialization is needed so manual locking and MutexLock can be used
-// at the same time on a SafeBinaryMutex.
-template <int Tag>
-class MutexLock<SafeBinaryMutex<Tag>> {
-	friend class ConditionVariable;
-
-	THREADING_NAMESPACE::unique_lock<THREADING_NAMESPACE::mutex> lock;
-
-public:
-	_ALWAYS_INLINE_ explicit MutexLock(const SafeBinaryMutex<Tag> &p_mutex) :
-			lock(p_mutex.mutex) {
-		SafeBinaryMutex<Tag>::count++;
-	};
-	_ALWAYS_INLINE_ ~MutexLock() {
-		SafeBinaryMutex<Tag>::count--;
-	};
-};
-
 using Mutex = MutexImpl<THREADING_NAMESPACE::recursive_mutex>; // Recursive, for general use
 using BinaryMutex = MutexImpl<THREADING_NAMESPACE::mutex>; // Non-recursive, handle with care
 
@@ -168,24 +100,12 @@ public:
 	bool try_lock() const { return true; }
 };
 
-template <int Tag>
-class SafeBinaryMutex : public MutexImpl {
-	static thread_local uint32_t count;
-};
-
 template <class MutexT>
 class MutexLock {
 public:
 	MutexLock(const MutexT &p_mutex) {}
 };
 
-template <int Tag>
-class MutexLock<SafeBinaryMutex<Tag>> {
-public:
-	MutexLock(const SafeBinaryMutex<Tag> &p_mutex) {}
-	~MutexLock() {}
-};
-
 using Mutex = MutexImpl;
 using BinaryMutex = MutexImpl;
 

+ 124 - 0
core/os/safe_binary_mutex.h

@@ -0,0 +1,124 @@
+/**************************************************************************/
+/*  safe_binary_mutex.h                                                   */
+/**************************************************************************/
+/*                         This file is part of:                          */
+/*                             GODOT ENGINE                               */
+/*                        https://godotengine.org                         */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
+/*                                                                        */
+/* Permission is hereby granted, free of charge, to any person obtaining  */
+/* a copy of this software and associated documentation files (the        */
+/* "Software"), to deal in the Software without restriction, including    */
+/* without limitation the rights to use, copy, modify, merge, publish,    */
+/* distribute, sublicense, and/or sell copies of the Software, and to     */
+/* permit persons to whom the Software is furnished to do so, subject to  */
+/* the following conditions:                                              */
+/*                                                                        */
+/* The above copyright notice and this permission notice shall be         */
+/* included in all copies or substantial portions of the Software.        */
+/*                                                                        */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
+/**************************************************************************/
+
+#ifndef SAFE_BINARY_MUTEX_H
+#define SAFE_BINARY_MUTEX_H
+
+#include "core/error/error_macros.h"
+#include "core/os/mutex.h"
+#include "core/typedefs.h"
+
+#ifdef THREADS_ENABLED
+
+// A very special kind of mutex, used in scenarios where these
+// requirements hold at the same time:
+// - Must be used with a condition variable (only binary mutexes are suitable).
+// - Must have recursive semnantics (or simulate, as this one does).
+// The implementation keeps the lock count in TS. Therefore, only
+// one object of each version of the template can exists; hence the Tag argument.
+// Tags must be unique across the Godot codebase.
+// Also, don't forget to declare the thread_local variable on each use.
+template <int Tag>
+class SafeBinaryMutex {
+	friend class MutexLock<SafeBinaryMutex>;
+
+	using StdMutexType = THREADING_NAMESPACE::mutex;
+
+	mutable THREADING_NAMESPACE::mutex mutex;
+	static thread_local uint32_t count;
+
+public:
+	_ALWAYS_INLINE_ void lock() const {
+		if (++count == 1) {
+			mutex.lock();
+		}
+	}
+
+	_ALWAYS_INLINE_ void unlock() const {
+		DEV_ASSERT(count);
+		if (--count == 0) {
+			mutex.unlock();
+		}
+	}
+
+	_ALWAYS_INLINE_ bool try_lock() const {
+		if (count) {
+			count++;
+			return true;
+		} else {
+			if (mutex.try_lock()) {
+				count++;
+				return true;
+			} else {
+				return false;
+			}
+		}
+	}
+
+	~SafeBinaryMutex() {
+		DEV_ASSERT(!count);
+	}
+};
+
+// This specialization is needed so manual locking and MutexLock can be used
+// at the same time on a SafeBinaryMutex.
+template <int Tag>
+class MutexLock<SafeBinaryMutex<Tag>> {
+	friend class ConditionVariable;
+
+	THREADING_NAMESPACE::unique_lock<THREADING_NAMESPACE::mutex> lock;
+
+public:
+	_ALWAYS_INLINE_ explicit MutexLock(const SafeBinaryMutex<Tag> &p_mutex) :
+			lock(p_mutex.mutex) {
+		SafeBinaryMutex<Tag>::count++;
+	};
+	_ALWAYS_INLINE_ ~MutexLock() {
+		SafeBinaryMutex<Tag>::count--;
+	};
+};
+
+#else // No threads.
+
+template <int Tag>
+class SafeBinaryMutex : public MutexImpl {
+	static thread_local uint32_t count;
+};
+
+template <int Tag>
+class MutexLock<SafeBinaryMutex<Tag>> {
+public:
+	MutexLock(const SafeBinaryMutex<Tag> &p_mutex) {}
+	~MutexLock() {}
+};
+
+#endif // THREADS_ENABLED
+
+#endif // SAFE_BINARY_MUTEX_H