[cfe-dev] [PATCH] Libc++ Windows fixes
Ruben Van Boxem
vanboxem.ruben at gmail.com
Sun Nov 27 06:28:40 PST 2011
Hi,
I've been cracking at it again, and came up with the attached patch to
let libc++ play nice with MSVC (or is it the other way around?).
I created a new __config macro: _LIBCPP_HAS_BROKEN_DECLTYPE, which is
defined for MSVC, and disables any functionality dependent on the
functionality broken in MSVC 10 (and probably 11). This is all the
__is_constructible stuff, and unfortunately this leads to other places
this macro pops up.
The good news: I've gotten through <type_traits>, adding the _MSC_VER
checks alongside the already existing Clang and GCC checks. Perhaps a
better way to handle this would be two new config macros:
_LIBCPP_HAS_NOTHROW_INTRINSICS and _LIBCPP_HAS_TRIVIAL_INTRINSICS (not
*_TYPE_TRAITS, as that's confusing, the type_traits stuff will always
be present). I can fix that if that sounds sensible. The
__is_standard_layout and __is_trivial are really just MSVC's __is_pod,
I don't know how conformant this will be untill I am able to run the
tests.
The bad news: I've run into another language incompatibility, namely
MSVC not allowing template function default template-arguments. I've
looked in C++03 and my C++11 FDIS, and there's indeed a difference,
and it is allowed in C++11 as far as I can see. But of course MSVC
doesn't allow it. I believe I can disable the error (which seems to be
a warning emitted by default as an error:
http://msdn.microsoft.com/en-us/library/190h9wbh(v=VS.100).aspx), but
I'm not sure if it'll have the wanted behavior (the default argument
will be ignored).
Comments and commits are welcome!
Ruben
-------------- next part --------------
Index: include/pthread_compat.h
===================================================================
--- include/pthread_compat.h (revision 0)
+++ include/pthread_compat.h (revision 0)
@@ -0,0 +1,76 @@
+/*
+ Copyright (c) 2011 mingw-w64 project
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+/*
+ * Parts of this library are derived by:
+ *
+ * Posix Threads library for Microsoft Windows
+ *
+ * Use at own risk, there is no implied warranty to this code.
+ * It uses undocumented features of Microsoft Windows that can change
+ * at any time in the future.
+ *
+ * (C) 2010 Lockless Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of Lockless Inc. nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WIN_PTHREADS_PTHREAD_COMPAT_H
+#define WIN_PTHREADS_PTHREAD_COMPAT_H
+
+#ifdef _MSC_VER
+
+#include "pthread_time.h"
+
+typedef __int64 pid_t;
+typedef int clockid_t;
+
+#define inline __inline
+#define __attribute__(X) __declspec X
+#define __section__(X) allocate(X)
+
+#endif
+
+#endif
Index: include/pthread.h
===================================================================
--- include/pthread.h (revision 4641)
+++ include/pthread.h (working copy)
@@ -69,6 +69,8 @@
#include <sys/timeb.h>
+#include "pthread_compat.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -301,7 +303,7 @@
pthread_t WINPTHREAD_API pthread_self(void);
int WINPTHREAD_API pthread_get_concurrency(int *val);
int WINPTHREAD_API pthread_set_concurrency(int val);
-int WINPTHREAD_API pthread_exit(void *res);
+void WINPTHREAD_API pthread_exit(void *res);
void WINPTHREAD_API _pthread_invoke_cancel(void);
void WINPTHREAD_API pthread_testcancel(void);
int WINPTHREAD_API pthread_cancel(pthread_t t);
Index: src/misc.h
===================================================================
--- src/misc.h (revision 4641)
+++ src/misc.h (working copy)
@@ -23,6 +23,8 @@
#ifndef WIN_PTHREADS_MISC_H
#define WIN_PTHREADS_MISC_H
+#include "pthread_compat.h"
+
#ifndef assert
#ifndef ASSERT_TRACE
Index: src/mutex.c
===================================================================
--- src/mutex.c (revision 4641)
+++ src/mutex.c (working copy)
@@ -249,6 +249,7 @@
{
unsigned long long t, ct;
int r;
+ mutex_t *_m;
if (!ts) return pthread_mutex_lock(m);
r = mutex_ref(m);
@@ -258,7 +259,7 @@
r=_mutex_trylock(m);
if (r != EBUSY) return mutex_unref(m,r);
- mutex_t *_m = (mutex_t *)*m;
+ _m = (mutex_t *)*m;
if (_m->type != PTHREAD_MUTEX_NORMAL && COND_LOCKED(_m) && COND_OWNER(_m))
return mutex_unref(m,EDEADLK);
ct = _pthread_time_in_ms();
@@ -269,11 +270,12 @@
}
int pthread_mutex_unlock(pthread_mutex_t *m)
-{
+{
+ mutex_t *_m;
int r = mutex_ref_unlock(m);
if(r) return r;
- mutex_t *_m = (mutex_t *)*m;
+ _m = (mutex_t *)*m;
if (_m->type == PTHREAD_MUTEX_NORMAL)
{
if (!COND_LOCKED(_m))
@@ -383,13 +385,14 @@
int pthread_mutex_destroy(pthread_mutex_t *m)
{
+ mutex_t *_m;
pthread_mutex_t mDestroy;
int r = mutex_ref_destroy(m,&mDestroy);
if(r) return r;
if(!mDestroy) return 0; /* destroyed a (still) static initialized mutex */
/* now the mutex is invalid, and no one can touch it */
- mutex_t *_m = (mutex_t *)mDestroy;
+ _m = (mutex_t *)mDestroy;
CloseHandle(_m->h);
Index: src/thread.c
===================================================================
--- src/thread.c (revision 4641)
+++ src/thread.c (working copy)
@@ -322,6 +322,8 @@
__dyn_tls_pthread (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
{
_pthread_v *t = NULL;
+ spin_t new_spin_keys = {0, LIFE_SPINLOCK, 1};
+
if (dwReason == DLL_PROCESS_DETACH)
{
free_pthread_mem ();
@@ -342,7 +344,7 @@
t->h = NULL;
}
pthread_mutex_destroy (&t->p_clock);
- t->spin_keys = (spin_t) {0,LIFE_SPINLOCK, 1};
+ t->spin_keys = new_spin_keys;
push_pthread_mem (t);
t = NULL;
TlsSetValue (_pthread_tls, t);
@@ -365,7 +367,7 @@
TlsSetValue (_pthread_tls, t);
}
pthread_mutex_destroy(&t->p_clock);
- t->spin_keys = (spin_t) {0,LIFE_SPINLOCK, 1};
+ t->spin_keys = new_spin_keys;
}
else if (t)
{
@@ -373,14 +375,20 @@
CloseHandle (t->evStart);
t->evStart = NULL;
pthread_mutex_destroy (&t->p_clock);
- t->spin_keys = (spin_t) {0,LIFE_SPINLOCK,1};
+ t->spin_keys = new_spin_keys;
}
}
return TRUE;
}
/* TLS-runtime section variable. */
-PIMAGE_TLS_CALLBACK __xl_f __attribute__ ((section (".CRT$XLF"))) = (PIMAGE_TLS_CALLBACK) __dyn_tls_pthread;
+#ifdef _MSC_VER
+#pragma section(".CRT$XLF", shared)
+#endif
+PIMAGE_TLS_CALLBACK __attribute__ ((__section__ (".CRT$XLF"))) __xl_f = (PIMAGE_TLS_CALLBACK) __dyn_tls_pthread;
+#ifdef _MSC_VER
+#pragma data_seg()
+#endif
#ifdef WINPTHREAD_DBG
static int print_state = 0;
@@ -858,6 +866,7 @@
__pthread_self_lite (void)
{
_pthread_v *t;
+ spin_t new_spin_keys = {0,LIFE_SPINLOCK,1};
_pthread_once_raw (&_pthread_tls_once, pthread_tls_init);
@@ -875,7 +884,7 @@
t->tid = GetCurrentThreadId();
t->evStart = CreateEvent (NULL, 1, 0, NULL);
t->p_clock = PTHREAD_MUTEX_INITIALIZER;
- t->spin_keys = (spin_t) {0,LIFE_SPINLOCK,1};
+ t->spin_keys = new_spin_keys;
t->sched_pol = SCHED_OTHER;
t->h = NULL; //GetCurrentThread();
if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &t->h, 0, FALSE, DUPLICATE_SAME_ACCESS))
@@ -939,16 +948,13 @@
return 0;
}
-int
+void
pthread_exit (void *res)
{
_pthread_v *t = NULL;
unsigned rslt = (unsigned) ((intptr_t) res);
struct _pthread_v *id = __pthread_self_lite ();
- if (!id)
- return EINVAL;
-
id->ret_arg = res;
_pthread_cleanup_dest (id->x);
@@ -994,9 +1000,9 @@
void
_pthread_invoke_cancel (void)
{
+ _pthread_cleanup *pcup;
struct _pthread_v *se = __pthread_self_lite ();
se->in_cancel = 1;
- _pthread_cleanup *pcup;
_pthread_setnobreak (1);
InterlockedDecrement(&_pthread_cancelling);
@@ -1410,6 +1416,7 @@
int redo = 0;
struct _pthread_v *tv;
size_t ssize = 0;
+ spin_t new_spin_keys = {0,LIFE_SPINLOCK,1};
if ((tv = pop_pthread_mem ()) == NULL)
return EAGAIN;
@@ -1434,7 +1441,7 @@
while (++redo <= 4);
tv->p_clock = PTHREAD_MUTEX_INITIALIZER;
- tv->spin_keys = (spin_t) {0,LIFE_SPINLOCK,1};
+ tv->spin_keys = new_spin_keys;
tv->valid = LIFE_THREAD;
tv->sched.sched_priority = THREAD_PRIORITY_NORMAL;
tv->sched_pol = SCHED_OTHER;
@@ -1472,7 +1479,7 @@
if (tv->evStart)
CloseHandle (tv->evStart);
pthread_mutex_destroy (&tv->p_clock);
- tv->spin_keys = (spin_t) {0,LIFE_SPINLOCK,1};
+ tv->spin_keys = new_spin_keys;
tv->evStart = NULL;
if (th)
memset(th,0, sizeof (pthread_t));
@@ -1513,6 +1520,7 @@
{
DWORD dwFlags;
struct _pthread_v *tv = __pth_gpointer_locked (t);
+ spin_t new_spin_keys = {0,LIFE_SPINLOCK,1};
if (!tv || tv->h == NULL || !GetHandleInformation(tv->h, &dwFlags))
return ESRCH;
@@ -1533,7 +1541,7 @@
if (res)
*res = tv->ret_arg;
pthread_mutex_destroy (&tv->p_clock);
- tv->spin_keys = (spin_t) {0,LIFE_SPINLOCK,1};
+ tv->spin_keys = new_spin_keys;
push_pthread_mem (tv);
return 0;
@@ -1544,6 +1552,7 @@
{
DWORD dwFlags;
struct _pthread_v *tv;
+ spin_t new_spin_keys = {0,LIFE_SPINLOCK,1};
pthread_mutex_lock (&mtx_pthr_locked);
tv = __pth_gpointer_locked (t);
@@ -1582,7 +1591,7 @@
if (res)
*res = tv->ret_arg;
pthread_mutex_destroy (&tv->p_clock);
- tv->spin_keys = (spin_t) {0,LIFE_SPINLOCK,1};
+ tv->spin_keys = new_spin_keys;
push_pthread_mem (tv);
@@ -1598,6 +1607,7 @@
DWORD dwFlags;
struct _pthread_v *tv = __pth_gpointer_locked (t);
HANDLE dw;
+ spin_t new_spin_keys = {0,LIFE_SPINLOCK,1};
pthread_mutex_lock (&mtx_pthr_locked);
if (!tv || tv->h == NULL || !GetHandleInformation(tv->h, &dwFlags))
@@ -1624,7 +1634,7 @@
CloseHandle (tv->evStart);
tv->evStart = NULL;
pthread_mutex_destroy (&tv->p_clock);
- tv->spin_keys = (spin_t) {0,LIFE_SPINLOCK,1};
+ tv->spin_keys = new_spin_keys;
push_pthread_mem (tv);
}
}
Index: src/cond.c
===================================================================
--- src/cond.c (revision 4641)
+++ src/cond.c (working copy)
@@ -36,6 +36,8 @@
#include "misc.h"
#include "winpthread_internal.h"
+#include "pthread_compat.h"
+
int __pthread_shallcancel (void);
static int do_sema_b_wait (HANDLE sema, int nointerrupt, DWORD timeout,CRITICAL_SECTION *cs, LONG *val);
Index: src/sem.c
===================================================================
--- src/sem.c (revision 4641)
+++ src/sem.c (working copy)
@@ -214,7 +214,7 @@
int cur_v, ret = 0;
DWORD dwr;
HANDLE semh;
- _sem_t *sv;;
+ _sem_t *sv;
struct sSemTimedWait arg;
if (!t)
@@ -327,7 +327,7 @@
int
sem_getvalue (sem_t *sem, int *sval)
{
- _sem_t *sv;;
+ _sem_t *sv;
int r;
if (!sval)
Index: src/barrier.c
===================================================================
--- src/barrier.c (revision 4641)
+++ src/barrier.c (working copy)
@@ -90,12 +90,13 @@
int pthread_barrier_destroy(pthread_barrier_t *b_)
{
pthread_barrier_t bDestroy;
+ barrier_t *b;
int r = barrier_ref_destroy(b_,&bDestroy);
if (r)
return r;
- barrier_t *b = (barrier_t *)bDestroy;
+ b = (barrier_t *)bDestroy;
pthread_mutex_lock(&b->m);
@@ -174,11 +175,12 @@
{
long sel;
int r, e, rslt;
+ barrier_t *b;
r = barrier_ref(b_);
if(r) return r;
- barrier_t *b = (barrier_t *)*b_;
+ b = (barrier_t *)*b_;
if ((r = pthread_mutex_lock(&b->m))) return barrier_unref(b_,EINVAL);
sel = b->sel;
Index: src/clock.c
===================================================================
--- src/clock.c (revision 4641)
+++ src/clock.c (working copy)
@@ -9,6 +9,8 @@
#include <time.h>
#include <windows.h>
+#include "pthread.h"
+
#define POW10_7 10000000
#define POW10_9 1000000000
More information about the cfe-dev
mailing list