[Ace-users] [ace-bugs] ACE_OS::gethrtime produces inconsistent results onx86_64 architecture

Johnny Willemsen jwillemsen at remedy.nl
Fri Nov 9 03:53:47 CST 2007


Hi,
 
At the moment you put this in bugzilla, can you also extend the
tests/High_Res_Timer_Test.cpp to reproduce this issue?
 
Regards,
 
Johnny Willemsen
Remedy IT
Postbus 101
2650 AC  Berkel en Rodenrijs
The Netherlands
www.theaceorb.nl / www.remedy.nl 

*** Integrated compile and test statistics see
http://scoreboard.theaceorb.nl <http://scoreboard.theaceorb.nl/>  ***
*** Commercial service and support for ACE/TAO/CIAO             ***
*** See http://www.theaceorb.nl/en/support.html                 *** 


________________________________

	From: ace-bugs-bounces at cse.wustl.edu
[mailto:ace-bugs-bounces at cse.wustl.edu] On Behalf Of Ernst, Nathan
	Sent: Thursday, November 08, 2007 8:02 PM
	To: ace-bugs at cs.wustl.edu
	Subject: [ace-bugs] ACE_OS::gethrtime produces inconsistent results
onx86_64 architecture
	
	

	    ACE VERSION: 5.6 (5.6.1 is also affected)

	 

	    HOST MACHINE and OPERATING SYSTEM:

	Linux 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64
x86_64 x86_64 GNU/Linux

	 

	    TARGET MACHINE and OPERATING SYSTEM, if different from HOST:

	 

	    COMPILER NAME AND VERSION (AND PATCHLEVEL):

	gcc4 (GCC) 4.1.1 20070105 (Red Hat 4.1.1-53)

	 

	    THE $ACE_ROOT/ace/config.h FILE [if you use a link to a
platform-

	    specific file, simply state which one]:

	 

	#ifndef ACE_CONFIG_H

	#define ACE_CONFIG_H

	#define ACE_DEFAULT_BASE_ADDR ((char *) 0x80000000) 

	#define ACE_DEFAULT_MAX_SOCKET_BUFSIZ 65535 

	#define ACE_EXPLICIT_TEMPLATE_DESTRUCTOR_TAKES_ARGS 1 

	#define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R 1 

	#define ACE_HAS_3_PARAM_READDIR_R 1 

	#define ACE_HAS_3_PARAM_WCSTOK 1 

	#define ACE_HAS_4_4BSD_SENDMSG_RECVMSG 1 

	#define ACE_HAS_AIO_CALLS 1 

	#define ACE_HAS_ALT_CUSERID 1 

	#define ACE_HAS_AUTOMATIC_INIT_FINI 1 

	#define ACE_HAS_BIG_FD_SET 1 

	#define ACE_HAS_BYTESWAP_H 1 

	#define ACE_HAS_CLOCK_GETTIME 1 

	#define ACE_HAS_CLOCK_SETTIME 1 

	#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES 1 

	#define ACE_HAS_CPLUSPLUS_HEADERS 1 

	#define ACE_HAS_CPU_SET_T 1 

	#define ACE_HAS_DIRENT 1 

	#define ACE_HAS_EXCEPTIONS 1 

	#define ACE_HAS_GETIFADDRS 1 

	#define ACE_HAS_GETPAGESIZE 1 

	#define ACE_HAS_GETRUSAGE 1 

	#define ACE_HAS_GETRUSAGE_PROTOTYPE 1 

	#define ACE_HAS_GNU_CSTRING_H 1 

	#define ACE_HAS_GPERF 1 

	#define ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT 1 

	#define ACE_HAS_ICMP_SUPPORT 1 

	#define ACE_HAS_INT16_T 1 

	#define ACE_HAS_INT32_T 1 

	#define ACE_HAS_INT64_T 1 

	#define ACE_HAS_INT8_T 1 

	#define ACE_HAS_IP_MULTICAST 1 

	#define ACE_HAS_ISASTREAM_PROTOTYPE 1 

	#define ACE_HAS_LSEEK64 1 

	#define ACE_HAS_MEMCHR 1 

	#define ACE_HAS_MKDIR 1 

	#define ACE_HAS_MSG 1 

	#define ACE_HAS_MUTEX_TIMEOUTS 1 

	#define ACE_HAS_NANOSLEEP 1 

	#define ACE_HAS_NEW_NOTHROW 1 

	#define ACE_HAS_NEW_NO_H 1 

	#define ACE_HAS_NONCONST_SELECT_TIMEVAL 1 

	#define ACE_HAS_NONCONST_SWAB 1 

	#define ACE_HAS_PENTIUM 1 

	#define ACE_HAS_POLL 1 

	#define ACE_HAS_POSITION_INDEPENDENT_POINTERS 1 

	#define ACE_HAS_POSIX_GETPWNAM_R 1 

	#define ACE_HAS_POSIX_NONBLOCK 1 

	#define ACE_HAS_POSIX_REALTIME_SIGNALS 1 

	#define ACE_HAS_POSIX_SEM 1 

	#define ACE_HAS_POSIX_TIME 1 

	#define ACE_HAS_PROC_FS 1 

	#define ACE_HAS_PTHREADS 1 

	#define ACE_HAS_PTHREADS_STD 1 

	#define ACE_HAS_PTHREADS_UNIX98_EXT 1 

	#define ACE_HAS_PTHREAD_GETCONCURRENCY 1 

	#define ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP 1 

	#define ACE_HAS_PTHREAD_PROCESS_ENUM 1 

	#define ACE_HAS_PTHREAD_SETCONCURRENCY 1 

	#define ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE 1 

	#define ACE_HAS_P_READ_WRITE 1 

	#define ACE_HAS_REACTOR_NOTIFICATION_QUEUE 1 

	#define ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS 1 

	#define ACE_HAS_REENTRANT_FUNCTIONS 1 

	#define ACE_HAS_SCHED_GETAFFINITY 1 

	#define ACE_HAS_SCHED_SETAFFINITY 1 

	#define ACE_HAS_SHM_OPEN 1 

	#define ACE_HAS_SIGACTION_CONSTP2 1 

	#define ACE_HAS_SIGINFO_T 1 

	#define ACE_HAS_SIGSUSPEND 1 

	#define ACE_HAS_SIGTIMEDWAIT 1 

	#define ACE_HAS_SIGWAIT 1 

	#define ACE_HAS_SIG_ATOMIC_T 1 

	#define ACE_HAS_SIG_C_FUNC 1 

	#define ACE_HAS_SNPRINTF 1 

	#define ACE_HAS_SOCKADDR_MSG_NAME 1 

	#define ACE_HAS_SOCKLEN_T 1 

	#define ACE_HAS_SSIZE_T 1 

	#define ACE_HAS_STANDARD_CPP_LIBRARY 1 

	#define ACE_HAS_STDCPP_STL_INCLUDES 1 

	#define ACE_HAS_STD_TEMPLATE_CLASS_MEMBER_SPECIALIZATION 1 

	#define ACE_HAS_STD_TEMPLATE_SPECIALIZATION 1 

	#define ACE_HAS_STRBUF_T 1 

	#define ACE_HAS_STREAMS 1 

	#define ACE_HAS_STRERROR 1 

	#define ACE_HAS_STRINGS 1 

	#define ACE_HAS_STRING_CLASS 1 

	#define ACE_HAS_STRNLEN 1 

	#define ACE_HAS_SVR4_DYNAMIC_LINKING 1 

	#define ACE_HAS_SYSCTL 1 

	#define ACE_HAS_SYSV_IPC 1 

	#define ACE_HAS_SYS_ERRLIST 1 

	#define ACE_HAS_SYS_SIGLIST 1 

	#define ACE_HAS_SYS_SYSCALL_H 1 

	#define ACE_HAS_TEMPLATE_TYPEDEFS 1 

	#define ACE_HAS_TERMIO 1 

	#define ACE_HAS_TERMIOS 1 

	#define ACE_HAS_THREADS 1 

	#define ACE_HAS_THREAD_SPECIFIC_STORAGE 1 

	#define ACE_HAS_TIMEZONE 1 

	#define ACE_HAS_TIMEZONE_GETTIMEOFDAY 1 

	#define ACE_HAS_TYPENAME_KEYWORD 1 

	#define ACE_HAS_UALARM 1 

	#define ACE_HAS_UCONTEXT_T 1 

	#define ACE_HAS_UINT16_T 1 

	#define ACE_HAS_UINT32_T 1 

	#define ACE_HAS_UINT64_T 1 

	#define ACE_HAS_UINT8_T 1 

	#define ACE_HAS_VFWPRINTF 1 

	#define ACE_HAS_VOIDPTR_MMAP 1 

	#define ACE_HAS_VOIDPTR_SOCKOPT 1 

	#define ACE_HAS_VSWPRINTF 1 

	#define ACE_HAS_WCHAR 1 

	#define ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR 1 

	#define ACE_HAS_XPG4_MULTIBYTE_CHAR 1 

	#define ACE_INT64_TYPE signed long 

	#define ACE_IOCTL_TYPE_ARG2 int 

	#define ACE_LACKS_GETIPNODEBYADDR 1 

	#define ACE_LACKS_GETIPNODEBYNAME 1 

	#define ACE_LACKS_IOSTREAM_FX 1 

	#define ACE_LACKS_ITOW 1 

	#define ACE_LACKS_LINEBUFFERED_STREAMBUF 1 

	#define ACE_LACKS_MSG_ACCRIGHTS 1 

	#define ACE_LACKS_NETDB_REENTRANT_FUNCTIONS 1 

	#define ACE_LACKS_PRAGMA_ONCE 1 

	#define ACE_LACKS_PRI_T 1 

	#define ACE_LACKS_PTHREAD_THR_SIGSETMASK 1 

	#define ACE_LACKS_RWLOCK_T 1 

	#define ACE_LACKS_SIGINFO_H 1 

	#define ACE_LACKS_TIMEDWAIT_PROTOTYPES 1 

	#define ACE_LACKS_TIMESPEC_T 1 

	#define ACE_LACKS_UNBUFFERED_STREAMBUF 1 

	#define ACE_LACKS_U_LONGLONG_T 1 

	#define ACE_LACKS_WCSNICMP 1 

	#define ACE_MT_SAFE 1 

	#define ACE_NDEBUG 1 

	#define ACE_NEW_THROWS_EXCEPTIONS 1 

	#define ACE_SIZEOF_DOUBLE 8 

	#define ACE_SIZEOF_FLOAT 4 

	#define ACE_SIZEOF_INT 4 

	#define ACE_SIZEOF_LONG 8 

	#define ACE_SIZEOF_LONG_DOUBLE 16 

	#define ACE_SIZEOF_LONG_LONG 8 

	#define ACE_SIZEOF_SHORT 2 

	#define ACE_SIZEOF_VOID_P 8 

	#define ACE_SIZEOF_WCHAR 4 

	#define ACE_SIZE_T_FORMAT_SPECIFIER "%lu"

	#define ACE_SSIZE_T_FORMAT_SPECIFIER "%ld"

	#define ACE_TEMPLATES_REQUIRE_SOURCE 1

	#define ACE_TIMER_SKEW (1000 * 10)

	#define ACE_UINT64_FORMAT_SPECIFIER "%lu"

	#define ACE_UINT64_TYPE unsigned long

	#define ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB 1 

	#define ACE_USE_RCSID 0 

	#define HAVE_DIRENT_H 1 

	#define HAVE_DLFCN_H 1 

	#define HAVE_FSTREAM 1 

	#define HAVE_INTTYPES_H 1 

	#define HAVE_IOMANIP 1 

	#define HAVE_IOS 1 

	#define HAVE_IOSTREAM 1 

	#define HAVE_ISTREAM 1 

	#define HAVE_MEMORY_H 1 

	#define HAVE_OSTREAM 1 

	#define HAVE_STDINT_H 1 

	#define HAVE_STDLIB_H 1 

	#define HAVE_STREAMBUF 1 

	#define HAVE_STRFTIME 1 

	#define HAVE_STRINGS_H 1 

	#define HAVE_STRING_H 1 

	#define HAVE_SYS_STAT_H 1 

	#define HAVE_SYS_TYPES_H 1 

	#define HAVE_SYS_WAIT_H 1 

	#define HAVE_UNISTD_H 1 

	#define PACKAGE_BUGREPORT "ace-bugs at cs.wustl.edu"

	#define PACKAGE_NAME "ACE"

	#define PACKAGE_STRING "ACE 5.6"

	#define PACKAGE_TARNAME "ace"

	#define PACKAGE_VERSION "5.6"

	#define SIZEOF_DOUBLE 8

	#define SIZEOF_FLOAT 4

	#define SIZEOF_INT 4

	#define SIZEOF_LONG 8

	#define SIZEOF_LONG_DOUBLE 16

	#define SIZEOF_LONG_LONG 8

	#define SIZEOF_SHORT 2

	#define SIZEOF_SIGNED_CHAR 1

	#define SIZEOF_VOID_P 8

	#define SIZEOF_WCHAR_T 4

	#define STDC_HEADERS 1

	#define __ACE_INLINE__ 1

	#endif  

	 

	    THE $ACE_ROOT/include/makeinclude/platform_macros.GNU FILE [if
you

	    use a link to a platform-specific file, simply state which one

	    (unless this isn't used in this case, e.g., with Microsoft
Visual

	    C++)]:

	(Note present)

	 

	    CONTENTS OF
$ACE_ROOT/bin/MakeProjectCreator/config/default.features

	    (used by MPC when you generate your own makefiles):

	(Note present)

	 

	    AREA/CLASS/EXAMPLE AFFECTED:

	ACE_OS::gethrtime  (OS_NS_time.inl)

	 

	    DOES THE PROBLEM AFFECT:

	        EXECUTION

	 

	    SYNOPSIS:

	At runtime, the ACE_OS::gethrtime call produces unreliable and
random results on the x86_64 architecture.

	 

	    DESCRIPTION:

	Using the ACE_High_Res_Timer, it was noticed that with a high
frequency, the elapsed time reported was incorrect.  Namely, operations that
completed in sub second timeframes were being reported to have taken 207
years to complete.

	 

	The problem was traced back to the inline assembler used for the x86
architecture when lacking an OS supplied gethrtime implementation. For an
explanation of why the assembler is incorrect, please refer to:
http://en.wikipedia.org/wiki/Rdtsc#C

	 

	Essentially what occurs is the current implementation only correctly
retrieves the lower 32-bits from the rdstc invocation due to differences in
register layout between x86 and x86_64.  The upper 32-bits returned is
random garbage left in the upper 32-bits of %rax.

	 

	From the Intel Assembler Reference for instruction RDTSC:

	 

	Loads the current value of the processor's time-stamp counter into
the EDX:EAX registers. The time-stamp counter is contained in a 64-bit MSR.
The high-order 32 bits of the MSR are loaded into the EDX register, and the
low-order 32 bits are loaded into the EAX register.

	 

	    REPEAT BY:

	 

	#include <iostream>

	#include <ace/High_Res_Timer.h>

	 

	int main(int argc, const char** argv[])

	{

	       ACE_High_Res_Timer timer;

	       timer.start();

	 

	       ACE_hrtime_t last = 0;

	       const unsigned long max = 2000000000;

	                     

	       while(true)

	       {

	              timer.stop();

	 

	              ACE_hrtime_t nanos;

	              timer.elapsed_time(nanos);

	 

	              std::cout << "Elapsed: " << nanos << std::endl;

	 

	              if ((nanos - last) > max)

	              {

	                     std::cerr << "Tight-loop time elapsed " <<
(nanos - last) << "ns exceeded thresold " << max << "ns" << std::endl;

	                     return 1;

	              }

	 

	              last = nanos;

	       }

	 

	       return 0;

	}

	 

	    SAMPLE FIX/WORKAROUND:

	Modify ACE_OS::gethrtime implementation from:

	  asm volatile ("rdtsc" : "=A" (now) : : "memory");

	 

	To:

	     unsigned int a,d;

	     asm volatile("rdtsc" : "=a" (a), "=d" (d));

	     now = ((unsigned long)a) | (((unsigned long)d)<<32);

	 

	Thanks,

	Nathan Ernst

	nathan.ernst at citadelgroup.com

	 

	 

	
----------------------------------------------------------------------------
---------------------
	-------------------------
	
	CONFIDENTIALITY AND SECURITY NOTICE 
	
	The contents of this message and any attachments may be privileged,
confidential and proprietary and also may be covered by the Electronic
Communications Privacy Act. This message is not intended to be used by, and
should not be relied upon in any way by, any third party. If you are not an
intended recipient, please inform the sender of the transmission error and
delete this message immediately without reading, disseminating, distributing
or copying the contents. Citadel makes no assurances that this e-mail and
any attachments are free of viruses and other harmful code.
	
	



More information about the Ace-users mailing list