diff options
| author | rpj <rpj> | 2011-03-03 23:37:20 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2011-03-03 23:37:20 +0000 | 
| commit | e470da85f7b9426eea03d66086c2822bf29e9b05 (patch) | |
| tree | b3747768258dc62752612327904be1f1067d5c7f | |
| parent | 1170175259781ece4a8d99d517230f4b9ecb7b50 (diff) | |
Some cleanups, mostly x86_64 compat plus interlocked macros
59 files changed, 467 insertions, 253 deletions
| @@ -1,8 +1,37 @@ +2011-03-04  Ross Johnson <ross.johnson at homemail.com.au>
 +
 +	* 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 <ross.johnson at homemail.com.au>
 +
 +	* ptw32_relmillisecs.c: If possible, use _ftime64_s or _ftime64
 +	before resorting to _ftime.
 +
  2011-02-27  Ross Johnson <ross.johnson at homemail.com.au>
 -	* 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 <ross.johnson at homemail.com.au>
 @@ -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) @@ -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) @@ -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 @@ -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 @@ -55,17 +55,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   * blocked threads. 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 <anorland@hem2.passagen.se> + * 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 */ @@ -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 @@ -91,70 +91,6 @@ pthread_win32_process_attach_np ()  #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 -    /*     * Load QUSEREX.DLL and try to get address of QueueUserAPCEx     */ 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 <process.h> */ -#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 <Ross dot Johnson at homemail dot com dot au> + +	* condvar3_2.c: abstime.tv_sec operation warning fixed. + +2011-02-28  Ross Johnson <Ross dot Johnson at homemail dot com dot au> + +	* 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 <Ross dot Johnson at homemail dot com dot au>  	* 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", | 
