rmaprath updated this revision to Diff 55967.
rmaprath added a comment.
Re-spun on top of http://reviews.llvm.org/D19412.
http://reviews.llvm.org/D19415
Files:
include/__threading_support
src/algorithm.cpp
src/memory.cpp
src/mutex.cpp
Index: src/mutex.cpp
===================================================================
--- src/mutex.cpp
+++ src/mutex.cpp
@@ -195,8 +195,23 @@
// keep in sync with: 7741191.
#ifndef _LIBCPP_HAS_NO_THREADS
+# if defined(_LIBCPP_THREAD_API_EXTERNAL)
+static mutex mut;
+static condition_variable cv;
+# define __LOCK_INIT() unique_lock<mutex> lk(mut);
+# define __LOCK_LOCK() lk.lock();
+# define __LOCK_UNLOCK() lk.unlock();
+# define __CV_WAIT_LOCK() cv.wait(lk);
+# define __CV_NOTIFY_ALL() cv.notify_all();
+# else
static __libcpp_mutex_t mut = _LIBCPP_MUTEX_INITIALIZER;
static __libcpp_condvar_t cv = _LIBCPP_CONDVAR_INITIALIZER;
+# define __LOCK_INIT() __libcpp_mutex_lock(&mut);
+# define __LOCK_LOCK() __libcpp_mutex_lock(&mut);
+# define __LOCK_UNLOCK() __libcpp_mutex_unlock(&mut);
+# define __CV_WAIT_LOCK() __libcpp_condvar_wait(&cv, &mut);
+# define __CV_NOTIFY_ALL() __libcpp_condvar_broadcast(&cv);
+# endif
#endif
/// NOTE: Changes to flag are done via relaxed atomic stores
@@ -225,38 +240,46 @@
#endif // _LIBCPP_NO_EXCEPTIONS
}
#else // !_LIBCPP_HAS_NO_THREADS
- __libcpp_mutex_lock(&mut);
+ __LOCK_INIT()
while (flag == 1)
- __libcpp_condvar_wait(&cv, &mut);
+ __CV_WAIT_LOCK()
if (flag == 0)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
__libcpp_relaxed_store(&flag, 1ul);
- __libcpp_mutex_unlock(&mut);
+ __LOCK_UNLOCK()
func(arg);
- __libcpp_mutex_lock(&mut);
+ __LOCK_LOCK()
__libcpp_relaxed_store(&flag, ~0ul);
- __libcpp_mutex_unlock(&mut);
- __libcpp_condvar_broadcast(&cv);
+ __LOCK_UNLOCK()
+ __CV_NOTIFY_ALL()
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
- __libcpp_mutex_lock(&mut);
+ __LOCK_LOCK()
__libcpp_relaxed_store(&flag, 0ul);
- __libcpp_mutex_unlock(&mut);
- __libcpp_condvar_broadcast(&cv);
+ __LOCK_UNLOCK()
+ __CV_NOTIFY_ALL()
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
}
else
- __libcpp_mutex_unlock(&mut);
+ __LOCK_UNLOCK()
#endif // !_LIBCPP_HAS_NO_THREADS
}
+#ifndef _LIBCPP_HAS_NO_THREADS
+# undef __LOCK_INIT
+# undef __LOCK_LOCK
+# undef __LOCK_UNLOCK
+# undef __CV_WAIT_LOCK
+# undef __CV_NOTIFY_ALL
+#endif
+
_LIBCPP_END_NAMESPACE_STD
Index: src/memory.cpp
===================================================================
--- src/memory.cpp
+++ src/memory.cpp
@@ -127,13 +127,17 @@
#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
static const std::size_t __sp_mut_count = 16;
+#if defined(_LIBCPP_THREAD_API_EXTERNAL)
+static mutex mut_back_imp[__sp_mut_count];
+#else
static __libcpp_mutex_t mut_back_imp[__sp_mut_count] =
{
_LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
_LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
_LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
_LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER
};
+#endif
static mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp);
Index: src/algorithm.cpp
===================================================================
--- src/algorithm.cpp
+++ src/algorithm.cpp
@@ -48,14 +48,22 @@
template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
#ifndef _LIBCPP_HAS_NO_THREADS
+# if defined(_LIBCPP_THREAD_API_EXTERNAL)
+static mutex __rs_mut;
+# define __LOCK_LOCK() __rs_mut.lock();
+# define __LOCK_UNLOCK() __rs_mut.unlock();
+# else
static __libcpp_mutex_t __rs_mut = _LIBCPP_MUTEX_INITIALIZER;
+# define __LOCK_LOCK() __libcpp_mutex_lock(&__rs_mut);
+# define __LOCK_UNLOCK() __libcpp_mutex_unlock(&__rs_mut);
+# endif
#endif
unsigned __rs_default::__c_ = 0;
__rs_default::__rs_default()
{
#ifndef _LIBCPP_HAS_NO_THREADS
- __libcpp_mutex_lock(&__rs_mut);
+ __LOCK_LOCK()
#endif
__c_ = 1;
}
@@ -69,7 +77,7 @@
{
#ifndef _LIBCPP_HAS_NO_THREADS
if (--__c_ == 0)
- __libcpp_mutex_unlock(&__rs_mut);
+ __LOCK_UNLOCK()
#else
--__c_;
#endif
@@ -88,4 +96,9 @@
return __rs_default();
}
+#ifndef _LIBCPP_HAS_NO_THREADS
+# undef __LOCK_LOCK
+# undef __LOCK_UNLOCK
+#endif
+
_LIBCPP_END_NAMESPACE_STD
Index: include/__threading_support
===================================================================
--- include/__threading_support
+++ include/__threading_support
@@ -194,7 +194,73 @@
pthread_setspecific(__key, __p);
}
-#else // !_LIBCPP_THREAD_API_PTHREAD
+#elif defined(_LIBCPP_THREAD_API_EXTERNAL)
+
+// Mutex
+#define _LIBCPP_MUTEX_INITIALIZER 0
+struct __libcpp_mutex_external;
+typedef __libcpp_mutex_external* __libcpp_mutex_t;
+
+int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m);
+
+int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
+
+int __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
+
+int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
+
+int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
+
+// Condition variable
+#define _LIBCPP_CONDVAR_INITIALIZER 0
+struct __libcpp_condvar_external;
+typedef __libcpp_condvar_external* __libcpp_condvar_t;
+
+int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
+
+int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
+
+int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
+
+int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts);
+
+int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
+
+// Thread id
+typedef unsigned long __libcpp_thread_id;
+
+// Returns non-zero if the thread ids are equal, otherwise 0
+int __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
+
+// Returns non-zero if t1 < t2, otherwise 0
+int __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
+
+// Thread
+struct __libcpp_thread_external;
+typedef __libcpp_thread_external* __libcpp_thread_t;
+
+int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__f)(void*), void* __arg);
+
+__libcpp_thread_id __libcpp_thread_get_current_id();
+
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t);
+
+int __libcpp_thread_join(__libcpp_thread_t* __t);
+
+int __libcpp_thread_detach(__libcpp_thread_t* __t);
+
+void __libcpp_thread_yield();
+
+// Thread local storage
+typedef unsigned long __libcpp_tl_key;
+
+int __libcpp_tl_create(__libcpp_tl_key* __key, void (*__at_exit) (void*));
+
+void* __libcpp_tl_get(__libcpp_tl_key __key);
+
+void __libcpp_tl_set(__libcpp_tl_key __key, void* __p);
+
+#else
#error "No thread API selected."
#endif
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits