From e470da85f7b9426eea03d66086c2822bf29e9b05 Mon Sep 17 00:00:00 2001 From: rpj Date: Thu, 3 Mar 2011 23:37:20 +0000 Subject: Some cleanups, mostly x86_64 compat plus interlocked macros --- ChangeLog | 35 +++++- Makefile | 6 +- NEWS | 17 ++- config.h | 8 ++ context.h | 2 +- global.c | 11 -- implement.h | 235 ++++++++++++++++++++++++++++++++++--- pthread.h | 3 + pthread_barrier_wait.c | 2 +- pthread_cancel.c | 2 +- pthread_delay_np.c | 2 +- pthread_exit.c | 2 +- pthread_once.c | 2 +- pthread_spin_destroy.c | 4 +- pthread_timechange_handler_np.c | 2 +- pthread_win32_attach_detach_np.c | 64 ---------- ptw32_InterlockedCompareExchange.c | 12 +- ptw32_MCS_lock.c | 37 +++--- ptw32_relmillisecs.c | 9 +- ptw32_threadStart.c | 4 +- ptw32_throw.c | 4 +- tests/Bmakefile | 4 +- tests/ChangeLog | 10 ++ tests/GNUmakefile | 3 +- tests/Makefile | 10 +- tests/SIZES.VC | 41 +++---- tests/SIZES.VCE | 40 ++++--- tests/benchtest1.c | 27 +++-- tests/benchtest2.c | 8 +- tests/benchtest3.c | 8 +- tests/benchtest4.c | 8 +- tests/benchtest5.c | 16 +-- tests/condvar2.c | 2 +- tests/condvar2_1.c | 2 +- tests/condvar3.c | 2 +- tests/condvar3_1.c | 2 +- tests/condvar3_2.c | 4 +- tests/condvar3_3.c | 2 +- tests/condvar4.c | 4 +- tests/condvar5.c | 4 +- tests/condvar6.c | 2 +- tests/condvar7.c | 2 +- tests/condvar8.c | 2 +- tests/condvar9.c | 2 +- tests/mutex8.c | 2 +- tests/mutex8e.c | 2 +- tests/mutex8n.c | 2 +- tests/mutex8r.c | 2 +- tests/rwlock2_t.c | 2 +- tests/rwlock3_t.c | 2 +- tests/rwlock4_t.c | 2 +- tests/rwlock5_t.c | 2 +- tests/rwlock6_t.c | 2 +- tests/rwlock6_t2.c | 2 +- tests/rwlock7.c | 8 +- tests/rwlock8.c | 8 +- tests/spin4.c | 6 +- tests/stress1.c | 2 +- tests/test.h | 8 ++ 59 files changed, 467 insertions(+), 253 deletions(-) diff --git a/ChangeLog b/ChangeLog index aefef91..dda9ea2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,37 @@ +2011-03-04 Ross Johnson + + * implement.h (PTW32_INTERLOCKED_*): Mingw32 does not provide + the __sync_* intrinsics so implemented them here as macro + assembler routines. MSVS Interlocked* are emmitted as intrinsics + wherever possible, so we want mingw to match it; Extended to + include all interlocked routines used by the library; implemented + x86_64 versions also. + * ptw32_InterlockedCompareExchange.c: No code remaining here. + * ptw32_MCS_lock.c: Converted interlocked calls to use new macros. + * pthread_barrier_wait.c: Likewise. + * pthread_once.c: Likewise. + +2011-02-28 Ross Johnson + + * ptw32_relmillisecs.c: If possible, use _ftime64_s or _ftime64 + before resorting to _ftime. + 2011-02-27 Ross Johnson - * sched_setscheduler: Ensure the handle is closed after use. - * sched_getscheduler: Likewise. - * pthread.h: Remove POSIX compatibility macros. + * sched_setscheduler.c: Ensure the handle is closed after use. + * sched_getscheduler.c: Likewise. + * pthread.h: Remove POSIX compatibility macros; don't define + timespec if already defined. + * context.h: Changes for 64 bit. + * pthread_cancel.c: Likewise. + * pthread_exit.c: Likewise. + * pthread_spin_destroy.c: Likewise. + * pthread_timechange_handler_np.c: Likewise. + * ptw32_MCS_lock.c: Likewise; some of these changes may + not be compatible with pre Windows 2000 systems; reverse the order of + the includes. + * ptw32_threadStart.c: Likewise. + * ptw32_throw.c: Likewise. 2011-02-13 Ross Johnson diff --git a/Makefile b/Makefile index 945bd43..6919117 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ OPTIM = /O2 /Ob2 OPTIMD = CFLAGS = /W3 /MD /nologo /I. /D_WIN32_WINNT=0x400 /DHAVE_CONFIG_H -CFLAGSD = /Zi $(CFLAGS) +CFLAGSD = /Z7 $(CFLAGS) # Uncomment this if config.h defines RETAIN_WSALASTERROR #XLIBS = wsock32.lib @@ -37,8 +37,8 @@ CFLAGSD = /Zi $(CFLAGS) CLEANUP = __CLEANUP_C # C++ Exceptions -VCEFLAGS = /GX /TP $(CFLAGS) -VCEFLAGSD = /GX /TP $(CFLAGSD) +VCEFLAGS = /EHsc /TP $(CFLAGS) +VCEFLAGSD = /EHsc /TP $(CFLAGSD) #Structured Exceptions VSEFLAGS = $(CFLAGS) VSEFLAGSD = $(CFLAGSD) diff --git a/NEWS b/NEWS index e19e645..5923901 100644 --- a/NEWS +++ b/NEWS @@ -1,13 +1,17 @@ CURRENT CVS HEAD Version RELEASE 2.9.0 pending ------------- -(2010-??-??) +(2011-??-??) General ------- New bug fixes in this release since 2.8.0 have NOT been applied to the 1.x.x series. +Version 2.8.0 may be the last release for some older Windows systems. +Some changes post 2011-02-26 in CVS may not be compatible with pre +Windows 2000 systems. + Version 1 no longer maintained ------------------------------ The 1.x.x series is no longer maintained. However, if you really need a @@ -47,6 +51,9 @@ See README.NONPORTABLE for descriptions of these routines. Bug fixes --------- +Many more changes for 64 bit systems. +- Kai Tietz + Various modifications and fixes to build and test for WinCE. - Marcel Ruff, Sinan Kaya @@ -75,6 +82,14 @@ have slowed barriers down slightly but halves the number of semaphores consumed per barrier to one. - Ross Johnson +Fixed a handle leak in sched_[gs]etscheduler. +- Mark Pizzolato + +Removed all of the POSIX re-entrant function compatibility macros from pthread.h. +Some were simply not semanticly correct. +- Igor Lubashev + + RELEASE 2.8.0 ------------- (2006-12-22) diff --git a/config.h b/config.h index 66f6f17..402b963 100644 --- a/config.h +++ b/config.h @@ -46,6 +46,14 @@ /* Do we know about type mode_t? */ #undef HAVE_MODE_T +/* + * Define if GCC has atomic builtins, i.e. __sync_* intrinsics + * __sync_lock_* is implemented in mingw32 gcc 4.5.2 at least + * so this define does not turn those on or off. If you get an + * error from __sync_lock* then consider upgrading your gcc. + */ +#undef HAVE_GCC_ATOMIC_BUILTINS + /* Define if you have the timespec struct */ #undef HAVE_STRUCT_TIMESPEC diff --git a/context.h b/context.h index 871aa3f..3d4511f 100644 --- a/context.h +++ b/context.h @@ -39,7 +39,7 @@ #undef PTW32_PROGCTR -#if defined(_M_IX86) || defined(_X86_) +#if defined(_M_IX86) || (defined(_X86_) && !defined(__amd64__)) #define PTW32_PROGCTR(Context) ((Context).Eip) #endif diff --git a/global.c b/global.c index 2b55422..60ccaff 100644 --- a/global.c +++ b/global.c @@ -54,17 +54,6 @@ int ptw32_features = 0; BOOL ptw32_smp_system = PTW32_TRUE; /* Safer if assumed true initially. */ -/* - * Function pointer to InterlockedCompareExchange if it exists, otherwise - * it will be set at runtime to a substitute local version with the same - * functionality but may be architecture specific. - */ -PTW32_INTERLOCKED_LONG - (WINAPI * ptw32_interlocked_compare_exchange) (PTW32_INTERLOCKED_LPLONG, - PTW32_INTERLOCKED_LONG, - PTW32_INTERLOCKED_LONG) = - NULL; - /* * Function pointer to QueueUserAPCEx if it exists, otherwise * it will be set at runtime to a substitute routine which cannot unblock diff --git a/implement.h b/implement.h index 00f153f..1bd3ce9 100644 --- a/implement.h +++ b/implement.h @@ -668,26 +668,229 @@ extern "C" /* - * Defaults. Could be overridden when building the inlined version of the dll. - * See ptw32_InterlockedCompareExchange.c + * Use intrinsic versions wherever possible. VC will do this + * automatically where possible and GCC define these if available: + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 + * + * The full set of Interlocked intrinsics in GCC are (check versions): + * type __sync_fetch_and_add (type *ptr, type value, ...) + * type __sync_fetch_and_sub (type *ptr, type value, ...) + * type __sync_fetch_and_or (type *ptr, type value, ...) + * type __sync_fetch_and_and (type *ptr, type value, ...) + * type __sync_fetch_and_xor (type *ptr, type value, ...) + * type __sync_fetch_and_nand (type *ptr, type value, ...) + * type __sync_add_and_fetch (type *ptr, type value, ...) + * type __sync_sub_and_fetch (type *ptr, type value, ...) + * type __sync_or_and_fetch (type *ptr, type value, ...) + * type __sync_and_and_fetch (type *ptr, type value, ...) + * type __sync_xor_and_fetch (type *ptr, type value, ...) + * type __sync_nand_and_fetch (type *ptr, type value, ...) + * bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...) + * type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...) + * __sync_synchronize (...) // Full memory barrier + * type __sync_lock_test_and_set (type *ptr, type value, ...) // Acquire barrier + * void __sync_lock_release (type *ptr, ...) // Release barrier + * + * These are all overloaded and take 1,2,4,8 byte scalar or pointer types. + * + * The above aren't available in Mingw32 as of gcc 4.5.2 so define our own. */ -#ifndef PTW32_INTERLOCKED_COMPARE_EXCHANGE -# define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_interlocked_compare_exchange -# endif - -#ifndef PTW32_INTERLOCKED_EXCHANGE -#define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange -#endif - - +#if defined(__GNUC__) +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE(location, value, comparand) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "cmpxchgl %2,(%1)" \ + :"=a" (_result) \ + :"r" (location), "r" (value), "a" (comparand) \ + :"memory", "cc"); \ + _result; \ + }) /* - * Check for old and new versions of cygwin. See the FAQ file: + * Faster version of XCHG for uni-processor systems because + * it doesn't lock the bus. If an interrupt or context switch + * occurs between the movl and the cmpxchgl then the value in + * 'location' may have changed, in which case we will loop + * back to do the movl again. * - * Question 1 - How do I get pthreads-win32 to link under Cygwin or Mingw32? + * Tests show that this routine has almost identical timing + * to Win32's InterlockedExchange(), and is much faster than + * using an inlined 'xchg' instruction, so Win32 is probably + * doing something similar to this (on UP systems). + */ +# define PTW32_INTERLOCKED_EXCHANGE(location, value) \ + ({ \ + __typeof (value) _result; \ + (ptw32_smp_system) ? ({ \ + __asm__ __volatile__ \ + ( \ + "xchgl %0,(%1)" \ + :"=r" (_result) \ + :"r" (location), "0" (value) \ + :"memory", "cc"); \ + }) : ({ \ + __asm__ __volatile__ \ + ( \ + "0:\n\t" \ + "movl %1,%%eax\n\t" \ + "cmpxchgl %2,(%1)\n\t" \ + "jnz 0b" \ + :"=&a" (_result) \ + :"r" (location), "r" (value) \ + :"memory", "cc"); \ + }); \ + _result; \ + }) +# define PTW32_INTERLOCKED_EXCHANGE_ADD(location, value) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddl %0,(%1)" \ + :"=r" (_result) \ + :"r" (location), "0" (value) \ + :"memory", "cc"); \ + _result; \ + }) +# define PTW32_INTERLOCKED_INCREMENT(location) \ + ({ \ + long _temp = 1; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddl %0,(%1)" \ + :"+r" (_temp) \ + :"r" (location) \ + :"memory", "cc"); \ + _temp + 1; \ + }) +# define PTW32_INTERLOCKED_DECREMENT(location) \ + ({ \ + long _temp = -1; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddl %0,(%1)" \ + :"+r" (_temp) \ + :"r" (location) \ + :"memory", "cc"); \ + _temp - 1; \ + }) +# if defined(_WIN64) +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE64(location, value, comparand) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "cmpxchgq %2,(%1)" \ + :"=a" (_result) \ + :"r" (location), "r" (value), "a" (comparand) \ + :"memory", "cc"); \ + _result; \ + }) +/* + * Faster version of XCHG for uni-processor systems because + * it doesn't lock the bus. If an interrupt or context switch + * occurs between the movl and the cmpxchgl then the value in + * 'location' may have changed, in which case we will loop + * back to do the movl again. * - * Patch by Anders Norlander + * Tests show that this routine has almost identical timing + * to Win32's InterlockedExchange(), and is much faster than + * using an inlined 'xchg' instruction, so Win32 is probably + * doing something similar to this (on UP systems). */ -#if defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(NEED_CREATETHREAD) +# define PTW32_INTERLOCKED_EXCHANGE64(location, value) \ + ({ \ + __typeof (value) _result; \ + (ptw32_smp_system) ? ({ \ + __asm__ __volatile__ \ + ( \ + "xchgq %0,(%1)" \ + :"=r" (_result) \ + :"r" (location), "0" (value) \ + :"memory", "cc"); \ + }) : ({ \ + __asm__ __volatile__ \ + ( \ + "0:\n\t" \ + "movq %1,%%eax\n\t" \ + "cmpxchgq %2,(%1)\n\t" \ + "jnz 0b" \ + :"=&a" (_result) \ + :"r" (location), "r" (value) \ + :"memory", "cc"); \ + }); \ + _result; \ + }) +# define PTW32_INTERLOCKED_EXCHANGE_ADD64(location, value) \ + ({ \ + __typeof (value) _result; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddq %0,(%1)" \ + :"=r" (_result) \ + :"r" (location), "0" (value) \ + :"memory", "cc"); \ + _result; \ + }) +# define PTW32_INTERLOCKED_INCREMENT64(location) \ + ({ \ + long _temp = 1; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddq %0,(%1)" \ + :"+r" (_temp) \ + :"r" (location) \ + :"memory", "cc"); \ + _temp + 1; \ + }) +# define PTW32_INTERLOCKED_DECREMENT64(location) \ + ({ \ + long _temp = -1; \ + __asm__ __volatile__ \ + ( \ + "lock\n\t" \ + "xaddq %0,(%1)" \ + :"+r" (_temp) \ + :"r" (location) \ + :"memory", "cc"); \ + _temp - 1; \ + }) +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR PTW32_INTERLOCKED_COMPARE_EXCHANGE64 +# define PTW32_INTERLOCKED_EXCHANGE_PTR PTW32_INTERLOCKED_EXCHANGE64 +# else +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR PTW32_INTERLOCKED_COMPARE_EXCHANGE +# define PTW32_INTERLOCKED_EXCHANGE_PTR PTW32_INTERLOCKED_EXCHANGE +# endif +#else +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR InterlockedCompareExchangePointer +# define PTW32_INTERLOCKED_EXCHANGE InterlockedExchange +# define PTW32_INTERLOCKED_EXCHANGE_PTR InterlockedExchangePointer +# define PTW32_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd +# define PTW32_INTERLOCKED_INCREMENT InterlockedIncrement +# define PTW32_INTERLOCKED_DECREMENT InterlockedDecrement +# if defined(_WIN64) +# define PTW32_INTERLOCKED_COMPARE_EXCHANGE64 InterlockedCompareExchange64 +# define PTW32_INTERLOCKED_EXCHANGE64 InterlockedExchange64 +# define PTW32_INTERLOCKED_EXCHANGE_ADD64 InterlockedExchangeAdd64 +# define PTW32_INTERLOCKED_INCREMENT64 InterlockedIncrement64 +# define PTW32_INTERLOCKED_DECREMENT64 InterlockedDecrement64 +# endif +#endif + +#if defined(NEED_CREATETHREAD) /* * Macro uses args so we can cast start_proc to LPTHREAD_START_ROUTINE @@ -709,7 +912,7 @@ extern "C" #define _endthreadex ExitThread -#endif /* __CYGWIN32__ || __CYGWIN__ || NEED_CREATETHREAD */ +#endif /* NEED_CREATETHREAD */ #endif /* _IMPLEMENT_H */ diff --git a/pthread.h b/pthread.h index f29f372..d487340 100644 --- a/pthread.h +++ b/pthread.h @@ -304,10 +304,13 @@ enum { #ifndef HAVE_STRUCT_TIMESPEC #define HAVE_STRUCT_TIMESPEC 1 +#ifndef _TIMESPEC_DEFINED +#define _TIMESPEC_DEFINED struct timespec { time_t tv_sec; long tv_nsec; }; +#endif /* _TIMESPEC_DEFINED */ #endif /* HAVE_STRUCT_TIMESPEC */ #ifndef SIG_BLOCK diff --git a/pthread_barrier_wait.c b/pthread_barrier_wait.c index 182b779..d60ba60 100644 --- a/pthread_barrier_wait.c +++ b/pthread_barrier_wait.c @@ -87,7 +87,7 @@ pthread_barrier_wait (pthread_barrier_t * barrier) result = ptw32_semwait (&(b->semBarrierBreeched)); } - if ((PTW32_INTERLOCKED_LONG)InterlockedIncrement((LPLONG)&b->nCurrentBarrierHeight) + if ((PTW32_INTERLOCKED_LONG)PTW32_INTERLOCKED_INCREMENT((LPLONG)&b->nCurrentBarrierHeight) == (PTW32_INTERLOCKED_LONG)b->nInitialBarrierHeight) { /* diff --git a/pthread_cancel.c b/pthread_cancel.c index de2c5a9..8ef2a11 100644 --- a/pthread_cancel.c +++ b/pthread_cancel.c @@ -157,7 +157,7 @@ pthread_cancel (pthread_t thread) * this will result in a call to ptw32_RegisterCancelation and only * the threadH arg will be used. */ - ptw32_register_cancelation (ptw32_cancel_callback, threadH, 0); + ptw32_register_cancelation ((PAPCFUNC)ptw32_cancel_callback, threadH, 0); (void) pthread_mutex_unlock (&tp->cancelLock); ResumeThread (threadH); } diff --git a/pthread_delay_np.c b/pthread_delay_np.c index 7fe9ae0..f624fc8 100644 --- a/pthread_delay_np.c +++ b/pthread_delay_np.c @@ -102,7 +102,7 @@ pthread_delay_np (struct timespec *interval) } /* convert secs to millisecs */ - secs_in_millisecs = interval->tv_sec * 1000L; + secs_in_millisecs = (DWORD)interval->tv_sec * 1000L; /* convert nanosecs to millisecs (rounding up) */ millisecs = (interval->tv_nsec + 999999L) / 1000000L; diff --git a/pthread_exit.c b/pthread_exit.c index e707f07..a3f7a03 100644 --- a/pthread_exit.c +++ b/pthread_exit.c @@ -89,7 +89,7 @@ pthread_exit (void *value_ptr) */ #if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - _endthreadex ((unsigned) value_ptr); + _endthreadex ((unsigned) (size_t) value_ptr); #else _endthread (); #endif diff --git a/pthread_once.c b/pthread_once.c index 4da54fc..79e4dbc 100644 --- a/pthread_once.c +++ b/pthread_once.c @@ -54,7 +54,7 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void)) return EINVAL; } - if (!InterlockedExchangeAdd((LPLONG)&once_control->done, 0)) /* MBR fence */ + if (!PTW32_INTERLOCKED_EXCHANGE_ADD((LPLONG)&once_control->done, 0)) /* MBR fence */ { ptw32_mcs_local_node_t node; diff --git a/pthread_spin_destroy.c b/pthread_spin_destroy.c index 8fe2267..c9317d2 100644 --- a/pthread_spin_destroy.c +++ b/pthread_spin_destroy.c @@ -59,9 +59,9 @@ pthread_spin_destroy (pthread_spinlock_t * lock) PTW32_INTERLOCKED_COMPARE_EXCHANGE ((PTW32_INTERLOCKED_LPLONG) & (s->interlock), (PTW32_INTERLOCKED_LONG) - PTW32_OBJECT_INVALID, + (size_t)PTW32_OBJECT_INVALID, (PTW32_INTERLOCKED_LONG) - PTW32_SPIN_UNLOCKED)) + (size_t)PTW32_SPIN_UNLOCKED)) { result = EINVAL; } diff --git a/pthread_timechange_handler_np.c b/pthread_timechange_handler_np.c index 7d8170a..12bd135 100644 --- a/pthread_timechange_handler_np.c +++ b/pthread_timechange_handler_np.c @@ -103,5 +103,5 @@ pthread_timechange_handler_np (void *arg) LeaveCriticalSection (&ptw32_cond_list_lock); - return (void *) (result != 0 ? EAGAIN : 0); + return (void *) (size_t) (result != 0 ? EAGAIN : 0); } diff --git a/pthread_win32_attach_detach_np.c b/pthread_win32_attach_detach_np.c index 7911fe1..bb83fd7 100644 --- a/pthread_win32_attach_detach_np.c +++ b/pthread_win32_attach_detach_np.c @@ -89,70 +89,6 @@ pthread_win32_process_attach_np () ptw32_smp_system = PTW32_FALSE; } -#endif - -#ifdef _WIN64 - -/* - * InterlockedCompareExchange routine in WIN64 is an intrinsic function. - * See PTW32_INTERLOCKED_COMPARE_EXCHANGE implement.h - */ - -#else - -#ifdef WINCE - - /* - * Load COREDLL and try to get address of InterlockedCompareExchange - */ - ptw32_h_kernel32 = LoadLibrary (TEXT ("COREDLL.DLL")); - -#else - - /* - * Load KERNEL32 and try to get address of InterlockedCompareExchange - */ - ptw32_h_kernel32 = LoadLibrary (TEXT ("KERNEL32.DLL")); - -#endif - - ptw32_interlocked_compare_exchange = - (PTW32_INTERLOCKED_LONG (WINAPI *) - (PTW32_INTERLOCKED_LPLONG, PTW32_INTERLOCKED_LONG, - PTW32_INTERLOCKED_LONG)) -#if defined(NEED_UNICODE_CONSTS) - GetProcAddress (ptw32_h_kernel32, - (const TCHAR *) TEXT ("InterlockedCompareExchange")); -#else - GetProcAddress (ptw32_h_kernel32, (LPCSTR) "InterlockedCompareExchange"); -#endif - - if (ptw32_interlocked_compare_exchange == NULL) - { - ptw32_interlocked_compare_exchange = ptw32_InterlockedCompareExchange; - - /* - * If InterlockedCompareExchange is not being used, then free - * the kernel32.dll handle now, rather than leaving it until - * DLL_PROCESS_DETACH. - * - * Note: this is not a pedantic exercise in freeing unused - * resources! It is a work-around for a bug in Windows 95 - * (see microsoft knowledge base article, Q187684) which - * does Bad Things when FreeLibrary is called within - * the DLL_PROCESS_DETACH code, in certain situations. - * Since w95 just happens to be a platform which does not - * provide InterlockedCompareExchange, the bug will be - * effortlessly avoided. - */ - (void) FreeLibrary (ptw32_h_kernel32); - ptw32_h_kernel32 = 0; - } - else - { - ptw32_features |= PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE; - } - #endif /* diff --git a/ptw32_InterlockedCompareExchange.c b/ptw32_InterlockedCompareExchange.c index 898591d..74b9f15 100644 --- a/ptw32_InterlockedCompareExchange.c +++ b/ptw32_InterlockedCompareExchange.c @@ -35,6 +35,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#if 0 #ifndef _WIN64 #include "pthread.h" @@ -154,6 +155,7 @@ ptw32_InterlockedCompareExchange (PTW32_INTERLOCKED_LPLONG location, } +#if 0 /* * ptw32_InterlockedExchange -- * @@ -207,8 +209,6 @@ ptw32_InterlockedExchange (LPLONG location, * 'location' may have changed, in which case we will loop * back to do the MOV again. * - * FIXME! Need memory barriers for the MOV+CMPXCHG combo? - * * Tests show that this routine has almost identical timing * to Win32's InterlockedExchange(), which is much faster than * using the inlined 'xchg' instruction above, so it's probably @@ -249,8 +249,6 @@ L1: MOV eax,dword ptr [ecx] * 'location' may have changed, in which case we will loop * back to do the movl again. * - * FIXME! Need memory barriers for the MOV+CMPXCHG combo? - * * Tests show that this routine has almost identical timing * to Win32's InterlockedExchange(), and is much faster than * using an inlined 'xchg' instruction, so Win32 is probably @@ -288,6 +286,7 @@ L1: MOV eax,dword ptr [ecx] #endif } +#endif #if 1 @@ -297,11 +296,16 @@ L1: MOV eax,dword ptr [ecx] #define PTW32_INTERLOCKED_COMPARE_EXCHANGE ptw32_InterlockedCompareExchange #endif +#if 0 #if defined(PTW32_BUILD_INLINED) && defined(HAVE_INLINABLE_INTERLOCKED_XCHG) #undef PTW32_INTERLOCKED_EXCHANGE #define PTW32_INTERLOCKED_EXCHANGE ptw32_InterlockedExchange #endif +#endif #endif #endif + +#endif /* 0 */ + diff --git a/ptw32_MCS_lock.c b/ptw32_MCS_lock.c index 80e0f5a..1cdf723 100644 --- a/ptw32_MCS_lock.c +++ b/ptw32_MCS_lock.c @@ -89,8 +89,8 @@ * } */ -#include "implement.h" #include "pthread.h" +#include "implement.h" /* * ptw32_mcs_flag_set -- notify another thread about an event. @@ -101,10 +101,10 @@ INLINE void ptw32_mcs_flag_set (LONG * flag) { - HANDLE e = (HANDLE)PTW32_INTERLOCKED_COMPARE_EXCHANGE( + HANDLE e = (HANDLE)(size_t)PTW32_INTERLOCKED_COMPARE_EXCHANGE( (PTW32_INTERLOCKED_LPLONG)flag, - (PTW32_INTERLOCKED_LONG)-1, - (PTW32_INTERLOCKED_LONG)0); + (PTW32_INTERLOCKED_LONG)(size_t)-1, + (PTW32_INTERLOCKED_LONG)(size_t)0); if ((HANDLE)0 != e) { /* another thread has already stored an event handle in the flag */ @@ -121,7 +121,7 @@ ptw32_mcs_flag_set (LONG * flag) INLINE void ptw32_mcs_flag_wait (LONG * flag) { - if (0 == InterlockedExchangeAdd((LPLONG)flag, 0)) /* MBR fence */ + if (0 == PTW32_INTERLOCKED_EXCHANGE_ADD((LPLONG)flag, 0)) /* MBR fence */ { /* the flag is not set. create event. */ @@ -129,8 +129,8 @@ ptw32_mcs_flag_wait (LONG * flag) if (0 == PTW32_INTERLOCKED_COMPARE_EXCHANGE( (PTW32_INTERLOCKED_LPLONG)flag, - (PTW32_INTERLOCKED_LONG)e, - (PTW32_INTERLOCKED_LONG)0)) + (PTW32_INTERLOCKED_LONG)(size_t)e, + (PTW32_INTERLOCKED_LONG)(size_t)0)) { /* stored handle in the flag. wait on it now. */ WaitForSingleObject(e, INFINITE); @@ -159,8 +159,8 @@ ptw32_mcs_lock_acquire (ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node) node->next = 0; /* initially, no successor */ /* queue for the lock */ - pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE((PTW32_INTERLOCKED_LPLONG)lock, - (PTW32_INTERLOCKED_LONG)node); + pred = (ptw32_mcs_local_node_t *)PTW32_INTERLOCKED_EXCHANGE_PTR((PVOID volatile *)lock, + (void*)node); if (0 != pred) { @@ -184,17 +184,20 @@ ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node) { ptw32_mcs_lock_t *lock = node->lock; ptw32_mcs_local_node_t *next = (ptw32_mcs_local_node_t *) - InterlockedExchangeAdd((LPLONG)&node->next, - (LONG)0); /* MBR fence */ +#ifndef _WIN64 + PTW32_INTERLOCKED_EXCHANGE_ADD((LPLONG)&node->next, 0); /* MBR fence */ +#else + PTW32_INTERLOCKED_EXCHANGE_ADD64((LONG64 *)&node->next, 0); /* MBR fence */ +#endif if (0 == next) { /* no known successor */ if (node == (ptw32_mcs_local_node_t *) - PTW32_INTERLOCKED_COMPARE_EXCHANGE((PTW32_INTERLOCKED_LPLONG)lock, - (PTW32_INTERLOCKED_LONG)0, - (PTW32_INTERLOCKED_LONG)node)) + PTW32_INTERLOCKED_COMPARE_EXCHANGE_PTR((LPVOID volatile *)lock, + (PVOID)0, + (PVOID)node)) { /* no successor, lock is free now */ return; @@ -203,7 +206,11 @@ ptw32_mcs_lock_release (ptw32_mcs_local_node_t * node) /* wait for successor */ ptw32_mcs_flag_wait(&node->nextFlag); next = (ptw32_mcs_local_node_t *) - InterlockedExchangeAdd((LPLONG)&node->next, 0); /* MBR fence */ +#ifndef _WIN64 + PTW32_INTERLOCKED_EXCHANGE_ADD((LPLONG)&node->next, 0); /* MBR fence */ +#else + PTW32_INTERLOCKED_EXCHANGE_ADD64((LONG64 *)&node->next, 0); /* MBR fence */ +#endif } /* pass the lock */ diff --git a/ptw32_relmillisecs.c b/ptw32_relmillisecs.c index ee4a7e3..dbc30a2 100644 --- a/ptw32_relmillisecs.c +++ b/ptw32_relmillisecs.c @@ -34,9 +34,6 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ifndef _UWIN -/*#include */ -#endif #include "pthread.h" #include "implement.h" #ifndef NEED_FTIME @@ -94,7 +91,13 @@ ptw32_relmillisecs (const struct timespec * abstime) #else /* ! NEED_FTIME */ +#ifdef _MSC_VER + _ftime64_s(&currSysTime); +#elif defined(__MINGW32__) && __MSVCRT_VERSION__ >= 0x0601 + _ftime64(&currSysTime); +#else _ftime(&currSysTime); +#endif tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC; tmpCurrMilliseconds += (int64_t) currSysTime.millitm; diff --git a/ptw32_threadStart.c b/ptw32_threadStart.c index 5c0fe0e..8121d5a 100644 --- a/ptw32_threadStart.c +++ b/ptw32_threadStart.c @@ -344,7 +344,7 @@ ptw32_threadStart (void *vthreadParms) #endif #if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - _endthreadex ((unsigned) status); + _endthreadex ((unsigned)(size_t) status); #else _endthread (); #endif @@ -354,7 +354,7 @@ ptw32_threadStart (void *vthreadParms) */ #if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) - return (unsigned) status; + return (unsigned)(size_t) status; #endif } /* ptw32_threadStart */ diff --git a/ptw32_throw.c b/ptw32_throw.c index b276119..63f45f1 100644 --- a/ptw32_throw.c +++ b/ptw32_throw.c @@ -79,12 +79,12 @@ ptw32_throw (DWORD exception) switch (exception) { case PTW32_EPS_CANCEL: - exitCode = (unsigned) PTHREAD_CANCELED; + exitCode = (unsigned)(size_t) PTHREAD_CANCELED; break; case PTW32_EPS_EXIT: if (NULL != sp) { - exitCode = (unsigned) sp->exitStatus; + exitCode = (unsigned)(size_t) sp->exitStatus; } break; } diff --git a/tests/Bmakefile b/tests/Bmakefile index 169f42c..c6cbc41 100644 --- a/tests/Bmakefile +++ b/tests/Bmakefile @@ -115,8 +115,7 @@ PASSES= loadfree.pass \ cancel9.pass create3.pass stress1.pass BENCHRESULTS = \ - benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench \ - benchtest6.bench + benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench help: @ $(ECHO) Run one of the following command lines: @@ -223,7 +222,6 @@ benchtest2.bench: benchtest3.bench: benchtest4.bench: benchtest5.bench: -benchtest6.bench: barrier1.pass: semaphore4.pass barrier2.pass: barrier1.pass barrier3.pass: barrier2.pass diff --git a/tests/ChangeLog b/tests/ChangeLog index 1bdcc43..bf604f5 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,13 @@ +2011-03-04 Ross Johnson + + * condvar3_2.c: abstime.tv_sec operation warning fixed. + +2011-02-28 Ross Johnson + + * test.h: Define FTIME to be _ftime64_s or _ftime64 or _ftime + in that order of preference where supported. + * several: Replace calls to _ftime with the FTIME macro. + 2010-06-19 Ross Johnson * Makefile (STATICRESULTS): Add all tests into suite for static diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 5d61a6f..013351f 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -111,7 +111,7 @@ STRESSTESTS = \ stress1 BENCHTESTS = \ - benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 benchtest6 + benchtest1 benchtest2 benchtest3 benchtest4 benchtest5 STATICTESTS = \ sizes \ @@ -213,7 +213,6 @@ benchtest2.bench: benchtest3.bench: benchtest4.bench: benchtest5.bench: -benchtest6.bench: barrier1.pass: semaphore4.pass barrier2.pass: barrier1.pass diff --git a/tests/Makefile b/tests/Makefile index 0042e02..aef83c2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -50,7 +50,7 @@ OPTIM = /O2 /Ob0 XXLIBS = ws2_32.lib # C++ Exceptions -VCEFLAGS = /GX /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX +VCEFLAGS = /EHsc /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX VCELIB = pthreadVCE$(DLL_VER).lib VCEDLL = pthreadVCE$(DLL_VER).dll # Structured Exceptions @@ -62,13 +62,13 @@ VCFLAGS = /D__CLEANUP_C VCLIB = pthreadVC$(DLL_VER).lib VCDLL = pthreadVC$(DLL_VER).dll # C++ Exceptions in application - using VC version of pthreads dll -VCXFLAGS = /GX /TP /D__CLEANUP_C +VCXFLAGS = /EHsc /TP /D__CLEANUP_C # Defaults CPLIB = $(VCLIB) CPDLL = $(VCDLL) -CFLAGS= $(OPTIM) /W3 /MD /nologo /Yd /Zi +CFLAGS= $(OPTIM) /W3 /MD /nologo /Z7 LFLAGS= /INCREMENTAL:NO INCLUDES=-I. BUILD_DIR=.. @@ -120,8 +120,7 @@ PASSES= sizes.pass loadfree.pass \ cancel9.pass create3.pass stress1.pass BENCHRESULTS = \ - benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench \ - benchtest6.bench + benchtest1.bench benchtest2.bench benchtest3.bench benchtest4.bench benchtest5.bench STRESSRESULTS = \ stress1.stress @@ -310,7 +309,6 @@ benchtest2.bench: benchtest3.bench: benchtest4.bench: benchtest5.bench: -benchtest6.bench: barrier1.pass: semaphore4.pass barrier2.pass: barrier1.pass diff --git a/tests/SIZES.VC b/tests/SIZES.VC index ae09a84..603521b 100755 --- a/tests/SIZES.VC +++ b/tests/SIZES.VC @@ -1,20 +1,21 @@ -Sizes of pthreads-win32 structs -------------------------------- - pthread_t_ 124 - pthread_attr_t_ 28 - sem_t_ 4 - pthread_mutex_t_ 44 - pthread_mutexattr_t_ 8 - pthread_spinlock_t_ 8 - pthread_barrier_t_ 24 - pthread_barrierattr_t_ 4 - pthread_key_t_ 16 - pthread_cond_t_ 32 - pthread_condattr_t_ 4 - pthread_rwlock_t_ 28 - pthread_rwlockattr_t_ 4 - pthread_once_t_ 8 - ptw32_cleanup_t 12 - sched_param 4 -------------------------------- - +Sizes of pthreads-win32 structs +------------------------------- + pthread_t 8 + ptw32_thread_t 140 + pthread_attr_t_ 28 + sem_t_ 12 + pthread_mutex_t_ 24 + pthread_mutexattr_t_ 8 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 36 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 16 + ptw32_cleanup_t 12 + ptw32_mcs_node_t_ 16 + sched_param 4 +------------------------------- diff --git a/tests/SIZES.VCE b/tests/SIZES.VCE index edc6427..7048d3a 100644 --- a/tests/SIZES.VCE +++ b/tests/SIZES.VCE @@ -1,19 +1,21 @@ -Sizes of pthreads-win32 structs -------------------------------- - pthread_t_ 68 - pthread_attr_t_ 28 - sem_t_ 4 - pthread_mutex_t_ 44 - pthread_mutexattr_t_ 8 - pthread_spinlock_t_ 8 - pthread_barrier_t_ 24 - pthread_barrierattr_t_ 4 - pthread_key_t_ 16 - pthread_cond_t_ 32 - pthread_condattr_t_ 4 - pthread_rwlock_t_ 28 - pthread_rwlockattr_t_ 4 - pthread_once_t_ 8 - ptw32_cleanup_t 12 - sched_param 4 -------------------------------- +Sizes of pthreads-win32 structs +------------------------------- + pthread_t 8 + ptw32_thread_t 76 + pthread_attr_t_ 28 + sem_t_ 12 + pthread_mutex_t_ 24 + pthread_mutexattr_t_ 8 + pthread_spinlock_t_ 8 + pthread_barrier_t_ 36 + pthread_barrierattr_t_ 4 + pthread_key_t_ 16 + pthread_cond_t_ 32 + pthread_condattr_t_ 4 + pthread_rwlock_t_ 28 + pthread_rwlockattr_t_ 4 + pthread_once_t_ 16 + ptw32_cleanup_t 12 + ptw32_mcs_node_t_ 16 + sched_param 4 +------------------------------- diff --git a/tests/benchtest1.c b/tests/benchtest1.c index 116dad0..21e8e64 100644 --- a/tests/benchtest1.c +++ b/tests/benchtest1.c @@ -57,21 +57,23 @@ struct _timeb currSysTimeStart; struct _timeb currSysTimeStop; long durationMilliSecs; long overHeadMilliSecs = 0; +int two = 2; int one = 1; int zero = 0; +int iter; -#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ - - (_TStart.time*1000+_TStart.millitm)) +#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm))) /* * Dummy use of j, otherwise the loop may be removed by the optimiser * when doing the overhead timing with an empty loop. */ #define TESTSTART \ - { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; #define TESTSTOP \ - }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; } void @@ -83,8 +85,8 @@ runTest (char * testNameString, int mType) assert(pthread_mutex_init(&mx, &ma) == 0); TESTSTART - assert(pthread_mutex_lock(&mx) == zero); - assert(pthread_mutex_unlock(&mx) == zero); + assert((pthread_mutex_lock(&mx),1) == one); + assert((pthread_mutex_unlock(&mx),2) == two); TESTSTOP assert(pthread_mutex_destroy(&mx) == 0); @@ -118,10 +120,9 @@ main (int argc, char *argv[]) /* * Time the loop overhead so we can subtract it from the actual test times. */ - TESTSTART assert(1 == one); - assert(1 == one); + assert(2 == two); TESTSTOP durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; @@ -130,7 +131,7 @@ main (int argc, char *argv[]) TESTSTART assert((dummy_call(&i), 1) == one); - assert((dummy_call(&i), 1) == one); + assert((dummy_call(&i), 2) == two); TESTSTOP durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; @@ -138,12 +139,12 @@ main (int argc, char *argv[]) printf( "%-45s %15ld %15.3f\n", "Dummy call x 2", durationMilliSecs, - (float) durationMilliSecs * 1E3 / ITERATIONS); + (float) (durationMilliSecs * 1E3 / ITERATIONS)); TESTSTART assert((interlocked_inc_with_conditionals(&i), 1) == one); - assert((interlocked_dec_with_conditionals(&i), 1) == one); + assert((interlocked_dec_with_conditionals(&i), 2) == two); TESTSTOP durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; @@ -156,7 +157,7 @@ main (int argc, char *argv[]) TESTSTART assert((InterlockedIncrement((LPLONG)&i), 1) == (LONG)one); - assert((InterlockedDecrement((LPLONG)&i), 1) == (LONG)one); + assert((InterlockedDecrement((LPLONG)&i), 2) == (LONG)two); TESTSTOP durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; @@ -171,7 +172,7 @@ main (int argc, char *argv[]) TESTSTART assert((EnterCriticalSection(&cs), 1) == one); - assert((LeaveCriticalSection(&cs), 1) == one); + assert((LeaveCriticalSection(&cs), 2) == two); TESTSTOP DeleteCriticalSection(&cs); diff --git a/tests/benchtest2.c b/tests/benchtest2.c index d92bb3c..10deca2 100644 --- a/tests/benchtest2.c +++ b/tests/benchtest2.c @@ -65,18 +65,18 @@ struct _timeb currSysTimeStop; pthread_t worker; int running = 0; -#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ - - (_TStart.time*1000+_TStart.millitm)) +#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm))) /* * Dummy use of j, otherwise the loop may be removed by the optimiser * when doing the overhead timing with an empty loop. */ #define TESTSTART \ - { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; #define TESTSTOP \ - }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; } void * diff --git a/tests/benchtest3.c b/tests/benchtest3.c index 023460d..6ff3c90 100644 --- a/tests/benchtest3.c +++ b/tests/benchtest3.c @@ -59,18 +59,18 @@ struct _timeb currSysTimeStop; long durationMilliSecs; long overHeadMilliSecs = 0; -#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ - - (_TStart.time*1000+_TStart.millitm)) +#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm))) /* * Dummy use of j, otherwise the loop may be removed by the optimiser * when doing the overhead timing with an empty loop. */ #define TESTSTART \ - { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; #define TESTSTOP \ - }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; } void * diff --git a/tests/benchtest4.c b/tests/benchtest4.c index 772d100..d64438d 100644 --- a/tests/benchtest4.c +++ b/tests/benchtest4.c @@ -59,18 +59,18 @@ struct _timeb currSysTimeStop; long durationMilliSecs; long overHeadMilliSecs = 0; -#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ - - (_TStart.time*1000+_TStart.millitm)) +#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm))) /* * Dummy use of j, otherwise the loop may be removed by the optimiser * when doing the overhead timing with an empty loop. */ #define TESTSTART \ - { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; #define TESTSTOP \ - }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; } void diff --git a/tests/benchtest5.c b/tests/benchtest5.c index 7700fde..0d5c360 100644 --- a/tests/benchtest5.c +++ b/tests/benchtest5.c @@ -60,18 +60,18 @@ long overHeadMilliSecs = 0; int one = 1; int zero = 0; -#define GetDurationMilliSecs(_TStart, _TStop) ((_TStop.time*1000+_TStop.millitm) \ - - (_TStart.time*1000+_TStart.millitm)) +#define GetDurationMilliSecs(_TStart, _TStop) ((long)((_TStop.time*1000+_TStop.millitm) \ + - (_TStart.time*1000+_TStart.millitm))) /* * Dummy use of j, otherwise the loop may be removed by the optimiser * when doing the overhead timing with an empty loop. */ #define TESTSTART \ - { int i, j = 0, k = 0; _ftime(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; + { int i, j = 0, k = 0; PTW32_FTIME(&currSysTimeStart); for (i = 0; i < ITERATIONS; i++) { j++; #define TESTSTOP \ - }; _ftime(&currSysTimeStop); if (j + k == i) j++; } + }; PTW32_FTIME(&currSysTimeStop); if (j + k == i) j++; } void @@ -115,7 +115,7 @@ main (int argc, char *argv[]) */ assert((w32sema = CreateSemaphore(NULL, (long) 0, (long) ITERATIONS, NULL)) != 0); TESTSTART - assert(ReleaseSemaphore(w32sema, 1, NULL) != zero); + assert((ReleaseSemaphore(w32sema, 1, NULL),1) == one); TESTSTOP assert(CloseHandle(w32sema) != 0); @@ -124,7 +124,7 @@ main (int argc, char *argv[]) assert((w32sema = CreateSemaphore(NULL, (long) ITERATIONS, (long) ITERATIONS, NULL)) != 0); TESTSTART - assert(WaitForSingleObject(w32sema, INFINITE) == WAIT_OBJECT_0); + assert((WaitForSingleObject(w32sema, INFINITE),1) == one); TESTSTOP assert(CloseHandle(w32sema) != 0); @@ -133,7 +133,7 @@ main (int argc, char *argv[]) assert(sem_init(&sema, 0, 0) == 0); TESTSTART - assert(sem_post(&sema) == zero); + assert((sem_post(&sema),1) == one); TESTSTOP assert(sem_destroy(&sema) == 0); @@ -142,7 +142,7 @@ main (int argc, char *argv[]) assert(sem_init(&sema, 0, ITERATIONS) == 0); TESTSTART - assert(sem_wait(&sema) == zero); + assert((sem_wait(&sema),1) == one); TESTSTOP assert(sem_destroy(&sema) == 0); diff --git a/tests/condvar2.c b/tests/condvar2.c index 33f1d3f..793bb36 100644 --- a/tests/condvar2.c +++ b/tests/condvar2.c @@ -97,7 +97,7 @@ main() assert(pthread_mutex_lock(&mutex) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar2_1.c b/tests/condvar2_1.c index 92dddfd..bf08f44 100644 --- a/tests/condvar2_1.c +++ b/tests/condvar2_1.c @@ -114,7 +114,7 @@ main() assert(pthread_mutex_init(&mutex, NULL) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar3.c b/tests/condvar3.c index e3a23f5..8e7e6eb 100644 --- a/tests/condvar3.c +++ b/tests/condvar3.c @@ -124,7 +124,7 @@ main() assert(pthread_mutex_lock(&mutex) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar3_1.c b/tests/condvar3_1.c index 25a50e4..87671a4 100644 --- a/tests/condvar3_1.c +++ b/tests/condvar3_1.c @@ -137,7 +137,7 @@ main() assert(pthread_mutex_init(&mutex1, NULL) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar3_2.c b/tests/condvar3_2.c index 5ddcf57..33d800c 100644 --- a/tests/condvar3_2.c +++ b/tests/condvar3_2.c @@ -136,9 +136,9 @@ main() assert(pthread_mutex_init(&mutex, NULL) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); - abstime.tv_sec = abstime.tv_sec = currSysTime.time + 5; + abstime.tv_sec = abstime2.tv_sec = currSysTime.time + 5; abstime.tv_nsec = abstime2.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; assert(pthread_mutex_lock(&mutex) == 0); diff --git a/tests/condvar3_3.c b/tests/condvar3_3.c index fe67632..2a4495f 100644 --- a/tests/condvar3_3.c +++ b/tests/condvar3_3.c @@ -94,7 +94,7 @@ int main() assert(pthread_mutex_init(&mtx, 0) == 0); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar4.c b/tests/condvar4.c index 3babeea..c27aafb 100644 --- a/tests/condvar4.c +++ b/tests/condvar4.c @@ -128,7 +128,7 @@ main() assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; @@ -141,7 +141,7 @@ main() assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar5.c b/tests/condvar5.c index 4d51f39..7e6ab38 100644 --- a/tests/condvar5.c +++ b/tests/condvar5.c @@ -127,7 +127,7 @@ main() assert(cvthing.lock != PTHREAD_MUTEX_INITIALIZER); /* get current system time */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; @@ -140,7 +140,7 @@ main() assert(pthread_create(&t[1], NULL, mythread, (void *) 1) == 0); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar6.c b/tests/condvar6.c index e63132c..70da6a7 100644 --- a/tests/condvar6.c +++ b/tests/condvar6.c @@ -157,7 +157,7 @@ main() assert(pthread_mutex_lock(&start_flag) == 0); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar7.c b/tests/condvar7.c index 6d89f2e..8df30cb 100644 --- a/tests/condvar7.c +++ b/tests/condvar7.c @@ -167,7 +167,7 @@ main() assert(pthread_mutex_lock(&start_flag) == 0); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar8.c b/tests/condvar8.c index e384a1c..53bfc52 100644 --- a/tests/condvar8.c +++ b/tests/condvar8.c @@ -164,7 +164,7 @@ main() assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/condvar9.c b/tests/condvar9.c index c751271..5443e8b 100644 --- a/tests/condvar9.c +++ b/tests/condvar9.c @@ -172,7 +172,7 @@ main() assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER); - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/mutex8.c b/tests/mutex8.c index 5ca9982..827fae0 100644 --- a/tests/mutex8.c +++ b/tests/mutex8.c @@ -47,7 +47,7 @@ void * locker(void * arg) struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/mutex8e.c b/tests/mutex8e.c index b99d24e..e358630 100644 --- a/tests/mutex8e.c +++ b/tests/mutex8e.c @@ -55,7 +55,7 @@ void * locker(void * arg) struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/mutex8n.c b/tests/mutex8n.c index 3cfdae6..1a96f2e 100644 --- a/tests/mutex8n.c +++ b/tests/mutex8n.c @@ -55,7 +55,7 @@ void * locker(void * arg) struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/mutex8r.c b/tests/mutex8r.c index d1328ca..1a76097 100644 --- a/tests/mutex8r.c +++ b/tests/mutex8r.c @@ -55,7 +55,7 @@ void * locker(void * arg) struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/rwlock2_t.c b/tests/rwlock2_t.c index 8e6ab6d..a34d351 100644 --- a/tests/rwlock2_t.c +++ b/tests/rwlock2_t.c @@ -53,7 +53,7 @@ main() struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/rwlock3_t.c b/tests/rwlock3_t.c index bc45abc..71aa02a 100644 --- a/tests/rwlock3_t.c +++ b/tests/rwlock3_t.c @@ -66,7 +66,7 @@ main() struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/rwlock4_t.c b/tests/rwlock4_t.c index 37ec34f..3eec003 100644 --- a/tests/rwlock4_t.c +++ b/tests/rwlock4_t.c @@ -66,7 +66,7 @@ main() struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/rwlock5_t.c b/tests/rwlock5_t.c index bf473a4..a3a9497 100644 --- a/tests/rwlock5_t.c +++ b/tests/rwlock5_t.c @@ -68,7 +68,7 @@ main() struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/rwlock6_t.c b/tests/rwlock6_t.c index aa38bf5..37a332a 100644 --- a/tests/rwlock6_t.c +++ b/tests/rwlock6_t.c @@ -65,7 +65,7 @@ void * rdfunc(void * arg) struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/rwlock6_t2.c b/tests/rwlock6_t2.c index 58bfc3d..1bce439 100644 --- a/tests/rwlock6_t2.c +++ b/tests/rwlock6_t2.c @@ -92,7 +92,7 @@ main() struct _timeb currSysTime; const DWORD NANOSEC_PER_MILLISEC = 1000000; - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); abstime.tv_sec = currSysTime.time; abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; diff --git a/tests/rwlock7.c b/tests/rwlock7.c index 91466e4..1e8fdf0 100644 --- a/tests/rwlock7.c +++ b/tests/rwlock7.c @@ -122,7 +122,7 @@ main (int argc, char *argv[]) assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); } - _ftime(&currSysTime1); + PTW32_FTIME(&currSysTime1); /* * Create THREADS threads to access shared data. @@ -187,13 +187,13 @@ main (int argc, char *argv[]) printf ("%d thread updates, %d data updates\n", thread_updates, data_updates); - _ftime(&currSysTime2); + PTW32_FTIME(&currSysTime2); printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n", currSysTime1.time,currSysTime1.millitm, currSysTime2.time,currSysTime2.millitm, - (currSysTime2.time*1000+currSysTime2.millitm) - - (currSysTime1.time*1000+currSysTime1.millitm)); + ((long)((currSysTime2.time*1000+currSysTime2.millitm) - + (currSysTime1.time*1000+currSysTime1.millitm)))); return 0; } diff --git a/tests/rwlock8.c b/tests/rwlock8.c index c83a775..207646c 100644 --- a/tests/rwlock8.c +++ b/tests/rwlock8.c @@ -128,7 +128,7 @@ main (int argc, char *argv[]) assert(pthread_rwlock_init (&data[data_count].lock, NULL) == 0); } - _ftime(&currSysTime1); + PTW32_FTIME(&currSysTime1); /* * Create THREADS threads to access shared data. @@ -193,13 +193,13 @@ main (int argc, char *argv[]) printf ("%d thread updates, %d data updates\n", thread_updates, data_updates); - _ftime(&currSysTime2); + PTW32_FTIME(&currSysTime2); printf( "\nstart: %ld/%d, stop: %ld/%d, duration:%ld\n", currSysTime1.time,currSysTime1.millitm, currSysTime2.time,currSysTime2.millitm, - (currSysTime2.time*1000+currSysTime2.millitm) - - (currSysTime1.time*1000+currSysTime1.millitm)); + ((long)((currSysTime2.time*1000+currSysTime2.millitm) - + (currSysTime1.time*1000+currSysTime1.millitm)))); return 0; } diff --git a/tests/spin4.c b/tests/spin4.c index 8386d09..93e8d90 100644 --- a/tests/spin4.c +++ b/tests/spin4.c @@ -51,11 +51,11 @@ static int washere = 0; void * func(void * arg) { - _ftime(&currSysTimeStart); + PTW32_FTIME(&currSysTimeStart); washere = 1; assert(pthread_spin_lock(&lock) == 0); assert(pthread_spin_unlock(&lock) == 0); - _ftime(&currSysTimeStop); + PTW32_FTIME(&currSysTimeStop); return (void *) GetDurationMilliSecs(currSysTimeStart, currSysTimeStop); } @@ -86,7 +86,7 @@ main() do { sched_yield(); - _ftime(&sysTime); + PTW32_FTIME(&sysTime); } while (GetDurationMilliSecs(currSysTimeStart, sysTime) <= 1000); diff --git a/tests/stress1.c b/tests/stress1.c index 3588361..fb50124 100644 --- a/tests/stress1.c +++ b/tests/stress1.c @@ -117,7 +117,7 @@ millisecondsFromNow (struct timespec * time, int millisecs) const int64_t NANOSEC_PER_SEC = 1000000000; /* get current system time and add millisecs */ - _ftime(&currSysTime); + PTW32_FTIME(&currSysTime); secs = (int64_t)(currSysTime.time) + (millisecs / 1000); nanosecs = ((int64_t) (millisecs%1000 + currSysTime.millitm)) * NANOSEC_PER_MILLISEC; diff --git a/tests/test.h b/tests/test.h index dc63eb4..a6c2b60 100644 --- a/tests/test.h +++ b/tests/test.h @@ -61,6 +61,14 @@ #define int64_t _int64 #endif +#ifdef _MSC_VER + #define PTW32_FTIME(x) _ftime64_s(x); +#elif defined(__MINGW32__) && __MSVCRT_VERSION__ >= 0x0601 + #define PTW32_FTIME(x) _ftime64(x); +#else + #define PTW32_FTIME(x) _ftime(x); +#endif + const char * error_string[] = { "ZERO_or_EOK", -- cgit v1.2.3