From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mumit Khan To: pthreads-win32@sourceware.cygnus.com Subject: (patch) Mingw32 support Date: Mon, 08 Nov 1999 02:55:00 -0000 Message-id: <199911081055.EAA30617@mercury.xraylith.wisc.edu> X-SW-Source: 1999/msg00120.html I finally released the thread-safe C++ EH support for Mingw, and with the following patch, the MSVCRT version passes all the tests. 98% of the patch is removing Mingw specific hacks (due to bugs in sys/timeb.h), and the remaining is to account for limitations of CRTDLL runtime, which is somewhat braindead when it comes to MT code, especially on Win9x. Note the -mthreads option, analogous to what's used on AIX. C++ code requiring thread-safe EH must compile *and* link with this option. This makes your final executable dependent on a Mingw runtime DLL (for CRTDLL, it's mingwc10.dll; for MSVCRT, mingwm10.dll). When compiking, it defines _MT; when linking, it links against libmingwthrd.a, the thread support library that cleans up the exception objects created by EH support routines in GCC. Use the -v option (or look at GCC specs file) to see what it does if curious. Without -mthreads, you don't get the thread helper DLL that causes trouble and you *will* get segfaults seemingly at random. http://www.xraylith.wisc.edu/~khan/software/gnu-win32/ for gcc-2.95.2 binaries that include the latest Mingw runtime that you need for this. You can download either the CRTDLL ("classic") or the MSVCRT version; both can coexist, as long as you install each to its own directory. Notes for Win9x: Thread support in CRTDLL runtime is somewhat braindead on Win9x, so caveat emptore. I recommend using *only* the MSVCRT version if you're developing with threads, even if using windows32 directly. Patch against CVS tree as of this evening (Nov 8, 1999). Mon Nov 8 04:40:29 1999 Mumit Khan * Makefile.in (LD): Add -mthreads option for GCC/Mingw. (CFLAGS): Likewise. * private.c: Remove Mingw bug workaround. * thread.h: Likewise. * tests/condvar2.c: Likewise. * tests/condvar3.c: Likewise. * tests/condvar4.c: Likewise. * tests/condvar5.c: Likewise. * tests/condvar6.c: Likewise. * tests/condvar7.c: Likewise. * tests/condvar8.c: Likewise. * tests/condvar9.c: Likewise. * tests/count1.c (NUMTHREADS): Adjust for Mingw/CRTDLL runtime. * tests/join2.c (main): Likewise. Index: Makefile.in =================================================================== RCS file: /cvs/pthreads-win32/pthreads/Makefile.in,v retrieving revision 1.10 diff -u -3 -p -r1.10 Makefile.in --- Makefile.in 1999/09/15 00:56:22 1.10 +++ Makefile.in 1999/11/08 10:40:09 @@ -24,12 +24,12 @@ CC = g++ AR = ar -LD = gcc -mdll +LD = gcc -mdll -mthreads OPT = -g -O2 ## Mingw32 -CFLAGS = $(OPT) -I. -DHAVE_CONFIG_H -Wall +CFLAGS = $(OPT) -I. -DHAVE_CONFIG_H -Wall -mthreads ## Cygwin G++ #CFLAGS = $(OPT) -fhandle-exceptions -I. -DHAVE_CONFIG_H -Wall Index: private.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/private.c,v retrieving revision 1.41 diff -u -3 -p -r1.41 private.c --- private.c 1999/11/04 17:18:43 1.41 +++ private.c 1999/11/08 10:40:09 @@ -686,15 +686,9 @@ _pthread_sem_timedwait (sem_t * sem, con struct timespec currSysTime; #else /* NEED_FTIME */ -#if defined(__MINGW32__) - struct timeb currSysTime; - -#else /* __MINGW32__ */ - struct _timeb currSysTime; -#endif /* __MINGW32__ */ #endif /* NEED_FTIME */ const DWORD NANOSEC_PER_MILLISEC = 1000000; Index: pthread.h =================================================================== RCS file: /cvs/pthreads-win32/pthreads/pthread.h,v retrieving revision 1.73 diff -u -3 -p -r1.73 pthread.h --- pthread.h 1999/11/05 12:58:50 1.73 +++ pthread.h 1999/11/08 10:40:09 @@ -285,16 +285,6 @@ struct timespec { #define PT_STDCALL __stdcall #endif - -/* - * This should perhaps be in autoconf or - * possibly fixed in Mingw32 to - * correspond to the Windows headers. - */ -#ifdef __MINGW32__ -#define _timeb timeb -#endif - #ifdef __cplusplus extern "C" { Index: tests/condvar2.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/condvar2.c,v retrieving revision 1.5 diff -u -3 -p -r1.5 condvar2.c --- tests/condvar2.c 1999/03/14 05:29:24 1.5 +++ tests/condvar2.c 1999/11/08 10:40:09 @@ -51,11 +51,7 @@ int main() { struct timespec abstime = { 0, 0 }; -#if defined(__MINGW32__) - struct timeb currSysTime; -#else struct _timeb currSysTime; -#endif const DWORD NANOSEC_PER_MILLISEC = 1000000; assert(pthread_cond_init(&cv, NULL) == 0); Index: tests/condvar3.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/condvar3.c,v retrieving revision 1.5 diff -u -3 -p -r1.5 condvar3.c --- tests/condvar3.c 1999/04/03 22:05:53 1.5 +++ tests/condvar3.c 1999/11/08 10:40:09 @@ -75,11 +75,7 @@ main() { pthread_t t[NUMTHREADS]; struct timespec abstime = { 0, 0 }; -#if defined(__MINGW32__) - struct timeb currSysTime; -#else struct _timeb currSysTime; -#endif const DWORD NANOSEC_PER_MILLISEC = 1000000; assert((t[0] = pthread_self()) != NULL); Index: tests/condvar4.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/condvar4.c,v retrieving revision 1.4 diff -u -3 -p -r1.4 condvar4.c --- tests/condvar4.c 1999/03/14 05:29:26 1.4 +++ tests/condvar4.c 1999/11/08 10:40:09 @@ -82,11 +82,7 @@ main() { pthread_t t[NUMTHREADS]; struct timespec abstime = { 0, 0 }; -#if defined(__MINGW32__) - struct timeb currSysTime; -#else struct _timeb currSysTime; -#endif const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; Index: tests/condvar5.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/condvar5.c,v retrieving revision 1.1 diff -u -3 -p -r1.1 condvar5.c --- tests/condvar5.c 1999/05/29 07:46:49 1.1 +++ tests/condvar5.c 1999/11/08 10:40:09 @@ -81,11 +81,7 @@ main() { pthread_t t[NUMTHREADS]; struct timespec abstime = { 0, 0 }; -#if defined(__MINGW32__) - struct timeb currSysTime; -#else struct _timeb currSysTime; -#endif const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; Index: tests/condvar6.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/condvar6.c,v retrieving revision 1.1 diff -u -3 -p -r1.1 condvar6.c --- tests/condvar6.c 1999/05/29 07:46:49 1.1 +++ tests/condvar6.c 1999/11/08 10:40:09 @@ -112,11 +112,7 @@ main() int i; pthread_t t[NUMTHREADS + 1]; -#if defined(__MINGW32__) - struct timeb currSysTime; -#else struct _timeb currSysTime; -#endif const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; Index: tests/condvar7.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/condvar7.c,v retrieving revision 1.1 diff -u -3 -p -r1.1 condvar7.c --- tests/condvar7.c 1999/10/16 16:24:43 1.1 +++ tests/condvar7.c 1999/11/08 10:40:09 @@ -116,11 +116,7 @@ main() int i; pthread_t t[NUMTHREADS + 1]; -#if defined(__MINGW32__) - struct timeb currSysTime; -#else struct _timeb currSysTime; -#endif const DWORD NANOSEC_PER_MILLISEC = 1000000; cvthing.shared = 0; Index: tests/condvar8.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/condvar8.c,v retrieving revision 1.1 diff -u -3 -p -r1.1 condvar8.c --- tests/condvar8.c 1999/10/16 16:24:43 1.1 +++ tests/condvar8.c 1999/11/08 10:40:09 @@ -121,11 +121,7 @@ main() int first, last; pthread_t t[NUMTHREADS + 1]; -#if defined(__MINGW32__) - struct timeb currSysTime; -#else struct _timeb currSysTime; -#endif const DWORD NANOSEC_PER_MILLISEC = 1000000; assert((t[0] = pthread_self()) != NULL); Index: tests/condvar9.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/condvar9.c,v retrieving revision 1.1 diff -u -3 -p -r1.1 condvar9.c --- tests/condvar9.c 1999/10/16 16:24:43 1.1 +++ tests/condvar9.c 1999/11/08 10:40:09 @@ -123,11 +123,7 @@ main() int canceledThreads = 0; pthread_t t[NUMTHREADS + 1]; -#if defined(__MINGW32__) - struct timeb currSysTime; -#else struct _timeb currSysTime; -#endif const DWORD NANOSEC_PER_MILLISEC = 1000000; assert((t[0] = pthread_self()) != NULL); Index: tests/count1.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/count1.c,v retrieving revision 1.3 diff -u -3 -p -r1.3 count1.c --- tests/count1.c 1999/03/14 05:29:27 1.3 +++ tests/count1.c 1999/11/08 10:40:09 @@ -7,7 +7,11 @@ #include "test.h" +#if ! defined (__MINGW32__) || defined (__MSVCRT__) #define NUMTHREADS (60) +#else +#define NUMTHREADS (59) +#endif static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; static pthread_t threads[NUMTHREADS]; Index: tests/join2.c =================================================================== RCS file: /cvs/pthreads-win32/pthreads/tests/join2.c,v retrieving revision 1.1 diff -u -3 -p -r1.1 join2.c --- tests/join2.c 1999/08/19 05:26:03 1.1 +++ tests/join2.c 1999/11/08 10:40:09 @@ -29,7 +29,11 @@ main(int argc, char * argv[]) for (i = 0; i < 4; i++) { assert(pthread_join(id[i], (void *) &result) == 0); +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + /* CRTDLL _beginthread doesn't support return value, so + the assertion is guaranteed to fail. */ assert(result == i); +#endif } /* Success. */ Regards, Mumit