2
0
Branimir Karadžić 8 жил өмнө
parent
commit
9c7f2db06b

+ 1 - 0
include/bx/bx.h

@@ -15,6 +15,7 @@
 #include "platform.h"
 #include "config.h"
 #include "macros.h"
+#include "debug.h"
 
 ///
 #define BX_COUNTOF(_x) sizeof(bx::COUNTOF_REQUIRES_ARRAY_ARGUMENT(_x) )

+ 1 - 0
include/bx/thread.h

@@ -59,6 +59,7 @@ namespace bx
 		ThreadFn  m_fn;
 		void*     m_userData;
 		MpScUnboundedBlockingQueue<void> m_queue;
+		Semaphore m_sem;
 		uint32_t  m_stackSize;
 		int32_t   m_exitCode;
 		bool      m_running;

+ 40 - 0
src/bx_p.h

@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010-2017 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_P_H_HEADER_GUARD
+#define BX_P_H_HEADER_GUARD
+
+#if 1 // BX_CONFIG_DEBUG
+#	define BX_TRACE _BX_TRACE
+#	define BX_WARN  _BX_WARN
+#	define BX_CHECK _BX_CHECK
+#	define BX_CONFIG_ALLOCATOR_DEBUG 1
+#endif // BX_CONFIG_DEBUG
+
+#define _BX_TRACE(_format, ...)                                                                       \
+				BX_MACRO_BLOCK_BEGIN                                                                  \
+					bx::debugPrintf(__FILE__ "(" BX_STRINGIZE(__LINE__) "): BX " _format "\n", ##__VA_ARGS__); \
+				BX_MACRO_BLOCK_END
+
+#define _BX_WARN(_condition, _format, ...)                        \
+				BX_MACRO_BLOCK_BEGIN                              \
+					if (!BX_IGNORE_C4127(_condition) )            \
+					{                                             \
+						BX_TRACE("WARN " _format, ##__VA_ARGS__); \
+					}                                             \
+				BX_MACRO_BLOCK_END
+
+#define _BX_CHECK(_condition, _format, ...)                        \
+				BX_MACRO_BLOCK_BEGIN                               \
+					if (!BX_IGNORE_C4127(_condition) )             \
+					{                                              \
+						BX_TRACE("CHECK " _format, ##__VA_ARGS__); \
+						bx::debugBreak();                          \
+					}                                              \
+				BX_MACRO_BLOCK_END
+
+#include <bx/bx.h>
+
+#endif // BX_P_H_HEADER_GUARD

+ 18 - 19
src/semaphore.cpp

@@ -3,6 +3,7 @@
  * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  */
 
+#include "bx_p.h"
 #include <bx/semaphore.h>
 
 #if BX_CONFIG_SUPPORTS_THREADING
@@ -24,9 +25,10 @@
 
 #ifndef BX_CONFIG_SEMAPHORE_PTHREAD
 #	define BX_CONFIG_SEMAPHORE_PTHREAD (0 \
-			|| BX_PLATFORM_OSX            \
-			|| BX_PLATFORM_IOS            \
-			)
+		|| BX_PLATFORM_LINUX              \
+		|| BX_PLATFORM_OSX                \
+		|| BX_PLATFORM_IOS                \
+		)
 #endif // BX_CONFIG_SEMAPHORE_PTHREAD
 
 namespace bx
@@ -135,13 +137,13 @@ namespace bx
 
 #		if BX_PLATFORM_OSX
 		BX_UNUSED(_msecs);
-		BX_CHECK(-1 == _msecs, "NaCl and OSX don't support pthread_cond_timedwait at this moment.");
+		BX_CHECK(-1 == _msecs, "OSX doesn't support pthread_cond_timedwait at this moment.");
 		while (0 == result
 		&&     0 >= si->m_count)
 		{
 			result = pthread_cond_wait(&si->m_cond, &si->m_mutex);
 		}
-#		elif BX_PLATFORM_IOS
+#		else
 		if (-1 == _msecs)
 		{
 			while (0 == result
@@ -153,6 +155,7 @@ namespace bx
 		else
 		{
 			timespec ts;
+#			if BX_PLATFORM_IOS
 			toTimespecMs(ts, _msecs);
 
 			while (0 == result
@@ -160,16 +163,16 @@ namespace bx
 			{
 				result = pthread_cond_timedwait_relative_np(&si->m_cond, &si->m_mutex, &ts);
 			}
-		}
-#		else
-		timespec ts;
-		clock_gettime(CLOCK_REALTIME, &ts);
-		add(ts, _msecs);
+#			else
+			clock_gettime(CLOCK_REALTIME, &ts);
+			add(ts, _msecs);
 
-		while (0 == result
-		&&     0 >= si->m_count)
-		{
-			result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts);
+			while (0 == result
+			&&     0 >= si->m_count)
+			{
+				result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts);
+			}
+#			endif // BX_PLATFORM_IOS
 		}
 #		endif // BX_PLATFORM_
 		bool ok = 0 == result;
@@ -226,10 +229,6 @@ namespace bx
 	{
 		SemaphoreInternal* si = (SemaphoreInternal*)m_internal;
 
-#		if BX_PLATFORM_OSX
-		BX_CHECK(-1 == _msecs, "NaCl and OSX don't support sem_timedwait at this moment."); BX_UNUSED(_msecs);
-		return 0 == sem_wait(&si->m_handle);
-#		else
 		if (0 > _msecs)
 		{
 			int32_t result;
@@ -246,8 +245,8 @@ namespace bx
 		clock_gettime(CLOCK_REALTIME, &ts);
 		add(ts, _msecs);
 		return 0 == sem_timedwait(&si->m_handle, &ts);
-#		endif // BX_PLATFORM_
 	}
+
 #	endif // BX_CONFIG_SEMAPHORE_PTHREAD
 
 #elif  BX_PLATFORM_WINDOWS \

+ 6 - 4
src/thread.cpp

@@ -150,7 +150,7 @@ namespace bx
 #	error "Not implemented!"
 #endif // BX_PLATFORM_
 
-		m_queue.pop();
+		m_sem.wait();
 
 		if (NULL != _name)
 		{
@@ -250,7 +250,8 @@ namespace bx
 
 	void* Thread::pop()
 	{
-		return m_queue.pop();
+		void* ptr = m_queue.pop();
+		return ptr;
 	}
 
 	int32_t Thread::entry()
@@ -260,8 +261,9 @@ namespace bx
 		ti->m_threadId = ::GetCurrentThreadId();
 #endif // BX_PLATFORM_WINDOWS
 
-		m_queue.push(NULL);
-		return m_fn(this, m_userData);
+		m_sem.post();
+		int32_t result = m_fn(this, m_userData);
+		return result;
 	}
 
 	struct TlsDataInternal

+ 28 - 2
tests/thread_test.cpp

@@ -6,9 +6,13 @@
 #include "test.h"
 #include <bx/thread.h>
 
+bx::MpScUnboundedBlockingQueue<void> s_mpsc;
+
 int32_t threadExit0(bx::Thread* _thread, void*)
 {
-	BX_UNUSED(_thread);
+	_thread->pop();
+
+	s_mpsc.push(reinterpret_cast<void*>(uintptr_t(0x1300) ) );
 
 	return bx::kExitSuccess;
 }
@@ -17,10 +21,21 @@ int32_t threadExit1(bx::Thread* _thread, void*)
 {
 	BX_UNUSED(_thread);
 
+	s_mpsc.push(reinterpret_cast<void*>(uintptr_t(0x89) ) );
+
 	return bx::kExitFailure;
 }
 
-TEST_CASE("thread", "")
+TEST_CASE("Semaphore", "")
+{
+	bx::Semaphore sem;
+	REQUIRE(!sem.wait(10) );
+
+	sem.post(1);
+	REQUIRE(sem.wait() );
+}
+
+TEST_CASE("Thread", "")
 {
 	bx::Thread th;
 
@@ -28,6 +43,7 @@ TEST_CASE("thread", "")
 
 	th.init(threadExit0);
 	REQUIRE(th.isRunning() );
+	th.push(NULL);
 	th.shutdown();
 
 	REQUIRE(!th.isRunning() );
@@ -40,3 +56,13 @@ TEST_CASE("thread", "")
 	REQUIRE(!th.isRunning() );
 	REQUIRE(th.getExitCode() == 1);
 }
+
+TEST_CASE("MpScUnboundedBlockingQueue", "")
+{
+	void* p0 = s_mpsc.pop();
+	void* p1 = s_mpsc.pop();
+
+	uintptr_t result = uintptr_t(p0) | uintptr_t(p1);
+
+	REQUIRE(result == 0x1389);
+}