[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd closed this revision.
compnerd added a comment.

SVN r291333




Comment at: include/__threading_support:29-30
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

majnemer wrote:
> EricWF wrote:
> > I think we agreed that we cannot use this macro.
> Can we do as Reid suggests and not expose users to windows.h?
I think that I would rather do that in a follow up.  This will require a fair 
amount of duplication.


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF accepted this revision.
EricWF added a comment.
This revision is now accepted and ready to land.

LGTM. I just successfully built this on Windows.


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: include/__threading_support:30
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

EricWF wrote:
> smeenai wrote:
> > EricWF wrote:
> > > EricWF wrote:
> > > > smeenai wrote:
> > > > > EricWF wrote:
> > > > > > > Can we do as Reid suggests and not expose users to windows.h?
> > > > > > 
> > > > > > I was about to ask the same question.  These includes are dragging 
> > > > > > in the `__deallocate` macro and I would love to avoid that.
> > > > > I feel like we would end up with a //lot// of duplication if we went 
> > > > > down this route, since this is using a fair amount of Windows APIs. 
> > > > > @rnk suggested having a test for prototype mismatches, but even with 
> > > > > those checks there could be a high maintenance burden to the 
> > > > > duplication.
> > > > > 
> > > > > Was the main objection to `WIN32_LEAN_AND_MEAN` that it would be 
> > > > > problematic for modules? If we're including `windows.h`, it seems 
> > > > > strictly preferable to include it with `WIN32_LEAN_AND_MEAN` than 
> > > > > without, since we'll pull in a lot less that way. Including 
> > > > > `windows.h` without `WIN32_LEAN_AND_MEAN` can also interact with 
> > > > > other headers badly sometimes, e.g. 
> > > > > [`winsock2.h`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629%28v=vs.85%29.aspx).
> > > > It seems that dragging in the `__deallocate` macro is inevitable :-( 
> > > > 
> > > > I submitted a patch to work around `__deallocate` here: 
> > > > https://reviews.llvm.org/D28426
> > > > Was the main objection to WIN32_LEAN_AND_MEAN that it would be 
> > > > problematic for modules? If we're including windows.h, it seems 
> > > > strictly preferable to include it with WIN32_LEAN_AND_MEAN than 
> > > > without, since we'll pull in a lot less that way. Including windows.h 
> > > > without WIN32_LEAN_AND_MEAN can also interact with other headers badly 
> > > > sometimes, e.g. winsock2.h.
> > > 
> > > The objection is that it breaks user code. For example:
> > > 
> > > ```
> > > #include 
> > > #include  // Windows.h already included as lean and mean.
> > > 
> > > typedef NonLeanAndMeanSymbol foo; // ERROR NonLeanAndMeanSymbol not 
> > > defined
> > > 
> > > ```
> > > 
> > But without the `WIN32_LEAN_AND_MEAN`, we're gonna break
> > 
> > ```
> > #include 
> > #include 
> > ```
> > 
> > (you could fix this by reordering the includes, which would also fix your 
> > example, or by defining `WIN32_LEAN_AND_MEAN` yourself, but it doesn't seem 
> > great either)
> I would much rather break that code. The fact that `Windows.h` doesn't play 
> nice with other Windows headers is a problem for Windows not libc++.
Although I think avoiding the `Windows.h` include all together would be better 
(if possible). However I think that can be fixed after committing this.


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: include/__threading_support:30
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

smeenai wrote:
> EricWF wrote:
> > EricWF wrote:
> > > smeenai wrote:
> > > > EricWF wrote:
> > > > > > Can we do as Reid suggests and not expose users to windows.h?
> > > > > 
> > > > > I was about to ask the same question.  These includes are dragging in 
> > > > > the `__deallocate` macro and I would love to avoid that.
> > > > I feel like we would end up with a //lot// of duplication if we went 
> > > > down this route, since this is using a fair amount of Windows APIs. 
> > > > @rnk suggested having a test for prototype mismatches, but even with 
> > > > those checks there could be a high maintenance burden to the 
> > > > duplication.
> > > > 
> > > > Was the main objection to `WIN32_LEAN_AND_MEAN` that it would be 
> > > > problematic for modules? If we're including `windows.h`, it seems 
> > > > strictly preferable to include it with `WIN32_LEAN_AND_MEAN` than 
> > > > without, since we'll pull in a lot less that way. Including `windows.h` 
> > > > without `WIN32_LEAN_AND_MEAN` can also interact with other headers 
> > > > badly sometimes, e.g. 
> > > > [`winsock2.h`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629%28v=vs.85%29.aspx).
> > > It seems that dragging in the `__deallocate` macro is inevitable :-( 
> > > 
> > > I submitted a patch to work around `__deallocate` here: 
> > > https://reviews.llvm.org/D28426
> > > Was the main objection to WIN32_LEAN_AND_MEAN that it would be 
> > > problematic for modules? If we're including windows.h, it seems strictly 
> > > preferable to include it with WIN32_LEAN_AND_MEAN than without, since 
> > > we'll pull in a lot less that way. Including windows.h without 
> > > WIN32_LEAN_AND_MEAN can also interact with other headers badly sometimes, 
> > > e.g. winsock2.h.
> > 
> > The objection is that it breaks user code. For example:
> > 
> > ```
> > #include 
> > #include  // Windows.h already included as lean and mean.
> > 
> > typedef NonLeanAndMeanSymbol foo; // ERROR NonLeanAndMeanSymbol not defined
> > 
> > ```
> > 
> But without the `WIN32_LEAN_AND_MEAN`, we're gonna break
> 
> ```
> #include 
> #include 
> ```
> 
> (you could fix this by reordering the includes, which would also fix your 
> example, or by defining `WIN32_LEAN_AND_MEAN` yourself, but it doesn't seem 
> great either)
I would much rather break that code. The fact that `Windows.h` doesn't play 
nice with other Windows headers is a problem for Windows not libc++.


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai added inline comments.



Comment at: include/__threading_support:30
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

EricWF wrote:
> EricWF wrote:
> > smeenai wrote:
> > > EricWF wrote:
> > > > > Can we do as Reid suggests and not expose users to windows.h?
> > > > 
> > > > I was about to ask the same question.  These includes are dragging in 
> > > > the `__deallocate` macro and I would love to avoid that.
> > > I feel like we would end up with a //lot// of duplication if we went down 
> > > this route, since this is using a fair amount of Windows APIs. @rnk 
> > > suggested having a test for prototype mismatches, but even with those 
> > > checks there could be a high maintenance burden to the duplication.
> > > 
> > > Was the main objection to `WIN32_LEAN_AND_MEAN` that it would be 
> > > problematic for modules? If we're including `windows.h`, it seems 
> > > strictly preferable to include it with `WIN32_LEAN_AND_MEAN` than 
> > > without, since we'll pull in a lot less that way. Including `windows.h` 
> > > without `WIN32_LEAN_AND_MEAN` can also interact with other headers badly 
> > > sometimes, e.g. 
> > > [`winsock2.h`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629%28v=vs.85%29.aspx).
> > It seems that dragging in the `__deallocate` macro is inevitable :-( 
> > 
> > I submitted a patch to work around `__deallocate` here: 
> > https://reviews.llvm.org/D28426
> > Was the main objection to WIN32_LEAN_AND_MEAN that it would be problematic 
> > for modules? If we're including windows.h, it seems strictly preferable to 
> > include it with WIN32_LEAN_AND_MEAN than without, since we'll pull in a lot 
> > less that way. Including windows.h without WIN32_LEAN_AND_MEAN can also 
> > interact with other headers badly sometimes, e.g. winsock2.h.
> 
> The objection is that it breaks user code. For example:
> 
> ```
> #include 
> #include  // Windows.h already included as lean and mean.
> 
> typedef NonLeanAndMeanSymbol foo; // ERROR NonLeanAndMeanSymbol not defined
> 
> ```
> 
But without the `WIN32_LEAN_AND_MEAN`, we're gonna break

```
#include 
#include 
```

(you could fix this by reordering the includes, which would also fix your 
example, or by defining `WIN32_LEAN_AND_MEAN` yourself, but it doesn't seem 
great either)


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: include/__threading_support:30
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

EricWF wrote:
> smeenai wrote:
> > EricWF wrote:
> > > > Can we do as Reid suggests and not expose users to windows.h?
> > > 
> > > I was about to ask the same question.  These includes are dragging in the 
> > > `__deallocate` macro and I would love to avoid that.
> > I feel like we would end up with a //lot// of duplication if we went down 
> > this route, since this is using a fair amount of Windows APIs. @rnk 
> > suggested having a test for prototype mismatches, but even with those 
> > checks there could be a high maintenance burden to the duplication.
> > 
> > Was the main objection to `WIN32_LEAN_AND_MEAN` that it would be 
> > problematic for modules? If we're including `windows.h`, it seems strictly 
> > preferable to include it with `WIN32_LEAN_AND_MEAN` than without, since 
> > we'll pull in a lot less that way. Including `windows.h` without 
> > `WIN32_LEAN_AND_MEAN` can also interact with other headers badly sometimes, 
> > e.g. 
> > [`winsock2.h`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629%28v=vs.85%29.aspx).
> It seems that dragging in the `__deallocate` macro is inevitable :-( 
> 
> I submitted a patch to work around `__deallocate` here: 
> https://reviews.llvm.org/D28426
> Was the main objection to WIN32_LEAN_AND_MEAN that it would be problematic 
> for modules? If we're including windows.h, it seems strictly preferable to 
> include it with WIN32_LEAN_AND_MEAN than without, since we'll pull in a lot 
> less that way. Including windows.h without WIN32_LEAN_AND_MEAN can also 
> interact with other headers badly sometimes, e.g. winsock2.h.

The objection is that it breaks user code. For example:

```
#include 
#include  // Windows.h already included as lean and mean.

typedef NonLeanAndMeanSymbol foo; // ERROR NonLeanAndMeanSymbol not defined

```



https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: include/__threading_support:30
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

smeenai wrote:
> EricWF wrote:
> > > Can we do as Reid suggests and not expose users to windows.h?
> > 
> > I was about to ask the same question.  These includes are dragging in the 
> > `__deallocate` macro and I would love to avoid that.
> I feel like we would end up with a //lot// of duplication if we went down 
> this route, since this is using a fair amount of Windows APIs. @rnk suggested 
> having a test for prototype mismatches, but even with those checks there 
> could be a high maintenance burden to the duplication.
> 
> Was the main objection to `WIN32_LEAN_AND_MEAN` that it would be problematic 
> for modules? If we're including `windows.h`, it seems strictly preferable to 
> include it with `WIN32_LEAN_AND_MEAN` than without, since we'll pull in a lot 
> less that way. Including `windows.h` without `WIN32_LEAN_AND_MEAN` can also 
> interact with other headers badly sometimes, e.g. 
> [`winsock2.h`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629%28v=vs.85%29.aspx).
It seems that dragging in the `__deallocate` macro is inevitable :-( 

I submitted a patch to work around `__deallocate` here: 
https://reviews.llvm.org/D28426


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai added inline comments.



Comment at: include/__threading_support:30
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

EricWF wrote:
> > Can we do as Reid suggests and not expose users to windows.h?
> 
> I was about to ask the same question.  These includes are dragging in the 
> `__deallocate` macro and I would love to avoid that.
I feel like we would end up with a //lot// of duplication if we went down this 
route, since this is using a fair amount of Windows APIs. @rnk suggested having 
a test for prototype mismatches, but even with those checks there could be a 
high maintenance burden to the duplication.

Was the main objection to `WIN32_LEAN_AND_MEAN` that it would be problematic 
for modules? If we're including `windows.h`, it seems strictly preferable to 
include it with `WIN32_LEAN_AND_MEAN` than without, since we'll pull in a lot 
less that way. Including `windows.h` without `WIN32_LEAN_AND_MEAN` can also 
interact with other headers badly sometimes, e.g. 
[`winsock2.h`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737629%28v=vs.85%29.aspx).


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd removed rL LLVM as the repository for this revision.
compnerd updated this revision to Diff 83469.
compnerd marked 2 inline comments as done.
compnerd added a comment.

remove `WIN32_LEAN_AND_MEAN`, fix decoration, remove inline decorations


https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support
  include/thread

Index: include/thread
===
--- include/thread
+++ include/thread
@@ -148,7 +148,8 @@
 __thread_specific_ptr(const __thread_specific_ptr&);
 __thread_specific_ptr& operator=(const __thread_specific_ptr&);
 
-static void __at_thread_exit(void*);
+static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
+
 public:
 typedef _Tp* pointer;
 
@@ -164,21 +165,19 @@
 };
 
 template 
-void
+void _LIBCPP_TLS_DESTRUCTOR_CC
 __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
 {
 delete static_cast(__p);
 }
 
 template 
 __thread_specific_ptr<_Tp>::__thread_specific_ptr()
 {
-int __ec = __libcpp_tls_create(
-&__key_,
-&__thread_specific_ptr::__at_thread_exit);
-if (__ec)
-__throw_system_error(__ec,
-   "__thread_specific_ptr construction failed");
+  int __ec =
+  __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+  if (__ec)
+__throw_system_error(__ec, "__thread_specific_ptr construction failed");
 }
 
 template 
Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -24,6 +24,13 @@
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 # include 
 # include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#include 
+#include 
+#include 
+#include 
+
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
@@ -58,6 +65,33 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC
+#else
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute Once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI
 #endif
 
 // Mutex
@@ -144,7 +178,8 @@
 
 // Thread local storage
 _LIBCPP_THREAD_ABI_VISIBILITY
-int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *));
+int __libcpp_tls_create(__libcpp_tls_key* __key,
+void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
 
 _LIBCPP_THREAD_ABI_VISIBILITY
 void *__libcpp_tls_get(__libcpp_tls_key __key);
@@ -321,6 +356,224 @@
 return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection(__m);
+  return 0;
+}
+
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  TryEnterCriticalSection(__m);
+  return 0;
+}
+
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection(__m);
+  return 0;
+}
+
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  TryAcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+   timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+
+  auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto abstime =
+  system_clock::time_point(duration_cast(duration));
+  auto timeout_ms = duration_cast(abstime - system_clock::now());
+
+  if (!SleepConditionVariableSRW(__cv, __m,
+   

[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: include/__threading_support:30
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

> Can we do as Reid suggests and not expose users to windows.h?

I was about to ask the same question.  These includes are dragging in the 
`__deallocate` macro and I would love to avoid that.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: include/__threading_support:580
+int __libcpp_tls_create(__libcpp_tls_key* __key,
+void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*))
+{

The `_LIBCPP_TLS_DESTRUCTOR_CC` needs to appear an the initial declaration as 
well.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread David Majnemer via Phabricator via cfe-commits
majnemer added inline comments.



Comment at: include/__threading_support:29-30
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 

EricWF wrote:
> I think we agreed that we cannot use this macro.
Can we do as Reid suggests and not expose users to windows.h?


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: include/__threading_support:29
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 

I think we agreed that we cannot use this macro.



Comment at: include/__threading_support:426
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)

DO NOT ANNOTATE THESE DEFINITIONS!! The forward declarations are already 
properly declared.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

Just tried the updated patch and I still get one build error:

  C:\Users\Eric\workspace\libcxx\src\thread.cpp(135,16):  error: use of 
undeclared identifier 'nanosleep'
  while (nanosleep(, ) == -1 && errno == EINTR)


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd set the repository for this revision to rL LLVM.
compnerd updated this revision to Diff 83453.

Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support
  include/thread

Index: include/thread
===
--- include/thread
+++ include/thread
@@ -148,7 +148,8 @@
 __thread_specific_ptr(const __thread_specific_ptr&);
 __thread_specific_ptr& operator=(const __thread_specific_ptr&);
 
-static void __at_thread_exit(void*);
+static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
+
 public:
 typedef _Tp* pointer;
 
@@ -164,21 +165,19 @@
 };
 
 template 
-void
+void _LIBCPP_TLS_DESTRUCTOR_CC
 __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
 {
 delete static_cast(__p);
 }
 
 template 
 __thread_specific_ptr<_Tp>::__thread_specific_ptr()
 {
-int __ec = __libcpp_tls_create(
-&__key_,
-&__thread_specific_ptr::__at_thread_exit);
-if (__ec)
-__throw_system_error(__ec,
-   "__thread_specific_ptr construction failed");
+  int __ec =
+  __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+  if (__ec)
+__throw_system_error(__ec, "__thread_specific_ptr construction failed");
 }
 
 template 
Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -24,6 +24,14 @@
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 # include 
 # include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#include 
+
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
@@ -58,6 +66,33 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC
+#else
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute Once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI
 #endif
 
 // Mutex
@@ -321,6 +356,249 @@
 return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  TryEnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  TryAcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+   timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+
+  auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto abstime =
+  system_clock::time_point(duration_cast(duration));
+  auto timeout_ms = duration_cast(abstime - system_clock::now());
+
+  if (!SleepConditionVariableSRW(__cv, __m,
+ timeout_ms.count() > 0 ? timeout_ms.count()
+: 0,
+ 0))
+return 

[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

I'm seeing the following build errors on Windows:

  C:\Users\Eric\workspace\libcxx\include\__threading_support(521,3):  warning: 
cannot delete expression with pointer-to-'void' type 'void *' 
[-Wdelete-incomplete]
delete __data;
^  ~~
  C:\Users\Eric\workspace\libcxx\include\__threading_support(530,18):  error: 
assigning to 'void *(*)(void *)' from incompatible type 'void (*)(void *)': 
different return type ('void *' vs 'void')
data->__func = __func;
   ^~
  C:\Users\Eric\workspace\libcxx\include\__threading_support(572,5):  error: 
functions that differ only in their return type cannot be overloaded
  int __libcpp_thread_yield()
  ~~~ ^
  C:\Users\Eric\workspace\libcxx\include\__threading_support(178,6):  note: 
previous declaration is here
  void __libcpp_thread_yield();
   ^
  C:\Users\Eric\workspace\libcxx\include\__threading_support(589,5):  error: 
functions that differ only in their return type cannot be overloaded
  int __libcpp_tls_get(__libcpp_tls_key __key)
  ~~~ ^
  C:\Users\Eric\workspace\libcxx\include\__threading_support(185,7):  note: 
previous declaration is here
  void *__libcpp_tls_get(__libcpp_tls_key __key);
  ~~^
  C:\Users\Eric\workspace\libcxx\include\__threading_support(591,10):  error: 
cannot initialize return object of type 'int' with an rvalue of type 'PVOID' 
(aka 'void *')
return FlsGetValue(__key);


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Andrey Khalyavin via Phabricator via cfe-commits
halyavin added a comment.

LGTM.




Comment at: include/__threading_support:480
+  if (!SleepConditionVariableSRW(__cv, __m,
+ timeout_ms.count() > 0 ? timeout_ms.count()
+: 0,

There is still problem with large timeout but let us fix it later.


https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd removed rL LLVM as the repository for this revision.
compnerd updated this revision to Diff 83432.
compnerd added a comment.

rebase


https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support
  include/thread

Index: include/thread
===
--- include/thread
+++ include/thread
@@ -148,7 +148,8 @@
 __thread_specific_ptr(const __thread_specific_ptr&);
 __thread_specific_ptr& operator=(const __thread_specific_ptr&);
 
-static void __at_thread_exit(void*);
+static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
+
 public:
 typedef _Tp* pointer;
 
@@ -164,21 +165,19 @@
 };
 
 template 
-void
+void _LIBCPP_TLS_DESTRUCTOR_CC
 __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
 {
 delete static_cast(__p);
 }
 
 template 
 __thread_specific_ptr<_Tp>::__thread_specific_ptr()
 {
-int __ec = __libcpp_tls_create(
-&__key_,
-&__thread_specific_ptr::__at_thread_exit);
-if (__ec)
-__throw_system_error(__ec,
-   "__thread_specific_ptr construction failed");
+  int __ec =
+  __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+  if (__ec)
+__throw_system_error(__ec, "__thread_specific_ptr construction failed");
 }
 
 template 
Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -24,6 +24,14 @@
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 # include 
 # include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#include 
+
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
@@ -58,6 +66,33 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC
+#else
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute Once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI
 #endif
 
 // Mutex
@@ -321,6 +356,249 @@
 return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  TryEnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  TryAcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+   timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+
+  auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto abstime =
+  system_clock::time_point(duration_cast(duration));
+  auto timeout_ms = duration_cast(abstime - system_clock::now());
+
+  if (!SleepConditionVariableSRW(__cv, __m,
+ timeout_ms.count() > 0 ? timeout_ms.count()
+: 0,
+ 

[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated this revision to Diff 83430.
compnerd marked an inline comment as done.
compnerd added a comment.

rebase, address negative timeouts, fix thunking for `__libcpp_tls_create`


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support
  include/thread

Index: include/thread
===
--- include/thread
+++ include/thread
@@ -148,7 +148,8 @@
 __thread_specific_ptr(const __thread_specific_ptr&);
 __thread_specific_ptr& operator=(const __thread_specific_ptr&);
 
-static void __at_thread_exit(void*);
+static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
+
 public:
 typedef _Tp* pointer;
 
@@ -164,21 +165,19 @@
 };
 
 template 
-void
+void _LIBCPP_TLS_DESTRUCTOR_CC
 __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
 {
 delete static_cast(__p);
 }
 
 template 
 __thread_specific_ptr<_Tp>::__thread_specific_ptr()
 {
-int __ec = __libcpp_tls_create(
-&__key_,
-&__thread_specific_ptr::__at_thread_exit);
-if (__ec)
-__throw_system_error(__ec,
-   "__thread_specific_ptr construction failed");
+  int __ec =
+  __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
+  if (__ec)
+__throw_system_error(__ec, "__thread_specific_ptr construction failed");
 }
 
 template 
Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -47,6 +47,14 @@
 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#include 
+
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -81,6 +89,33 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC
+#else
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute Once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
+
+#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI
 #endif
 
 // Mutex
@@ -342,6 +377,249 @@
 return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  TryEnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  TryAcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+   timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+
+  auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto abstime =
+  system_clock::time_point(duration_cast(duration));
+  auto timeout_ms = duration_cast(abstime - system_clock::now());
+
+  if (!SleepConditionVariableSRW(__cv, __m,
+ timeout_ms.count() > 0 ? timeout_ms.count()
+ 

[PATCH] D28220: provide Win32 native threading

2017-01-06 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF requested changes to this revision.
EricWF added a comment.
This revision now requires changes to proceed.

This needs to be rebased following the `<__threading_support>` cleanup in 
r291275.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-05 Thread Andrey Khalyavin via Phabricator via cfe-commits
halyavin added inline comments.



Comment at: include/__threading_support:474
+  
system_clock::time_point(duration_cast(duration));
+  auto timeout_ms = duration_cast(abstime - system_clock::now());
+

compnerd wrote:
> halyavin wrote:
> > Since negative timeouts can't be avoided, we must make sure that 
> > timeout_ms.count() is at least zero.
> Good point.  I suppose that the assert takes care of that though.
Negative timeout_ms.count() is a normal case, we shouldn't fail on assertion. 
The reason is that program can always be slow enough for current timestamp 
(system_clock::now()) to pass any fixed point in time (__ts/abstime). 



Comment at: include/__threading_support:476
+
+  _LIBCPP_ASSERT(timeout_ms.count() > INFINITE && "timeout duration overflow");
+  if (!SleepConditionVariableSRW(__cv, __m, timeout_ms.count(), 0))

compnerd wrote:
> halyavin wrote:
> > It is >= INFINITE. _LIBCPP_ASSERT has 2 arguments and supports error 
> > message out of the box.
> Shouldnt this be, `timeout_ms.count() > 0` which implicitly ensures that it 
> is not `INFINITE` (-1)?
I just checked in the Windows SDK, INFINITE is defined as `0x` and 
negative timeouts are legal anyway.



Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-05 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd marked an inline comment as done.
compnerd added inline comments.



Comment at: include/__threading_support:474
+  
system_clock::time_point(duration_cast(duration));
+  auto timeout_ms = duration_cast(abstime - system_clock::now());
+

halyavin wrote:
> Since negative timeouts can't be avoided, we must make sure that 
> timeout_ms.count() is at least zero.
Good point.  I suppose that the assert takes care of that though.



Comment at: include/__threading_support:476
+
+  _LIBCPP_ASSERT(timeout_ms.count() > INFINITE && "timeout duration overflow");
+  if (!SleepConditionVariableSRW(__cv, __m, timeout_ms.count(), 0))

halyavin wrote:
> It is >= INFINITE. _LIBCPP_ASSERT has 2 arguments and supports error message 
> out of the box.
Shouldnt this be, `timeout_ms.count() > 0` which implicitly ensures that it is 
not `INFINITE` (-1)?


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Andrey Khalyavin via Phabricator via cfe-commits
halyavin added inline comments.



Comment at: include/__threading_support:474
+  
system_clock::time_point(duration_cast(duration));
+  auto timeout_ms = duration_cast(abstime - system_clock::now());
+

Since negative timeouts can't be avoided, we must make sure that 
timeout_ms.count() is at least zero.



Comment at: include/__threading_support:476
+
+  _LIBCPP_ASSERT(timeout_ms.count() > INFINITE && "timeout duration overflow");
+  if (!SleepConditionVariableSRW(__cv, __m, timeout_ms.count(), 0))

It is >= INFINITE. _LIBCPP_ASSERT has 2 arguments and supports error message 
out of the box.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF accepted this revision.
EricWF added a comment.
This revision is now accepted and ready to land.

This LGTM.  I'm sure we can flush out any bugs once we get the tests running.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated this revision to Diff 83182.
compnerd marked an inline comment as done.
compnerd added a comment.

Fix `__libcpp_condvar_timedwait` parameter usage (absolute vs relative time)


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -47,6 +47,15 @@
 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#include 
+
+#include <__debug>
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -81,6 +90,29 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#else
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute Once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif
 
 // Mutex
@@ -342,6 +374,247 @@
 return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  TryEnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  TryAcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+   timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+
+  auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto abstime =
+  system_clock::time_point(duration_cast(duration));
+  auto timeout_ms = duration_cast(abstime - system_clock::now());
+
+  _LIBCPP_ASSERT(timeout_ms.count() > INFINITE && "timeout duration overflow");
+  if (!SleepConditionVariableSRW(__cv, __m, timeout_ms.count(), 0))
+return GetLastError();
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
+{
+  static_cast(__cv);
+  return 0;
+}
+
+// Execute Once
+static inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK
+__libcpp_init_once_execute_once_thunk(PINIT_ONCE __init_once, PVOID __parameter,
+  PVOID *__context)
+{
+  static_cast(__init_once);
+  static_cast(__context);
+
+  void (*init_routine)(void) = reinterpret_cast(__parameter);
+  init_routine();
+  return TRUE;
+}
+
+int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
+  void (*__init_routine)(void))
+{
+  if (!InitOnceExecuteOnce(__flag, __libcpp_init_once_execute_once_thunk,
+   reinterpret_cast(__init_routine), NULL))
+return GetLastError();
+  return 0;
+}
+
+// Thread ID
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+  __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// 

[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd marked an inline comment as done.
compnerd added inline comments.



Comment at: include/__threading_support:458
+   __libcpp_mutex_reference&& __m,
+   timespec* __ts)
+{

halyavin wrote:
> In posix, pthread_cond_timedwait uses absolute time but we use relative time 
> here.
Good catch.  I guess we have to convert the timespec to a relative time before 
using it.  Slightly annoying, but thankfully, we can fallback on chrono :-).


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated this revision to Diff 83178.
compnerd added a comment.

Address a number of review comments.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -47,6 +47,15 @@
 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#include 
+
+#include <__debug>
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -81,6 +90,29 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#else
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute Once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif
 
 // Mutex
@@ -342,6 +374,244 @@
 return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  TryEnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  TryAcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+   timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto timeout_ms = duration_cast(timeout);
+
+  _LIBCPP_ASSERT(timeout_ms.count() > INFINITE && "timeout duration overflow");
+  if (!SleepConditionVariableSRW(__cv, __m, timeout_ms.count(), 0))
+return GetLastError();
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
+{
+  static_cast(__cv);
+  return 0;
+}
+
+// Execute Once
+static inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK
+__libcpp_init_once_execute_once_thunk(PINIT_ONCE __init_once, PVOID __parameter,
+  PVOID *__context)
+{
+  static_cast(__init_once);
+  static_cast(__context);
+
+  void (*init_routine)(void) = reinterpret_cast(__parameter);
+  init_routine();
+  return TRUE;
+}
+
+int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
+  void (*__init_routine)(void))
+{
+  if (!InitOnceExecuteOnce(__flag, __libcpp_init_once_execute_once_thunk,
+   reinterpret_cast(__init_routine), NULL))
+return GetLastError();
+  return 0;
+}
+
+// Thread ID
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+  __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// Thread
+struct __libcpp_beginthreadex_thunk_data
+{
+  void *(*__func)(void *);
+  void *__arg;
+};
+
+static inline _LIBCPP_ALWAYS_INLINE unsigned int WINAPI

[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd marked 6 inline comments as done.
compnerd added inline comments.



Comment at: include/__threading_support:527
+static inline _LIBCPP_ALWAYS_INLINE unsigned int WINAPI
+__libcpp_thread_trampoline(void *__data)
+{

rnk wrote:
> halyavin wrote:
> > Trampolines will never be inlined. Should we put them in support *.cpp 
> > instead? The downside is new public symbols which can't be changed without 
> > breaking backward compatibility. The upside is that we will have only one 
> > copy of each trampoline. What do you think?
> Considering that libc++ already has a __thread_proxy trampoline, let's just 
> give it the right CC and get rid of this trampoline.
I think I prefer @rnk's solution here.  Lets try to use the `__thread_proxy` to 
hide the thunk.



Comment at: include/__threading_support:532
+  _VSTD::free(__data);
+  return reinterpret_cast(data.__func(data.__arg));
+}

halyavin wrote:
> Should we even try to pass thread exit code, given that sizeof(unsigned int) 
> < sizeof(void*) on 64-bit system? std::thread doesn't support thread exit 
> code anyway.
Im not sure what the cleanest way to address this is.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated the summary for this revision.
compnerd updated this revision to Diff 83174.

Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -47,6 +47,12 @@
 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#include 
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -81,6 +87,29 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#else
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute Once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif
 
 // Mutex
@@ -342,6 +371,247 @@
 return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
+{
+  EnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
+{
+  TryEnterCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
+{
+  LeaveCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  TryAcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+   timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto timeout_ms = duration_cast(timeout);
+
+  _LIBCPP_ASSERT(timeout_ms.count() < _VSTD::numeric_limits::max() &&
+ "timeout duration overflow");
+
+  if (!SleepConditionVariableSRW(__cv, __m, timeout_ms.count(), 0))
+return GetLastError();
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
+{
+  static_cast(__cv);
+  return 0;
+}
+
+// Execute Once
+static inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK
+__libcpp_init_once_execute_once_thunk(PINIT_ONCE InitOnce, PVOID Parameter,
+  PVOID *Context)
+{
+  static_cast(InitOnce);
+  static_cast(Context);
+
+  void (*init_routine)(void) = reinterpret_cast(Parameter);
+  init_routine();
+  return TRUE;
+}
+
+int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
+  void (*__init_routine)(void))
+{
+  if (!InitOnceExecuteOnce(__flag, __libcpp_init_once_execute_once_thunk,
+   reinterpret_cast(__init_routine), NULL))
+return GetLastError();
+  return 0;
+}
+
+// Thread ID
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+  __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// Thread
+struct __libcpp_beginthreadex_thunk_data
+{
+  void *(*__func)(void *);
+  void *__arg;
+};
+
+static inline _LIBCPP_ALWAYS_INLINE unsigned int WINAPI
+__libcpp_beginthreadex_thunk(void *__data)
+{
+ 

[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: include/__threading_support:44
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include 

kimgr wrote:
> EricWF wrote:
> > compnerd wrote:
> > > EricWF wrote:
> > > > Do these definitions have any affect when `` has already 
> > > > been included?
> > > > Also are these definitions required before including the header, or 
> > > > merely beneficial? If they are required this will make the 
> > > > `` header a pain to use with modules.
> > > > 
> > > > 
> > > No, they dont effect it once it has been included.  They are beneficial 
> > > since they reduce the amount of stuff that gets included (including 
> > > things which, at least when I last checked, can cause clang to choke).
> > And can users re-include `` afterwards in the same TU and get 
> > all of the symbols?
> I don't think so.
> 
> We've recently switched to defining these two symbols in our build system, 
> and I think that's basically the only way to make this work in a project 
> composed of headers from various authors. I think you're right that libc++ 
> should not define them.
I don't think libc++ should not include windows.h in a public header. I'd 
rather write our own __threading_support_win.h that re-prototypes everything we 
need from windows.h, and then we can have some test in libc++ that validates 
that there are no mismatches when including windows.h before libc++ . If 
we do this, we should sink as much win32 API usage as possible out of headers 
to reduce our duplication.

It's worth pointing out VS 2015's thread implementation also hides its win32 
API usage.



Comment at: include/__threading_support:527
+static inline _LIBCPP_ALWAYS_INLINE unsigned int WINAPI
+__libcpp_thread_trampoline(void *__data)
+{

halyavin wrote:
> Trampolines will never be inlined. Should we put them in support *.cpp 
> instead? The downside is new public symbols which can't be changed without 
> breaking backward compatibility. The upside is that we will have only one 
> copy of each trampoline. What do you think?
Considering that libc++ already has a __thread_proxy trampoline, let's just 
give it the right CC and get rid of this trampoline.



Comment at: include/__threading_support:593
+{
+  // TODO(compnerd) provide a wrapper for CC adjustment
+  *__key = FlsAlloc(reinterpret_cast(__at_exit));

Yeah, we need to fix that. We should find a way to make 
`__thread_specific_ptr::__at_thread_exit(void*)` have the right convention out 
of the box, rather than thunking. Something like:
  #define __LIBCPP_TLS_CALLBACK_CC WINAPI
  .. // else
  #define __LIBCPP_TLS_CALLBACK_CC
  ... // 
  static void __LIBCPP_TLS_CALLBACK_CC __at_thread_exit(void*);



Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-04 Thread Andrey Khalyavin via Phabricator via cfe-commits
halyavin added inline comments.



Comment at: include/__threading_support:458
+   __libcpp_mutex_reference&& __m,
+   timespec* __ts)
+{

In posix, pthread_cond_timedwait uses absolute time but we use relative time 
here.



Comment at: include/__threading_support:460
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);

We need to include  to use types and functions from this namespace.



Comment at: include/__threading_support:464
+
+  _LIBCPP_ASSERT(timeout_ms.count() < _VSTD::numeric_limits::max(),
+ "timeout duration overflows");

You have done it accidentally right. I realized there is a second problem here 
- if timeout equals to INFINITE, the thread will wait forever. INFINITE equals 
to (DWORD)-1, so the strict sign in the assert is required. But for sanity sake 
_VSTD::numeric_limits::max() should be replaced with INFINITE.  



Comment at: include/__threading_support:486
+static inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK
+__libcpp_init_once_trampoline(PINIT_ONCE InitOnce, PVOID Parameter,
+  PVOID *Context)

We need underscores for parameters and init_routine.



Comment at: include/__threading_support:497
+
+int __libcpp_execute_once(__libcpp_exec_once_flag* flag,
+  void (*init_routine)(void))

Underscores for parameters are missing.



Comment at: include/__threading_support:527
+static inline _LIBCPP_ALWAYS_INLINE unsigned int WINAPI
+__libcpp_thread_trampoline(void *__data)
+{

Trampolines will never be inlined. Should we put them in support *.cpp instead? 
The downside is new public symbols which can't be changed without breaking 
backward compatibility. The upside is that we will have only one copy of each 
trampoline. What do you think?



Comment at: include/__threading_support:531
+  *(__libcpp_thread_trampoline_data*)__data;
+  _VSTD::free(__data);
+  return reinterpret_cast(data.__func(data.__arg));

Do we need #include  for free() and malloc() now? Can we use 
new/delete instead?

BTW, What is the purpose of _VSTD? I think it is used to prevent 
argument-dependent lookup and so is not needed for free and malloc.



Comment at: include/__threading_support:532
+  _VSTD::free(__data);
+  return reinterpret_cast(data.__func(data.__arg));
+}

Should we even try to pass thread exit code, given that sizeof(unsigned int) < 
sizeof(void*) on 64-bit system? std::thread doesn't support thread exit code 
anyway.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-03 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated this revision to Diff 82954.
compnerd added a comment.

Remove incorrect use of `VC_EXTRALEAN`.  Fix signature for 
`__libcpp_set_thread_specific`.  Provide CC adjustment thunks for the thread 
creation.  Add an assertion for sleep timeout truncation.  Implement exec-once 
interfaces.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -43,10 +43,21 @@
 #include <__external_threading>
 #else
 
+#if !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) &&\
+!defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD) &&   \
+!defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#error "unknown threading model"
+#endif
+
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include 
+#include 
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -81,6 +92,29 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Execute once
+typedef INIT_ONCE __libcpp_exec_once_flag;
+#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif
 
 struct __libcpp_mutex_reference {
@@ -347,6 +381,236 @@
 return pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+EnterCriticalSection(__m);
+  else
+AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+return TryEnterCriticalSection(__m);
+  return TryAcquireSRWLockExclusive(__m);
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+LeaveCriticalSection(__m);
+  else
+ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_reference&& __m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t* __cv,
+  __libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+SleepConditionVariableCS(__cv, __m, INFINITE);
+  else
+SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv,
+   __libcpp_mutex_reference&& __m,
+   timespec* __ts)
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  auto timeout_ms = duration_cast(timeout);
+
+  _LIBCPP_ASSERT(timeout_ms.count() < _VSTD::numeric_limits::max(),
+ "timeout duration overflows");
+
+  if (__m.__recursive) {
+if (!SleepConditionVariableCS(__cv, __m, timeout_ms.count()))
+  return GetLastError();
+  } else {
+if (!SleepConditionVariableSRW(__cv, __m, timeout_ms.count(), 0))
+  return GetLastError();
+  }
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
+{
+  static_cast(__cv);
+  return 0;
+}
+
+// Execute once
+static inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK
+__libcpp_init_once_trampoline(PINIT_ONCE InitOnce, PVOID Parameter,
+  PVOID *Context)
+{
+  static_cast(InitOnce);
+  static_cast(Context);
+
+  void (*init_routine)(void) = reinterpret_cast(Parameter);
+  init_routine();
+  return TRUE;
+}
+
+int __libcpp_execute_once(__libcpp_exec_once_flag* flag,
+  void (*init_routine)(void))
+{
+  if (!InitOnceExecuteOnce(flag, __libcpp_init_once_trampoline,
+   reinterpret_cast(init_routine), NULL))
+return GetLastError();
+  

[PATCH] D28220: provide Win32 native threading

2017-01-03 Thread Andrey Khalyavin via Phabricator via cfe-commits
halyavin added inline comments.



Comment at: include/__threading_support:421
+if (!SleepConditionVariableCS(__cv, __m,
+  
duration_cast(timeout).count()))
+  return GetLastError();

We can have integer overflow on cast to DWORD here and get unexpectedly small 
wait for large timeouts.



Comment at: include/__threading_support:458
+{
+  // TODO(compnerd) provide a wrapper for CC adjustment
+  *__t = reinterpret_cast(_beginthreadex(

For other reviewers: CC means Calling Convention.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-03 Thread Kyrill Briantsev via Phabricator via cfe-commits
awson added a comment.

You don't need #define VC_EXTRA_LEAN since:

1. VC_EXTRA_LEAN is a mistype, only VC_EXTRALEAN has some meaning in Windows 
ecosystem;
2. VC_EXTRALEAN is used *only* in MFC headers which obviously aren't used in 
clang codebase.

Thus it would be better to remove this altogether, and (perhaps) replace with 
the relevant #define WIN32_LEAN_AND_MEAN.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-03 Thread Kim Gräsman via Phabricator via cfe-commits
kimgr added a comment.

Re Eric's windows.h concern.




Comment at: include/__threading_support:44
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include 

EricWF wrote:
> compnerd wrote:
> > EricWF wrote:
> > > Do these definitions have any affect when `` has already been 
> > > included?
> > > Also are these definitions required before including the header, or 
> > > merely beneficial? If they are required this will make the `` 
> > > header a pain to use with modules.
> > > 
> > > 
> > No, they dont effect it once it has been included.  They are beneficial 
> > since they reduce the amount of stuff that gets included (including things 
> > which, at least when I last checked, can cause clang to choke).
> And can users re-include `` afterwards in the same TU and get all 
> of the symbols?
I don't think so.

We've recently switched to defining these two symbols in our build system, and 
I think that's basically the only way to make this work in a project composed 
of headers from various authors. I think you're right that libc++ should not 
define them.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-03 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added inline comments.



Comment at: include/__threading_support:44
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include 

compnerd wrote:
> EricWF wrote:
> > Do these definitions have any affect when `` has already been 
> > included?
> > Also are these definitions required before including the header, or merely 
> > beneficial? If they are required this will make the `` header a 
> > pain to use with modules.
> > 
> > 
> No, they dont effect it once it has been included.  They are beneficial since 
> they reduce the amount of stuff that gets included (including things which, 
> at least when I last checked, can cause clang to choke).
And can users re-include `` afterwards in the same TU and get all of 
the symbols?


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added inline comments.



Comment at: include/__threading_support:46
+inline _LIBCPP_INLINE_VISIBILITY
+int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m);
+

EricWF wrote:
> The forward declarations of the `__libcpp_` threading wrapper should be 
> shared between all API's. Please don't add your own forward declarations for 
> Windows. 
Yeah, restructed that.  There is now the dependent patch for the type-erased 
mutex handling.



Comment at: include/__threading_support:44
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include 

EricWF wrote:
> Do these definitions have any affect when `` has already been 
> included?
> Also are these definitions required before including the header, or merely 
> beneficial? If they are required this will make the `` header a 
> pain to use with modules.
> 
> 
No, they dont effect it once it has been included.  They are beneficial since 
they reduce the amount of stuff that gets included (including things which, at 
least when I last checked, can cause clang to choke).


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated this revision to Diff 82846.
compnerd added a comment.

add more context


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -32,9 +32,20 @@
 #include <__external_threading>
 #else
 
+#if !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) &&\
+!defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#error "unknown threading model"
+#endif
+
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include 
+#include 
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -64,6 +75,25 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif
 
 struct __libcpp_mutex_reference {
@@ -306,6 +336,192 @@
   pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+EnterCriticalSection(__m);
+  else
+AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+return TryEnterCriticalSection(__m);
+  return TryAcquireSRWLockExclusive(__m);
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+LeaveCriticalSection(__m);
+  else
+ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_reference&& __m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t* __cv,
+  __libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+SleepConditionVariableCS(__cv, __m, INFINITE);
+  else
+SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv,
+   __libcpp_mutex_reference&& __m,
+   timespec* __ts)
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+
+  // TODO(compnerd) handle timeouts < 10ms
+  if (__m.__recursive) {
+if (!SleepConditionVariableCS(__cv, __m,
+  duration_cast(timeout).count()))
+  return GetLastError();
+  } else {
+if (!SleepConditionVariableSRW(__cv, __m,
+   duration_cast(timeout).count(),
+   0))
+  return GetLastError();
+  }
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
+{
+  static_cast(__cv);
+  return 0;
+}
+
+// Thread ID
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+  __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// Thread
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*),
+   void* __arg)
+{
+  // TODO(compnerd) provide a wrapper for CC adjustment
+  *__t = reinterpret_cast(_beginthreadex(
+  NULL, 0, (unsigned int(WINAPI*)(void*))__func, __arg, 0, NULL));
+  if (*__t)
+return 0;
+  return GetLastError();
+}
+
+_LIBCPP_ALWAYS_INLINE
+__libcpp_thread_id __libcpp_thread_get_current_id()
+{
+  return GetCurrentThreadId();
+}
+
+_LIBCPP_ALWAYS_INLINE
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
+{
+  return GetThreadId(*__t);
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_join(__libcpp_thread_t* __t)
+{
+  if (WaitForSingleObjectEx(*__t, INFINITE, FALSE) 

[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated this revision to Diff 82843.
compnerd added a comment.

update for separation of mutex and recursive_mutex.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -32,9 +32,20 @@
 #include <__external_threading>
 #else
 
+#if !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) &&\
+!defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#error "unknown threading model"
+#endif
+
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include 
+#include 
+#include 
 #endif
 
 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -64,6 +75,25 @@
 
 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+typedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif
 
 struct __libcpp_mutex_reference {
@@ -306,6 +336,192 @@
   pthread_setspecific(__key, __p);
 }
 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m)
+{
+  InitializeCriticalSection(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+EnterCriticalSection(__m);
+  else
+AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+return TryEnterCriticalSection(__m);
+  return TryAcquireSRWLockExclusive(__m);
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+LeaveCriticalSection(__m);
+  else
+ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_reference&& __m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t* __cv,
+  __libcpp_mutex_reference&& __m)
+{
+  if (__m.__recursive)
+SleepConditionVariableCS(__cv, __m, INFINITE);
+  else
+SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv,
+   __libcpp_mutex_reference&& __m,
+   timespec* __ts)
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+
+  // TODO(compnerd) handle timeouts < 10ms
+  if (__m.__recursive) {
+if (!SleepConditionVariableCS(__cv, __m,
+  duration_cast(timeout).count()))
+  return GetLastError();
+  } else {
+if (!SleepConditionVariableSRW(__cv, __m,
+   duration_cast(timeout).count(),
+   0))
+  return GetLastError();
+  }
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
+{
+  static_cast(__cv);
+  return 0;
+}
+
+// Thread ID
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+  __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// Thread
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*),
+   void* __arg)
+{
+  // TODO(compnerd) provide a wrapper for CC adjustment
+  *__t = reinterpret_cast(_beginthreadex(
+  NULL, 0, (unsigned int(WINAPI*)(void*))__func, __arg, 0, NULL));
+  if (*__t)
+return 0;
+  return GetLastError();
+}
+
+_LIBCPP_ALWAYS_INLINE
+__libcpp_thread_id __libcpp_thread_get_current_id()
+{
+  return GetCurrentThreadId();
+}
+
+_LIBCPP_ALWAYS_INLINE
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
+{
+  return GetThreadId(*__t);
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_join(__libcpp_thread_t* __t)
+{
+  if 

[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai added inline comments.



Comment at: include/__threading_support:300-305
+int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m)
+{
+  InitializeSRWLock(__m);
+  return 0;
+}
+

majnemer wrote:
> compnerd wrote:
> > majnemer wrote:
> > > I don't think you can use slim rw locks for recursive locks. I think we 
> > > will need to use `CRITICAL_SECTION` for those. std::recursive_mutex can't 
> > > be used with std::condition_variable AFAIK so all you need (I think) is 
> > > recursive versions of `__libcpp_mutex_...`
> > > 
> > > Recursive locks should be used far less frequently which makes it 
> > > valuable, IMO, to use slim rw locks for the non-recursive mutex 
> > > implementation.
> > You are absolutely right.  That was something that I looked at originally 
> > and went with the CS.  However, the overhead of a tagged struct is 5 or 9 
> > bytes (sizeof(void *) + 1) bytes (ignoring padding for MS ABI).  Going with 
> > that should give the benefits of always being able to properly initialize 
> > the CS instead of the kludge.
> Er, isn't the overhead much more than that? IIRC, `CRITICAL_SECTION` is quite 
> large. You'd be making all the users of `std::mutex` pay for the space of 
> `std::recursive_mutex`...
Yeah, CRITICAL_SECTION is 24 bytes vs 4 bytes for a SRWLOCK.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai added inline comments.



Comment at: include/__threading_support:83
+} __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER {{0}, SRWLOCK_INIT, 0}
+

Why not a tagged union?


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread David Majnemer via Phabricator via cfe-commits
majnemer added inline comments.



Comment at: include/__threading_support:300-305
+int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m)
+{
+  InitializeSRWLock(__m);
+  return 0;
+}
+

compnerd wrote:
> majnemer wrote:
> > I don't think you can use slim rw locks for recursive locks. I think we 
> > will need to use `CRITICAL_SECTION` for those. std::recursive_mutex can't 
> > be used with std::condition_variable AFAIK so all you need (I think) is 
> > recursive versions of `__libcpp_mutex_...`
> > 
> > Recursive locks should be used far less frequently which makes it valuable, 
> > IMO, to use slim rw locks for the non-recursive mutex implementation.
> You are absolutely right.  That was something that I looked at originally and 
> went with the CS.  However, the overhead of a tagged struct is 5 or 9 bytes 
> (sizeof(void *) + 1) bytes (ignoring padding for MS ABI).  Going with that 
> should give the benefits of always being able to properly initialize the CS 
> instead of the kludge.
Er, isn't the overhead much more than that? IIRC, `CRITICAL_SECTION` is quite 
large. You'd be making all the users of `std::mutex` pay for the space of 
`std::recursive_mutex`...


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

Could you upload this patch with more context?


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated this revision to Diff 82834.
compnerd added a comment.

switch between a CRITICAL_SECTION and SRWLOCK


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -32,9 +32,20 @@
 #include <__external_threading>
 #else

+#if !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) &&\
+!defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#error "unknown threading model"
+#endif
+
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include 
+#include 
+#include 
 #endif

 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -62,6 +73,28 @@

 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+// Mutex
+typedef struct {
+  CRITICAL_SECTION __mutex;
+  SRWLOCK __lock;
+  unsigned char __use_mutex : 1;
+  unsigned char __reserved : 7;
+} __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER {{0}, SRWLOCK_INIT, 0}
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif

 // Mutex
@@ -267,6 +300,192 @@
   pthread_setspecific(__key, __p);
 }

+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
+{
+  if (__m->__use_mutex)
+return 0;
+  InitializeCriticalSection(&__m->__mutex);
+  __m->__use_mutex = 1;
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
+{
+  if (__m->__use_mutex)
+EnterCriticalSection(&__m->__mutex);
+  else
+AcquireSRWLockExclusive(&__m->__lock);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
+{
+  if (__m->__use_mutex)
+return TryEnterCriticalSection(&__m->__mutex);
+  return TryAcquireSRWLockExclusive(&__m->__lock);
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
+{
+  if (__m->__use_mutex)
+LeaveCriticalSection(&__m->__mutex);
+  else
+ReleaseSRWLockExclusive(&__m->__lock);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
+{
+  if (__m->__use_mutex)
+SleepConditionVariableCS(__cv, &__m->__mutex, INFINITE);
+  else
+SleepConditionVariableSRW(__cv, &__m->__lock, INFINITE, 0);
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m,
+   timespec* __ts)
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  if (__m->__use_mutex) {
+if (!SleepConditionVariableCS(__cv, &__m->__mutex,
+  duration_cast(timeout).count()))
+  return GetLastError();
+  } else {
+// TODO(compnerd) handle timeouts < 10ms
+if (!SleepConditionVariableSRW(__cv, &__m->__lock,
+   duration_cast(timeout).count(),
+   0))
+  return GetLastError();
+  }
+  return 0;
+}
+
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
+{
+  static_cast(__cv);
+  return 0;
+}
+
+// Thread ID
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+  __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+_LIBCPP_ALWAYS_INLINE
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// Thread
+_LIBCPP_ALWAYS_INLINE
+int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*),
+   void* __arg)
+{
+  // TODO(compnerd) provide a wrapper for CC adjustment
+  *__t = reinterpret_cast(_beginthreadex(
+  NULL, 0, (unsigned int(WINAPI*)(void*))__func, __arg, 0, NULL));
+  if (*__t)
+return 0;
+  return GetLastError();
+}
+
+_LIBCPP_ALWAYS_INLINE
+__libcpp_thread_id __libcpp_thread_get_current_id()
+{
+  return GetCurrentThreadId();
+}
+
+_LIBCPP_ALWAYS_INLINE
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
+{
+  return GetThreadId(*__t);
+}
+

[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added inline comments.



Comment at: include/__threading_support:300-305
+int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m)
+{
+  InitializeSRWLock(__m);
+  return 0;
+}
+

majnemer wrote:
> I don't think you can use slim rw locks for recursive locks. I think we will 
> need to use `CRITICAL_SECTION` for those. std::recursive_mutex can't be used 
> with std::condition_variable AFAIK so all you need (I think) is recursive 
> versions of `__libcpp_mutex_...`
> 
> Recursive locks should be used far less frequently which makes it valuable, 
> IMO, to use slim rw locks for the non-recursive mutex implementation.
You are absolutely right.  That was something that I looked at originally and 
went with the CS.  However, the overhead of a tagged struct is 5 or 9 bytes 
(sizeof(void *) + 1) bytes (ignoring padding for MS ABI).  Going with that 
should give the benefits of always being able to properly initialize the CS 
instead of the kludge.



Comment at: include/__threading_support:355
+  // TODO(compnerd) handle spurious timeout
+  if (!SleepConditionVariableSRW(__cv, __m,
+ duration_cast(timeout).count(),

majnemer wrote:
> I don't think it should be `__libcpp_condvar_timedwait'`s problem. 
> `__libcpp_condvar_timedwait` wraps `pthread_cond_timedwait` on POSIX 
> platforms and the caller of `__libcpp_condvar_wait` properly handles spurious 
> wakeups. The caller of `__libcpp_condvar_timedwait` probably should be 
> audited.
SG; seems that there is a single user in condition_variable.cpp


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd updated this revision to Diff 82826.
compnerd added a comment.

Use SRW locks, rebase for avoid redeclaration of interfaces, remove static 
initialization check removals.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220

Files:
  include/__config
  include/__threading_support

Index: include/__threading_support
===
--- include/__threading_support
+++ include/__threading_support
@@ -32,9 +32,20 @@
 #include <__external_threading>
 #else

+#if !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) &&\
+!defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#error "unknown threading model"
+#endif
+
 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
 #include 
 #include 
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRA_LEAN
+#include 
+#include 
+#include 
 #endif

 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
@@ -62,6 +73,23 @@

 // Thrad Local Storage
 typedef pthread_key_t __libcpp_tls_key;
+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+// Mutex
+typedef SRWLOCK __libcpp_mutex_t;
+#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
+
+// Condition Variable
+typedef CONDITION_VARIABLE __libcpp_condvar_t;
+#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
+
+// Thread ID
+typedef DWORD __libcpp_thread_id;
+
+// Thread
+typedef HANDLE __libcpp_thread_t;
+
+// Thread Local Storage
+typedef DWORD __libcpp_tls_key;
 #endif

 // Mutex
@@ -267,6 +295,150 @@
   pthread_setspecific(__key, __p);
 }

+#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
+
+// Mutex
+int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m)
+{
+  InitializeSRWLock(__m);
+  return 0;
+}
+
+int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
+{
+  AcquireSRWLockExclusive(__m);
+  return 0;
+}
+
+int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
+{
+  return TryAcquireSRWLockExclusive(__m);
+}
+
+int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
+{
+  ReleaseSRWLockExclusive(__m);
+  return 0;
+}
+
+int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
+{
+  static_cast(__m);
+  return 0;
+}
+
+// Condition Variable
+int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
+{
+  WakeConditionVariable(__cv);
+  return 0;
+}
+
+int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
+{
+  WakeAllConditionVariable(__cv);
+  return 0;
+}
+
+int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
+{
+  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
+  return 0;
+}
+
+int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
+   timespec *__ts)
+{
+  using namespace _VSTD::chrono;
+  auto timeout = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
+  // TODO(compnerd) handle timeouts < 10ms
+  // TODO(compnerd) handle spurious timeout
+  if (!SleepConditionVariableSRW(__cv, __m,
+ duration_cast(timeout).count(),
+ 0))
+return GetLastError();
+  return 0;
+}
+
+int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
+{
+  static_cast(__cv);
+  return 0;
+}
+
+// Thread ID
+bool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
+  __libcpp_thread_id __rhs)
+{
+  return __lhs == __rhs;
+}
+
+bool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
+{
+  return __lhs < __rhs;
+}
+
+// Thread
+int __libcpp_thread_create(__libcpp_thread_t *__t,
+   unsigned int (* WINAPI __func)(void *), void *__arg)
+{
+  *__t =
+  reinterpret_cast(_beginthreadex(NULL, 0, __func, __arg, 0, NULL));
+  if (*__t)
+return 0;
+  return GetLastError();
+}
+
+__libcpp_thread_id __libcpp_thread_get_current_id()
+{
+  return GetCurrentThreadId();
+}
+
+__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
+{
+  return GetThreadId(*__t);
+}
+
+int __libcpp_thread_join(__libcpp_thread_t *__t)
+{
+  if (WaitForSingleObjectEx(*__t, INFINITE, FALSE) == WAIT_FAILED)
+return GetLastError();
+  if (!CloseHandle(*__t))
+return GetLastError();
+  return 0;
+}
+
+int __libcpp_thread_detach(__libcpp_thread_t *__t)
+{
+  if (!CloseHandle(*__t))
+return GetLastError();
+  return 0;
+}
+
+void __libcpp_thread_yield()
+{
+  SwitchToThread();
+}
+
+// Thread Local Storage
+int __libcpp_tls_create(__libcpp_tls_key *__key, void (* WINAPI __at_exit)(void *))
+{
+  *__key = FlsAlloc(__at_exit);
+  if (*__key == FLS_OUT_OF_INDEXES)
+return GetLastError();
+  return 0;
+}
+
+void *__libcpp_tls_get(__libcpp_tls_key __key)
+{
+  return FlsGetValue(__key);
+}
+
+void __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
+{
+  FlsSetValue(__key, __p);
+}
+
 #endif // _LIBCPP_HAS_THREAD_API_PTHREAD

 _LIBCPP_END_NAMESPACE_STD
Index: include/__config
===
--- include/__config
+++ include/__config
@@ -882,6 +882,8 @@
 defined(__CloudABI__) || \
 defined(__sun__)
 #  define 

[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd marked 3 inline comments as done.
compnerd added a comment.

The SRW initializers avoid the initializer changes, so its one less set of 
changes that is necessary.




Comment at: include/__threading_support:33
 #include <__external_threading>
+#elif defined(_WIN32) && defined(_LIBCPP_HAS_THREAD_API_WIN32)
+#define WIN32_LEAN_AND_MEAN

EricWF wrote:
> Isn't checking `_LIBCPP_HAS_THREAD_API_WIN32` enough?
No, because the structure of the header is such that it requires redeclarations 
:-(.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread David Majnemer via Phabricator via cfe-commits
majnemer added a comment.

In https://reviews.llvm.org/D28220#633622, @compnerd wrote:

> @majnemer Im using the Fls* APIs since they provide the thread termination 
> callback, which Tls* doesn't.  Good point about the SRW.  Those are newer, 
> but, we can always provide a fallback later.


I don't believe they are newer than the condition variable API so all should be 
fine.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added a comment.

@majnemer Im using the Fls* APIs since they provide the thread termination 
callback, which Tls* doesn't.  Good point about the SRW.  Those are newer, but, 
we can always provide a fallback later.


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28220: provide Win32 native threading

2017-01-02 Thread David Majnemer via Phabricator via cfe-commits
majnemer added a comment.

slim reader-writer locks are faster than critical sections, I'd recommend your 
implementation switch to those.

Also, why do you use Fls instead of Tls?


Repository:
  rL LLVM

https://reviews.llvm.org/D28220



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits