diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-05-15 22:26:55 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-05-15 22:26:55 +0000 |
commit | ec42afe8e8d4952567723685999a6a7990ec5d08 (patch) | |
tree | 684ed84f1bc373a59ecd5bc4d8377c4aaae1db68 | |
parent | f0a1acd242b0abcf4cc0ec15aec3d508e138dfe5 (diff) | |
download | ATCD-ec42afe8e8d4952567723685999a6a7990ec5d08.tar.gz |
ChangeLogTag:Mon May 15 15:14:41 2000 Carlos O'Ryan <coryan@uci.edu>
-rw-r--r-- | ChangeLog | 37 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-02a | 37 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-03a | 37 | ||||
-rw-r--r-- | ace/CDR_Stream.cpp | 507 | ||||
-rw-r--r-- | ace/CDR_Stream.h | 16 | ||||
-rw-r--r-- | ace/CDR_Stream.i | 168 | ||||
-rw-r--r-- | tests/CDR_Array_Test.cpp | 899 | ||||
-rw-r--r-- | tests/CDR_Array_Test.dsp | 101 | ||||
-rw-r--r-- | tests/CDR_Array_Test.icc | 15 | ||||
-rw-r--r-- | tests/CDR_File_Test.cpp | 194 | ||||
-rw-r--r-- | tests/Makefile | 1 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/Makefile.bor | 2 | ||||
-rw-r--r-- | tests/run_tests.bat | 2 | ||||
-rw-r--r-- | tests/run_tests.lst | 1 | ||||
-rw-r--r-- | tests/run_tests.vxworks | 11 | ||||
-rw-r--r-- | tests/tests.dsw | 12 |
17 files changed, 1923 insertions, 119 deletions
diff --git a/ChangeLog b/ChangeLog index bdad33d7c20..f9f90b821f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +Mon May 15 15:14:41 2000 Carlos O'Ryan <coryan@uci.edu> + + * ace/CDR_Stream.h: + * ace/CDR_Stream.i: + * ace/CDR_Stream.cpp: + Cristian Ferretti <cristian_ferretti@yahoo.com> has contributed + a number of optimizations to the but swapping code for CDR + streams. The optimizations include loop unrolling for 32-bit + and 64-bit architectures, use of special assembly instructions + for x86-based platforms and use of bit operations (instead of + memory manipulation) for other processors. + + * tests/Makefile: + * tests/Makefile.am: + * tests/Makefile.bor: + * tests/run_tests.bat: + * tests/run_tests.lst: + * tests/run_tests.vxworks: + * tests/tests.dsw: + * tests/CDR_Array_Test.cpp: + * tests/CDR_Array_Test.dsp: + * tests/CDR_Array_Test.icc: + New test to verify that the array operations in the CDR classes + actually work, this is specially critical because the new + versions unroll loop, perform assembly instructions that work + best when the alingment is right, etc. + + * tests/CDR_File_Test.cpp: + The test was extended. Now we can save a file in one platform + and load it (manually) in another platform, to verify that byte + swapping actually works. + Both tests were contributed by Cristian Ferretti + <cristian_ferretti@yahoo.com>, which is good because all this + voodoo programming needs testing. + The changes were tested using PA-RISC, Alphas, Sparcs and + finally Pentiums in various forms and using several compilers. + Mon May 15 14:01:23 2000 Ossama Othman <ossama@uci.edu> * ace/OS.h: diff --git a/ChangeLogs/ChangeLog-02a b/ChangeLogs/ChangeLog-02a index bdad33d7c20..f9f90b821f6 100644 --- a/ChangeLogs/ChangeLog-02a +++ b/ChangeLogs/ChangeLog-02a @@ -1,3 +1,40 @@ +Mon May 15 15:14:41 2000 Carlos O'Ryan <coryan@uci.edu> + + * ace/CDR_Stream.h: + * ace/CDR_Stream.i: + * ace/CDR_Stream.cpp: + Cristian Ferretti <cristian_ferretti@yahoo.com> has contributed + a number of optimizations to the but swapping code for CDR + streams. The optimizations include loop unrolling for 32-bit + and 64-bit architectures, use of special assembly instructions + for x86-based platforms and use of bit operations (instead of + memory manipulation) for other processors. + + * tests/Makefile: + * tests/Makefile.am: + * tests/Makefile.bor: + * tests/run_tests.bat: + * tests/run_tests.lst: + * tests/run_tests.vxworks: + * tests/tests.dsw: + * tests/CDR_Array_Test.cpp: + * tests/CDR_Array_Test.dsp: + * tests/CDR_Array_Test.icc: + New test to verify that the array operations in the CDR classes + actually work, this is specially critical because the new + versions unroll loop, perform assembly instructions that work + best when the alingment is right, etc. + + * tests/CDR_File_Test.cpp: + The test was extended. Now we can save a file in one platform + and load it (manually) in another platform, to verify that byte + swapping actually works. + Both tests were contributed by Cristian Ferretti + <cristian_ferretti@yahoo.com>, which is good because all this + voodoo programming needs testing. + The changes were tested using PA-RISC, Alphas, Sparcs and + finally Pentiums in various forms and using several compilers. + Mon May 15 14:01:23 2000 Ossama Othman <ossama@uci.edu> * ace/OS.h: diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a index bdad33d7c20..f9f90b821f6 100644 --- a/ChangeLogs/ChangeLog-03a +++ b/ChangeLogs/ChangeLog-03a @@ -1,3 +1,40 @@ +Mon May 15 15:14:41 2000 Carlos O'Ryan <coryan@uci.edu> + + * ace/CDR_Stream.h: + * ace/CDR_Stream.i: + * ace/CDR_Stream.cpp: + Cristian Ferretti <cristian_ferretti@yahoo.com> has contributed + a number of optimizations to the but swapping code for CDR + streams. The optimizations include loop unrolling for 32-bit + and 64-bit architectures, use of special assembly instructions + for x86-based platforms and use of bit operations (instead of + memory manipulation) for other processors. + + * tests/Makefile: + * tests/Makefile.am: + * tests/Makefile.bor: + * tests/run_tests.bat: + * tests/run_tests.lst: + * tests/run_tests.vxworks: + * tests/tests.dsw: + * tests/CDR_Array_Test.cpp: + * tests/CDR_Array_Test.dsp: + * tests/CDR_Array_Test.icc: + New test to verify that the array operations in the CDR classes + actually work, this is specially critical because the new + versions unroll loop, perform assembly instructions that work + best when the alingment is right, etc. + + * tests/CDR_File_Test.cpp: + The test was extended. Now we can save a file in one platform + and load it (manually) in another platform, to verify that byte + swapping actually works. + Both tests were contributed by Cristian Ferretti + <cristian_ferretti@yahoo.com>, which is good because all this + voodoo programming needs testing. + The changes were tested using PA-RISC, Alphas, Sparcs and + finally Pentiums in various forms and using several compilers. + Mon May 15 14:01:23 2000 Ossama Othman <ossama@uci.edu> * ace/OS.h: diff --git a/ace/CDR_Stream.cpp b/ace/CDR_Stream.cpp index 985f86cdaea..bd8f2d8fd0f 100644 --- a/ace/CDR_Stream.cpp +++ b/ace/CDR_Stream.cpp @@ -8,6 +8,453 @@ ACE_RCSID(ace, CDR_Stream, "$Id$") +// +// See comments in CDR_Stream.i about optimization cases for swap_XX_array. +// + +void +ACE_CDR::swap_2_array (const char* orig, char* target, size_t n) +{ + // ACE_ASSERT(n > 0); The caller checks that n > 0 + + // Later, we try to read in 32 or 64 bit chunks, + // so make sure we don't do that for unaligned addresses. +#if ACE_SIZEOF_LONG == 8 + const char* const o8 = ACE_ptr_align_binary(orig, 8); + while (orig < o8 && n > 0) + { + ACE_CDR::swap_2 (orig, target); + orig += 2; + target += 2; + --n; + } +#else + const char* const o4 = ACE_ptr_align_binary(orig, 4); + // this is an _if_, not a _while_. The mistmatch can only be by 2. + if (orig != o4) + { + ACE_CDR::swap_2 (orig, target); + orig += 2; + target += 2; + --n; + } +#endif + if (n == 0) + return; + + // + // Loop unrolling. Here be dragons. + // + + // (n & (~3)) is the greatest multiple of 4 not bigger than n. + // In the while loop ahead, orig will move over the array by 8 byte + // increments (4 elements of 2 bytes). + // end marks our barrier for not falling outside. + const char* const end = orig + 2*(n & (~3)); + + // See if we're aligned for writting in 64 or 32 bit chunks... +#if ACE_SIZEOF_LONG == 8 + if (target == ACE_ptr_align_binary(target, 8)) +#else + if (target == ACE_ptr_align_binary(target, 4)) +#endif + { + while (orig < end) + { +#if defined(ACE_HAS_PENTIUM) && defined(__GNUG__) + unsigned int a = + * ACE_reinterpret_cast(const unsigned int*, orig); + unsigned int b = + * ACE_reinterpret_cast(const unsigned int*, orig + 4); + asm( "bswap %1" : "=r" (a) : "0" (a) ); + asm( "bswap %1" : "=r" (b) : "0" (b) ); + asm( "rol $16, %1" : "=r" (a) : "0" (a) ); + asm( "rol $16, %1" : "=r" (b) : "0" (b) ); + * ACE_reinterpret_cast(unsigned int*, target) = a; + * ACE_reinterpret_cast(unsigned int*, target + 4) = b; +#elif defined(ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ecx, orig; + __asm mov edx, target; + __asm mov eax, [ecx]; + __asm mov ebx, 4[ecx]; + __asm bswap eax; + __asm bswap ebx; + __asm rol eax, 16; + __asm rol ebx, 16; + __asm mov [edx], eax; + __asm mov 4[edx], ebx; +#elif ACE_SIZEOF_LONG == 8 + // 64 bit architecture. + register unsigned long a = + * ACE_reinterpret_cast(const unsigned long*, orig); + + register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8; + register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8; + + a = (a1 | a2); + + * ACE_reinterpret_cast(unsigned long*, target) = a; +#else + register ACE_UINT32 a = + * ACE_reinterpret_cast(const ACE_UINT32*, orig); + register ACE_UINT32 b = + * ACE_reinterpret_cast(const ACE_UINT32*, orig + 4); + + register ACE_UINT32 a1 = (a & 0x00ff00ffU) << 8; + register ACE_UINT32 b1 = (b & 0x00ff00ffU) << 8; + register ACE_UINT32 a2 = (a & 0xff00ff00U) >> 8; + register ACE_UINT32 b2 = (b & 0xff00ff00U) >> 8; + + a = (a1 | a2); + b = (b1 | b2); + + * ACE_reinterpret_cast(ACE_UINT32*, target) = a; + * ACE_reinterpret_cast(ACE_UINT32*, target + 4) = b; +#endif + orig += 8; + target += 8; + } + } + else + { + // We're out of luck. We have to write in 2 byte chunks. + while (orig < end) + { +#if defined(ACE_HAS_PENTIUM) && defined(__GNUG__) + unsigned int a = + * ACE_reinterpret_cast(const unsigned int*, orig); + unsigned int b = + * ACE_reinterpret_cast(const unsigned int*, orig + 4); + asm( "bswap %1" : "=r" (a) : "0" (a) ); + asm( "bswap %1" : "=r" (b) : "0" (b) ); + // We're little endian. + * ACE_reinterpret_cast(unsigned short*, target + 2) + = (unsigned short) (a & 0xffff); + * ACE_reinterpret_cast(unsigned short*, target + 6) + = (unsigned short) (b & 0xffff); + asm( "shrl $16, %1" : "=r" (a) : "0" (a) ); + asm( "shrl $16, %1" : "=r" (b) : "0" (b) ); + * ACE_reinterpret_cast(unsigned short*, target + 0) + = (unsigned short) (a & 0xffff); + * ACE_reinterpret_cast(unsigned short*, target + 4) + = (unsigned short) (b & 0xffff); +#elif defined(ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ecx, orig; + __asm mov edx, target; + __asm mov eax, [ecx]; + __asm mov ebx, 4[ecx]; + __asm bswap eax; + __asm bswap ebx; + // We're little endian. + __asm mov 2[edx], ax; + __asm mov 6[edx], bx; + __asm shr eax, 16; + __asm shr ebx, 16; + __asm mov 0[edx], ax; + __asm mov 4[edx], bx; +#elif ACE_SIZEOF_LONG == 8 + // 64 bit architecture. + register unsigned long a = + * ACE_reinterpret_cast(const unsigned long*, orig); + + register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8; + register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8; + + a = (a1 | a2); + + ACE_UINT16 b1 = ACE_static_cast(ACE_UINT16, (a >> 48)); + ACE_UINT16 b2 = ACE_static_cast(ACE_UINT16, ((a >> 32) & 0xffff)); + ACE_UINT16 b3 = ACE_static_cast(ACE_UINT16, ((a >> 16) & 0xffff)); + ACE_UINT16 b4 = ACE_static_cast(ACE_UINT16, (a & 0xffff)); + +#if defined(ACE_LITTLE_ENDIAN) + * ACE_reinterpret_cast(ACE_UINT16*, target) = b4; + * ACE_reinterpret_cast(ACE_UINT16*, target + 2) = b3; + * ACE_reinterpret_cast(ACE_UINT16*, target + 4) = b2; + * ACE_reinterpret_cast(ACE_UINT16*, target + 6) = b1; +#else + * ACE_reinterpret_cast(ACE_UINT16*, target) = b1; + * ACE_reinterpret_cast(ACE_UINT16*, target + 2) = b2; + * ACE_reinterpret_cast(ACE_UINT16*, target + 4) = b3; + * ACE_reinterpret_cast(ACE_UINT16*, target + 6) = b4; +#endif +#else + register ACE_UINT32 a = + * ACE_reinterpret_cast(const ACE_UINT32*, orig); + register ACE_UINT32 b = + * ACE_reinterpret_cast(const ACE_UINT32*, orig + 4); + + register ACE_UINT32 a1 = (a & 0x00ff00ff) << 8; + register ACE_UINT32 b1 = (b & 0x00ff00ff) << 8; + register ACE_UINT32 a2 = (a & 0xff00ff00) >> 8; + register ACE_UINT32 b2 = (b & 0xff00ff00) >> 8; + + a = (a1 | a2); + b = (b1 | b2); + + ACE_UINT32 c1 = ACE_static_cast(ACE_UINT16, (a >> 16)); + ACE_UINT32 c2 = ACE_static_cast(ACE_UINT16, (a & 0xffff)); + ACE_UINT32 c3 = ACE_static_cast(ACE_UINT16, (b >> 16)); + ACE_UINT32 c4 = ACE_static_cast(ACE_UINT16, (b & 0xffff)); + +#if defined(ACE_LITTLE_ENDIAN) + * ACE_reinterpret_cast(ACE_UINT16*, target) = c2; + * ACE_reinterpret_cast(ACE_UINT16*, target + 2) = c1; + * ACE_reinterpret_cast(ACE_UINT16*, target + 4) = c4; + * ACE_reinterpret_cast(ACE_UINT16*, target + 6) = c3; +#else + * ACE_reinterpret_cast(ACE_UINT16*, target) = c1; + * ACE_reinterpret_cast(ACE_UINT16*, target + 2) = c2; + * ACE_reinterpret_cast(ACE_UINT16*, target + 4) = c3; + * ACE_reinterpret_cast(ACE_UINT16*, target + 6) = c4; +#endif +#endif + + orig += 8; + target += 8; + } + } + + // (n & 3) == (n % 4). + switch (n&3) { + case 3: + ACE_CDR::swap_2 (orig, target); + orig += 2; + target += 2; + case 2: + ACE_CDR::swap_2 (orig, target); + orig += 2; + target += 2; + case 1: + ACE_CDR::swap_2 (orig, target); + } +} + +void +ACE_CDR::swap_4_array (const char* orig, char* target, size_t n) +{ + // ACE_ASSERT(n > 0); The caller checks that n > 0 + +#if ACE_LONG_SIZE == 8 + // Later, we read from *orig in 64 bit chunks, + // so make sure we don't generate unaligned readings. + const char* const o8 = ACE_ptr_align_binary(orig, 8); + // The mistmatch can only be by 4. + if (orig != o8) + { + ACE_CDR::swap_4 (orig, target); + orig += 4; + target += 4; + --n; + } +#endif + if (n == 0) + return; + + // + // Loop unrolling. Here be dragons. + // + + // (n & (~3)) is the greatest multiple of 4 not bigger than n. + // In the while loop, orig will move over the array by 16 byte + // increments (4 elements of 4 bytes). + // ends marks our barrier for not falling outside. + const char* const end = orig + 4*(n & (~3)); + +#if ACE_LONG_SIZE == 8 + // 64 bits architecture. + // See if we can write in 8 byte chunks. + if (target == ACE_ptr_align_binary(target, 8)) + { + while (orig < end) + { + register unsigned long a = + * ACE_reinterpret_cast(const long*, orig); + register unsigned long b = + * ACE_reinterpret_cast(const long*, orig + 8); + + register unsigned long a84 = (a & 0x000000ff000000ffL) << 24; + register unsigned long b84 = (b & 0x000000ff000000ffL) << 24; + register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8; + register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8; + register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8; + register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8; + register unsigned long a51 = (a & 0xff000000ff000000L) >> 24; + register unsigned long b51 = (b & 0xff000000ff000000L) >> 24; + + a = (a84 | a73 | a62 | a51); + b = (b84 | b73 | b62 | b51); + + * ACE_reinterpret_cast(long*, target) = a; + * ACE_reinterpret_cast(long*, target + 8) = b; + + orig += 16; + target += 16; + } + } + else + { + // We are out of luck, we have to write in 4 byte chunks. + while (orig < end) + { + register unsigned long a = + * ACE_reinterpret_cast(const long*, orig); + register unsigned long b = + * ACE_reinterpret_cast(const long*, orig + 8); + + register unsigned long a84 = (a & 0x000000ff000000ffL) << 24; + register unsigned long b84 = (b & 0x000000ff000000ffL) << 24; + register unsigned long a73 = (a & 0x0000ff000000ff00L) << 8; + register unsigned long b73 = (b & 0x0000ff000000ff00L) << 8; + register unsigned long a62 = (a & 0x00ff000000ff0000L) >> 8; + register unsigned long b62 = (b & 0x00ff000000ff0000L) >> 8; + register unsigned long a51 = (a & 0xff000000ff000000L) >> 24; + register unsigned long b51 = (b & 0xff000000ff000000L) >> 24; + + a = (a84 | a73 | a62 | a51); + b = (b84 | b73 | b62 | b51); + + ACE_UINT32 c1 = ACE_static_cast(ACE_UINT32, (a >> 32)); + ACE_UINT32 c2 = ACE_static_cast(ACE_UINT32, (a & 0xffffffff)); + ACE_UINT32 c3 = ACE_static_cast(ACE_UINT32, (b >> 32)); + ACE_UINT32 c4 = ACE_static_cast(ACE_UINT32, (b & 0xffffffff)); + +#if defined(ACE_LITTLE_ENDIAN) + * ACE_reinterpret_cast(ACE_UINT32*, target + 0) = c2; + * ACE_reinterpret_cast(ACE_UINT32*, target + 4) = c1; + * ACE_reinterpret_cast(ACE_UINT32*, target + 8) = c4; + * ACE_reinterpret_cast(ACE_UINT32*, target + 12) = c3; +#else + * ACE_reinterpret_cast(ACE_UINT32*, target + 0) = c1; + * ACE_reinterpret_cast(ACE_UINT32*, target + 4) = c2; + * ACE_reinterpret_cast(ACE_UINT32*, target + 8) = c3; + * ACE_reinterpret_cast(ACE_UINT32*, target + 12) = c4; +#endif + orig += 16; + target += 16; + } + } + +#else /* ACE_LONG_SIZE != 8 */ + + while (orig < end) + { +#if defined(ACE_HAS_PENTIUM) && defined(__GNUG__) + register unsigned int a = + *ACE_reinterpret_cast(const unsigned int*, orig); + register unsigned int b = + *ACE_reinterpret_cast(const unsigned int*, orig + 4); + register unsigned int c = + *ACE_reinterpret_cast(const unsigned int*, orig + 8); + register unsigned int d = + *ACE_reinterpret_cast(const unsigned int*, orig + 12); + + asm ("bswap %1" : "=r" (a) : "0" (a)); + asm ("bswap %1" : "=r" (b) : "0" (b)); + asm ("bswap %1" : "=r" (c) : "0" (c)); + asm ("bswap %1" : "=r" (d) : "0" (d)); + + *ACE_reinterpret_cast(unsigned int*, target) = a; + *ACE_reinterpret_cast(unsigned int*, target + 4) = b; + *ACE_reinterpret_cast(unsigned int*, target + 8) = c; + *ACE_reinterpret_cast(unsigned int*, target + 12) = d; +#elif defined(ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov eax, orig + __asm mov esi, target + __asm mov edx, [eax] + __asm mov ecx, 4[eax] + __asm mov ebx, 8[eax] + __asm mov eax, 12[eax] + __asm bswap edx + __asm bswap ecx + __asm bswap ebx + __asm bswap eax + __asm mov [esi], edx + __asm mov 4[esi], ecx + __asm mov 8[esi], ebx + __asm mov 12[esi], eax +#else + register ACE_UINT32 a = + * ACE_reinterpret_cast(const ACE_UINT32*, orig); + register ACE_UINT32 b = + * ACE_reinterpret_cast(const ACE_UINT32*, orig + 4); + register ACE_UINT32 c = + * ACE_reinterpret_cast(const ACE_UINT32*, orig + 8); + register ACE_UINT32 d = + * ACE_reinterpret_cast(const ACE_UINT32*, orig + 12); + + // Expect the optimizer reordering this A LOT. + // We leave it this way for clarity. + a = (a << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8) | (a >> 24); + b = (b << 24) | ((b & 0xff00) << 8) | ((b & 0xff0000) >> 8) | (b >> 24); + c = (c << 24) | ((c & 0xff00) << 8) | ((c & 0xff0000) >> 8) | (c >> 24); + d = (d << 24) | ((d & 0xff00) << 8) | ((d & 0xff0000) >> 8) | (d >> 24); + + * ACE_reinterpret_cast(ACE_UINT32*, target) = a; + * ACE_reinterpret_cast(ACE_UINT32*, target + 4) = b; + * ACE_reinterpret_cast(ACE_UINT32*, target + 8) = c; + * ACE_reinterpret_cast(ACE_UINT32*, target + 12) = d; +#endif + + orig += 16; + target += 16; + } + +#endif /* ACE_LONG_SIZE == 8 */ + + // (n & 3) == (n % 4). + switch (n&3) { + case 3: + ACE_CDR::swap_4 (orig, target); + orig += 4; + target += 4; + case 2: + ACE_CDR::swap_4 (orig, target); + orig += 4; + target += 4; + case 1: + ACE_CDR::swap_4 (orig, target); + } +} + +// +// We don't benefit from unrolling in swap_8_array and swap_16_array +// (swap_8 and swap_16 are big enough). +// +void +ACE_CDR::swap_8_array (const char* orig, char* target, size_t n) +{ + // ACE_ASSERT(n > 0); The caller checks that n > 0 + + const char* const end = orig + 8*n; + while (orig < end) + { + swap_8(orig, target); + orig += 8; + target += 8; + } +} + +void +ACE_CDR::swap_16_array (const char* orig, char* target, size_t n) +{ + // ACE_ASSERT(n > 0); The caller checks that n > 0 + + const char* const end = orig + 16*n; + while (orig < end) + { + swap_16(orig, target); + orig += 16; + target += 16; + } +} + int ACE_CDR::grow (ACE_Message_Block *mb, size_t minsize) { @@ -519,38 +966,26 @@ ACE_OutputCDR::write_array (const void *x, } else { - // I cannot see any fast way out of this.... - typedef void (*SWAPPER)(const char *, char *); - SWAPPER swapper; + const char *source = ACE_reinterpret_cast (const char *, x); switch (size) { case 2: - swapper = ACE_CDR::swap_2; - break; + ACE_CDR::swap_2_array (source, buf, length); + return 1; case 4: - swapper = ACE_CDR::swap_4; - break; + ACE_CDR::swap_4_array (source, buf, length); + return 1; case 8: - swapper = ACE_CDR::swap_8; - break; + ACE_CDR::swap_8_array (source, buf, length); + return 1; case 16: - swapper = ACE_CDR::swap_16; - break; + ACE_CDR::swap_16_array (source, buf, length); + return 1; default: // TODO: print something? this->good_bit_ = 0; return 0; } - - const char *source = ACE_reinterpret_cast (const char *, x); - const char *end = source + size*length; - - for (; source != end; source += size, buf += size) - { - (*swapper)(source, buf); - } - - return 1; } #endif /* ACE_ENABLE_SWAP_ON_WRITE */ } @@ -811,41 +1246,29 @@ ACE_InputCDR::read_array (void* x, char* buf; if (this->adjust (size * length, align, buf) == 0) { -#if !defined (ACE_DISABLE_SWAP_ON_READ) +#if defined (ACE_DISABLE_SWAP_ON_READ) + ACE_OS::memcpy (x, buf, size*length); +#else if (!this->do_byte_swap_ || size == 1) { ACE_OS::memcpy (x, buf, size*length); } else { - // I cannot see any fast way out of this.... char *target = ACE_reinterpret_cast (char*, x); - char *end = target + size*length; switch (size) { case 2: - for (; target != end; target += size, buf += size) - { - ACE_CDR::swap_2 (buf, target); - } - break; + ACE_CDR::swap_2_array (buf, target, length); + break; case 4: - for (; target != end; target += size, buf += size) - { - ACE_CDR::swap_4 (buf, target); - } + ACE_CDR::swap_4_array (buf, target, length); break; case 8: - for (; target != end; target += size, buf += size) - { - ACE_CDR::swap_8 (buf, target); - } + ACE_CDR::swap_8_array (buf, target, length); break; case 16: - for (; target != end; target += size, buf += size) - { - ACE_CDR::swap_16 (buf, target); - } + ACE_CDR::swap_16_array (buf, target, length); break; default: // TODO: print something? @@ -853,8 +1276,6 @@ ACE_InputCDR::read_array (void* x, return 0; } } -#else - ACE_OS::memcpy (x, buf, size*length); #endif /* ACE_DISABLE_SWAP_ON_READ */ return this->good_bit_; } diff --git a/ace/CDR_Stream.h b/ace/CDR_Stream.h index 13439e7410c..7adf7e9a383 100644 --- a/ace/CDR_Stream.h +++ b/ace/CDR_Stream.h @@ -103,6 +103,18 @@ public: static void swap_4 (const char *orig, char *target); static void swap_8 (const char *orig, char *target); static void swap_16 (const char *orig, char *target); + static void swap_2_array (const char *orig, + char *target, + size_t length); + static void swap_4_array (const char *orig, + char *target, + size_t length); + static void swap_8_array (const char *orig, + char *target, + size_t length); + static void swap_16_array (const char *orig, + char *target, + size_t length); // Do byte swapping for each basic IDL type size. There exist only // routines to put byte, halfword (2 bytes), word (4 bytes), // doubleword (8 bytes) and quadword (16 byte); because those are @@ -118,7 +130,7 @@ public: // To understand how a "best fit" is computed look at the // algorithm in the code. // Basically the buffers grow exponentially, up to a certain point, - // then the buffer size grows linearly. + // then the buffer size grows linearly. // The advantage of this algorithm is that is rapidly grows to a // large value, but does not explode at the end. @@ -630,7 +642,7 @@ public: // another without requiring any extra memory allocations, data // copies or too many temporaries. Transfer_Contents (ACE_InputCDR &rhs); - + ACE_InputCDR &rhs_; }; ACE_InputCDR (Transfer_Contents rhs); diff --git a/ace/CDR_Stream.i b/ace/CDR_Stream.i index 9fd0c6c142a..33d0d21c685 100644 --- a/ace/CDR_Stream.i +++ b/ace/CDR_Stream.i @@ -3,54 +3,150 @@ // **************************************************************** +// +// The ACE_CDR::swap_X and ACE_CDR::swap_X_array routines are broken +// in 4 cases for optimization: +// +// * x86 Pentium CPU + gnu g++ +// (ACE_HAS_PENTIUM && __GNUG__) +// => gcc x86 inline assembly. +// +// * x86 Pentium CPU and (_MSC_VER) or BORLAND C++) +// (ACE_HAS_PENTIUM && ( _MSC_VER || __BORLANDC__ ) +// => MSC x86 inline assembly. +// +// * 64 bit architecture +// (ACE_SIZEOF_LONG == 8) +// => shift/masks using 64bit words. +// +// * default +// (none of the above) +// => shift/masks using 32bit words. +// +// +// Some things you could find usefull to know if you intend to mess +// with this optimizations for swaps: +// +// * MSVC++ don't assume register values are conserved between +// statements. So you can clobber any register you want, +// whenever you want (well not *anyone* really, see manual). +// The MSVC++ optimizer will try to pick different registers +// for the C++ statements sorrounding your asm block, and if +// it's not possible will use the stack. +// +// * If you clobber registers with asm statements in gcc, you +// better do it in an asm-only function, or save/restore them +// before/after in the stack. If not, sorrounding C statements +// could end using the same registers and big-badda-bum (been +// there, done that...). The big-badda-bum could happen *even +// if you specify the clobbered register in your asm's*. +// Even better, use gcc asm syntax for detecting the register +// asigned to a certain variable so you don't have to clobber any +// register directly. +// + ACE_INLINE void ACE_CDR::swap_2 (const char *orig, char* target) { - target[1] = *orig++; - target[0] = *orig++; +#if defined(ACE_HAS_PENTIUM) +# if defined(__GNUG__) + asm( "movw 0(%0), %%ax" : /* no output */ : "r" (orig) : "%ax"); + asm( "rolw $8, %%ax" : /* no output */ : /* no input */ : "%ax"); + asm( "movw %%ax, 0(%0)" : /* no output */ : "r" (target) : "memory"); +# elif (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ebx, orig; + __asm mov ecx, target; + __asm mov ax, [ebx]; + __asm rol ax, 8; + __asm mov [ecx], ax; +# else + // For CISC Platforms this is faster than shift/masks. + target[1] = orig[0]; + target[0] = orig[1]; +# endif +#else + register ACE_UINT16 usrc = * ACE_reinterpret_cast(const ACE_UINT16*, orig); + register ACE_UINT16* udst = ACE_reinterpret_cast(ACE_UINT16*, target); + *udst = (usrc << 8) | (usrc >> 8); +#endif /* ACE_HAS_PENTIUM */ } ACE_INLINE void -ACE_CDR::swap_4 (const char *orig, char* target) -{ - target [3] = *orig++; - target [2] = *orig++; - target [1] = *orig++; - target [0] = *orig++; +ACE_CDR::swap_4 (const char* orig, char* target) +{ +#if defined(ACE_HAS_PENTIUM) && defined(__GNUG__) + // We have ACE_HAS_PENTIUM, so we know the sizeof's. + register unsigned int j = + *ACE_reinterpret_cast(const unsigned int*, orig); + asm ("bswap %1" : "=r" (j) : "0" (j)); + *ACE_reinterpret_cast(unsigned int*, target) = j; +#elif defined(ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ebx, orig; + __asm mov ecx, target; + __asm mov eax, [ebx]; + __asm bswap eax; + __asm mov [ecx], eax; +#else + register ACE_UINT32 x = * ACE_reinterpret_cast(const ACE_UINT32*, orig); + x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24); + * ACE_reinterpret_cast(ACE_UINT32*, target) = x; +#endif } ACE_INLINE void -ACE_CDR::swap_8 (const char *orig, char* target) -{ - target [7] = *orig++; - target [6] = *orig++; - target [5] = *orig++; - target [4] = *orig++; - target [3] = *orig++; - target [2] = *orig++; - target [1] = *orig++; - target [0] = *orig++; +ACE_CDR::swap_8 (const char* orig, char* target) +{ +#if defined(ACE_HAS_PENTIUM) && defined(__GNUG__) + register unsigned int i = + *ACE_reinterpret_cast(const unsigned int*, orig); + register unsigned int j = + *ACE_reinterpret_cast(const unsigned int*, (orig + 4)); + asm ("bswap %1" : "=r" (i) : "0r" (i)); + asm ("bswap %1" : "=r" (j) : "0r" (j)); + *ACE_reinterpret_cast(unsigned int*, target + 4) = i; + *ACE_reinterpret_cast(unsigned int*, target) = j; +#elif defined(ACE_HAS_PENTIUM) \ + && (defined(_MSC_VER) || defined(__BORLANDC__)) \ + && !defined(ACE_LACKS_INLINE_ASSEMBLY) + __asm mov ecx, orig; + __asm mov edx, target; + __asm mov eax, [ecx]; + __asm mov ebx, 4[ecx]; + __asm bswap eax; + __asm bswap ebx; + __asm mov 4[edx], eax; + __asm mov [edx], ebx; +#elif ACE_SIZEOF_LONG == 8 + // 64 bit architecture. + register unsigned long x = + * ACE_reinterpret_cast(const unsigned long*, orig); + register unsigned long x84 = (x & 0x000000ff000000ffUL) << 24; + register unsigned long x73 = (x & 0x0000ff000000ff00UL) << 8; + register unsigned long x62 = (x & 0x00ff000000ff0000UL) >> 8; + register unsigned long x51 = (x & 0xff000000ff000000UL) >> 24; + x = (x84 | x73 | x62 | x51); + x = (x << 32) | (x >> 32); + *ACE_reinterpret_cast(unsigned long*, target) = x; +#else + register ACE_UINT32 x = + * ACE_reinterpret_cast(const ACE_UINT32*, orig); + register ACE_UINT32 y = + * ACE_reinterpret_cast(const ACE_UINT32*, orig + 4); + x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24); + y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24); + * ACE_reinterpret_cast(ACE_UINT32*, target) = y; + * ACE_reinterpret_cast(ACE_UINT32*, target + 4) = x; +#endif } ACE_INLINE void -ACE_CDR::swap_16 (const char *orig, char* target) -{ - target [15] = *orig++; - target [14] = *orig++; - target [13] = *orig++; - target [12] = *orig++; - target [11] = *orig++; - target [10] = *orig++; - target [9] = *orig++; - target [8] = *orig++; - target [7] = *orig++; - target [6] = *orig++; - target [5] = *orig++; - target [4] = *orig++; - target [3] = *orig++; - target [2] = *orig++; - target [1] = *orig++; - target [0] = *orig++; +ACE_CDR::swap_16 (const char* orig, char* target) +{ + swap_8 (orig + 8, target); + swap_8 (orig, target + 8); } ACE_INLINE void diff --git a/tests/CDR_Array_Test.cpp b/tests/CDR_Array_Test.cpp new file mode 100644 index 00000000000..cca75e89607 --- /dev/null +++ b/tests/CDR_Array_Test.cpp @@ -0,0 +1,899 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// CDR_Array_Test.cpp +// +// = DESCRIPTION +// Checks ACE_OutputCDR::write_XX_array. +// Checks ACE_InputCDR::read_XX_array. +// Checks operator<< and operator>> for CDR Streams in +// each of the basic CDR types. +// Gives a measure of the speed of the ACE CDR streams wrt those operations. +// +// = AUTHORS +// Cristian Ferretti <cristian_ferretti@yahoo.com> +// +// ============================================================================ + +// For measuring time, choose your method: +// Define: +// +// * USE_GETRUSAGE for using ACE_OS::getrusage. +// Ticks only when process is running. +// +// * USE_CLOCK for using clock(2). +// You're on your own, no ACE_OS:: support. +// Ticks only when process is running. +// +// * None of the above for using ACE_High_Res_Timer. +// Ticks independent of running state of process. + +// #define USE_CLOCK +// #define USE_GETRUSAGE + +#if defined(USE_CLOCK) +#include <time.h> +#endif + +#include "test_config.h" +#include "ace/Get_Opt.h" +#include "ace/CDR_Stream.h" +#include "ace/High_Res_Timer.h" + +#if defined(USE_GETRUSAGE) && !defined(ACE_HAS_GETRUSAGE) +#error "Can't define USE_GETRUSAGE on this platform." +#endif + +ACE_RCSID(tests, CDR_Array_Test, "$Id$"); + +// Default number of elements for check buffer, for each tested CDR type. +// Be aware that time will be affected by the buffer fitting/not fitting +// in the cache (ie, if default_total*sizeof(T) bytes fit in the cache). +// Also, you want that your time measuring method has a resolution +// compatible with this buffer size, if not you will end up measuring 0. +// You can change this value with -t option. +static const int default_total = 32*1024; + +// Repeat this many times for each tested CDR type. +// We then take the average time that took for each type and report that. +// You can change this value with -n option. +static const int default_niter = 5; + +// +// A simple cronometer in seconds, that encapsulates our time +// measuring method. +// +class Crono { +public: + Crono() {} + ~Crono() {} + void start () + { +#if defined(USE_CLOCK) + start_ = clock (); +#elif defined(USE_GETRUSAGE) + ACE_OS::getrusage (RUSAGE_SELF, &start_); +#else + timer.start (); +#endif + } + void stop () + { +#if defined(USE_CLOCK) + end_ = clock (); +#elif defined(USE_GETRUSAGE) + ACE_OS::getrusage (RUSAGE_SELF, &end_); +#else + timer.stop (); +#endif + } + double read_seconds () + { +#if defined(USE_CLOCK) + return (end_ - start_) / (double) CLOCKS_PER_SEC; +#elif defined(USE_GETRUSAGE) + timeval diff; + diff.tv_sec = end_.ru_utime.tv_sec - start_.ru_utime.tv_sec; + diff.tv_usec = end_.ru_utime.tv_usec - start_.ru_utime.tv_usec; + while (diff.tv_usec < 0) + { + --diff.tv_sec; + diff.tv_usec += ACE_ONE_SECOND_IN_USECS; + } + + return diff.tv_sec + diff.tv_usec / double(ACE_ONE_SECOND_IN_USECS); +#else + ACE_Time_Value tv; + timer.elapsed_time(tv); + return tv.usec () / 1000000.0; +#endif + } +private: +#if defined(USE_CLOCK) + clock_t start_; + clock_t end_; +#elif defined(USE_GETRUSAGE) + ACE_Rusage start_; + ACE_Rusage end_; +#else + ACE_High_Res_Timer timer; +#endif +}; + +// +// Our test, performed in the constructor. +// T is one of the CDR types. +// H is a helper class (described later). +// +// All this stuff is in a class and not in template functions +// to avoid having to deal with potential template function +// instantiations problems. +// +template<class T, class H> class CDR_Test +{ +public: + CDR_Test (int total, int niter, int use_array); + static void do_test (int total, int niter, int use_array, + char* srcbuf, char* dstbuf, + int src_offset = 0, int dst_offset = 0); + ~CDR_Test (); + + static void ttoh (const T& t, char* s); + +private: + CDR_Test (const CDR_Test&); + CDR_Test& operator= (const CDR_Test&); +}; + +static ACE_UINT32 seal = 0xdeadbeef; + +void +zero (char* p, int k) +{ + char* end = p + k; + while (p < end) + { + *p++ = '\0'; + } +} + +inline int +max (int a, int b) +{ + return (a >= b) ? a : b; +} + +void +memabort () +{ + ACE_ERROR((LM_ERROR, + ACE_TEXT ("new failed, aborting\n"))); + ACE_OS::exit (1); +} + +template<class T, class H> +CDR_Test<T, H>::CDR_Test (int total, int niter, int use_array) +{ + if (total <= 0) + { + return ; + } + + char* srcbuf; + char* dstbuf; + { + const int stotal = + total*sizeof(T) + sizeof(ACE_UINT32) + ACE_CDR::MAX_ALIGNMENT; + + ACE_NEW(srcbuf, char[stotal]); + if (srcbuf == 0) + { + memabort (); + } + zero(srcbuf, stotal); + + ACE_NEW(dstbuf, char[stotal]); + if (dstbuf == 0) + { + memabort (); + } + zero(srcbuf, stotal); + } + + if (use_array) + { + // We want to test all the possible loop unrolling deltas. + int t; + for (t = total - 3; t <= total; t++) + { + int delta; + if (sizeof(long) <= sizeof(T)) + { + delta = 1; + } + else + { + delta = (int) (sizeof(long)/sizeof(T)); + } + + // We want to test all the posible source/destination buffer + // alignment combinations. + int sk; + for (sk = 0; sk < delta; sk++) + { + int dk; + for (dk = 0; dk < delta; dk++) + { + int tdelta = t - max(sk, dk); + + CDR_Test<T, H>::do_test(tdelta, niter, 1, + srcbuf, dstbuf, + sk, dk); + + } + } + } + } + else + { + do_test(total, niter, use_array, srcbuf, dstbuf); + } + + delete[] srcbuf; + delete[] dstbuf; +} + +// Generate a ``interesting'' value for testing at pos `i'. +#if 0 +// egcs-1.0.2 (egcs-2.90.27 980315) generates an internal compiler +// error 9 with this. +template<class T> inline T +checkval<T> (int i) +{ + const int cycle = 17; + return T(i % cycle); +} +#else +const int cycle = 17; +#define checkval(T,x) ((T) ((x) % cycle)) +#endif + +static char digits[16] = { + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' +}; + +// +// Returns in s an hex representation of T's memory. +// (differences in byte order will be noticed in s). +// +// If T = int, +// t = 0xaabbccdd, +// => s = "aabbccdd" for big endian machines, +// s = "ddccbbaa" for little endian machines. +// +template<class T, class H> void +CDR_Test<T, H>::ttoh (const T& t, char* s) +{ + const unsigned char *const p = + ACE_reinterpret_cast(const unsigned char*, &t); + + const unsigned char* q; + for (q = p; q < p + sizeof(t); ++q) + { + int k = ACE_static_cast(int, *q); + *s++ = digits[ k >> 4 ]; + *s++ = digits[ k & 15 ]; + } + + *s = 0; +} + +void +do_seal (char* pos) +{ + char* ps = ACE_reinterpret_cast(char*, &seal); + pos[0] = ps[0]; + pos[1] = ps[1]; + pos[2] = ps[2]; + pos[3] = ps[3]; +} + +int +check_seal (char* pos) +{ + char* ps = ACE_reinterpret_cast(char*, &seal); + return (pos[0] == ps[0] + && pos[1] == ps[1] + && pos[2] == ps[2] + && pos[3] == ps[3]); +} + +// +// returns the alignment of ptr, wrt ACE_CDR::MAX_ALIGNMENT. +// +int +tellalign (char* ptr) +{ + int align = ACE_CDR::MAX_ALIGNMENT; + while (ptr != ACE_ptr_align_binary(ptr, align)) + { + align = align >> 1; + } + + return align; +} + +template<class T, class H> void +CDR_Test<T, H>::do_test (int total, int niter, int use_array, + char* srcbuf, char* dstbuf, + int src_offset, int dst_offset) +{ + if (!use_array) + { + dst_offset = src_offset = 0; + } + + ACE_DEBUG((LM_DEBUG, + ACE_TEXT( "Starting Test for %s: %d elements " ) + ACE_TEXT( "%susing arrays.\n" ), + ACE_TEXT( H::name ), + total, + ((use_array) ? ACE_TEXT( "" ) : ACE_TEXT( "not " )))); + + + if (!use_array && (total % 4) != 0) + { + int lasttotal = total; + total -= (total % 4); + ACE_DEBUG((LM_DEBUG, + ACE_TEXT( "Rounding from %d to %d elements.\n" ), + lasttotal, + total)); + } + + char* src = ACE_ptr_align_binary(srcbuf, sizeof(T)); + T* idata = ACE_reinterpret_cast(T*, src); + idata += src_offset; + src = ACE_reinterpret_cast(char*, idata); + + { + int i; + for (i = 0; i < total; i++) + { + idata[i] = checkval(T, i); + } + } + + ACE_DEBUG((LM_DEBUG, + ACE_TEXT( "Writing data...\n" ))); + + char* toread = 0; + { + ACE_ASSERT(use_array || total % 4 == 0); + + double totalsecs = 0.0; + int n; + for (n = 0; n < niter; n++) + { + int size = sizeof(T)*(dst_offset + total); + ACE_OutputCDR os (dstbuf, size); + + char* const end = os.begin ()->wr_ptr() + size; + + do_seal(end); + + double secs = 0.0; + if (use_array) + { + { + int i; + for (i = 0; i < dst_offset; i++) + { + os << T(0); + } + } + + if (n == 0) + { + ACE_DEBUG((LM_DEBUG, + "* src align = %d, dst align = %d\n", + tellalign (src), + tellalign (os.begin ()->wr_ptr ()))); + } + + + Crono crono; + crono.start (); + H::write_array (os, idata, total); + crono.stop (); + secs = crono.read_seconds (); + } + else + { + int i = 0; + + Crono crono; + crono.start(); + while (i < total) + { + os << idata[i++]; + os << idata[i++]; + os << idata[i++]; + os << idata[i++]; + } + crono.stop (); + secs = crono.read_seconds (); + } + + if (!check_seal(end)) + { + ACE_ERROR((LM_ERROR, + ACE_TEXT( "Broken seal, aborting.\n" ))); + ACE_OS::exit(1); + } + + totalsecs += secs; + + if (n == niter - 1) + { + toread = os.begin()->rd_ptr(); + } + } + + totalsecs = totalsecs / niter; + + ACE_DEBUG((LM_DEBUG, + ACE_TEXT ("Writing to stream %d %s values: %f seconds.\n"), + total, + ACE_TEXT (H::name), + totalsecs)); + } + + { + int i; + for (i = 0; i < total; i++) + { + idata[i] = 0; + } + } + + ACE_DEBUG((LM_DEBUG, + ACE_TEXT( "Reading them back in opposing byte order...\n" ))); + + const int opposite_byte_order = 1 - ACE_CDR_BYTE_ORDER; + + { + double totalsecs = 0.0; + int n; + for (n = 0; n < niter; n++) + { + int size = (total + dst_offset)*sizeof(T); + ACE_InputCDR is (toread, size, opposite_byte_order); + + char* const end = is.rd_ptr() + size; + + do_seal(end); + + double secs = 0.0; + if (use_array) + { + { + int i; + for (i = 0; i < dst_offset; i++) + { + T v; + is >> v; + } + } + + if (n == 0) + { + ACE_DEBUG((LM_DEBUG, + "* src align = %d, dst align = %d\n", + tellalign (is.rd_ptr ()), + tellalign (src))); + } + + Crono crono; + crono.start (); + H::read_array(is, idata, total); + crono.stop (); + secs = crono.read_seconds (); + } + else + { + int i = 0; + Crono crono; + crono.start (); + while (i < total) + { + is >> idata[i++]; + is >> idata[i++]; + is >> idata[i++]; + is >> idata[i++]; + } + crono.stop (); + secs = crono.read_seconds (); + } + totalsecs += secs; + + if (!check_seal(end)) + { + ACE_ERROR((LM_ERROR, + ACE_TEXT( "Broken seal, aborting.\n" ))); + ACE_OS::exit(1); + } + } + + totalsecs = totalsecs / niter; + + ACE_DEBUG((LM_DEBUG, + ACE_TEXT ("Reading from stream %d %s values") + ACE_TEXT (" (byte swapping): %f seconds.\n"), + total, + ACE_TEXT (H::name), + totalsecs)); + } + + ACE_DEBUG((LM_DEBUG, + ACE_TEXT ("Now checking data...\n") )); + + int errors = 0; + const int maxerrors = 6; + + { + int i; + for (i = 0; i < total; i++) + { + T v; + + const char* src = ACE_reinterpret_cast(const char*, (idata + i)); + char* dst = ACE_reinterpret_cast(char*, (&v)); + + // Easier than writing each H::swap... + switch(sizeof(T)) + { + case 1: + *dst = *src; + break; + + case 2: + ACE_CDR::swap_2(src, dst); + break; + + case 4: + ACE_CDR::swap_4(src, dst); + break; + + case 8: + ACE_CDR::swap_8(src, dst); + break; + + case 16: + ACE_CDR::swap_16(src, dst); + break; + + default: + ACE_ERROR((LM_DEBUG, + ACE_TEXT ("Unsupported size, aborting.\n"))); + ACE_OS::exit(1); + } + + + if (v != checkval(T, i)) + { + static char s1[32 + 1]; + static char s2[32 + 1]; + CDR_Test::ttoh (v, s1); + CDR_Test::ttoh (checkval(T, i), s2); + ACE_ERROR((LM_ERROR, + ACE_TEXT ( "Wrong value at pos %d:" ) + ACE_TEXT ( " '%s' should be '%s'.\n" ), + i, s1, s2)); + errors++; + if (errors == maxerrors) + { + ACE_ERROR((LM_ERROR, + ACE_TEXT ( "%d errors found, ") + ACE_TEXT ( "interrupting check.\n" ), + errors)); + break; + } + } + } + } + + if (errors != 0) + { + ACE_ERROR((LM_ERROR, + ACE_TEXT ("Inconsistencies found, aborting.\n") )); + ACE_OS::exit(1); + } + + ACE_DEBUG((LM_DEBUG, + ACE_TEXT ("Data OK, Ending %s test.\n"), + ACE_TEXT (H::name))); +} + +template <class T, class N> +CDR_Test<T, N>::~CDR_Test () +{ +} + +// +// Helper Clases for the second template parameter of CDR_Test. +// One for each tested CDR type. +// + +struct DoubleHelper +{ + static const char* name; + static void read_array (ACE_InputCDR& is, + ACE_CDR::Double* x, + ACE_UINT32 n) + { + is.read_double_array (x, n); + } + static void write_array (ACE_OutputCDR& os, + ACE_CDR::Double* x, + ACE_UINT32 n) + { + os.write_double_array (x, n); + } +}; +const char* DoubleHelper::name = "CDR::Double"; + +struct FloatHelper +{ + static const char* name; + static void read_array (ACE_InputCDR& is, + ACE_CDR::Float* x, + ACE_UINT32 n) + { + is.read_float_array (x, n); + } + static void write_array (ACE_OutputCDR& os, + ACE_CDR::Float* x, + ACE_UINT32 n) + { + os.write_float_array (x, n); + } +}; +const char* FloatHelper::name = "CDR::Float"; + +struct ShortHelper +{ + static const char* name; + static void read_array (ACE_InputCDR& is, + ACE_CDR::Short* x, + ACE_UINT32 n) + { + is.read_short_array (x, n); + } + static void write_array (ACE_OutputCDR& os, + ACE_CDR::Short* x, + ACE_UINT32 n) + { + os.write_short_array (x, n); + } +}; +const char* ShortHelper::name = "CDR::Short"; + +struct LongHelper +{ + static const char* name; + static void read_array (ACE_InputCDR& is, + ACE_CDR::Long* x, + ACE_UINT32 n) + { + is.read_long_array (x, n); + } + static void write_array (ACE_OutputCDR& os, + ACE_CDR::Long* x, + ACE_UINT32 n) + { + os.write_long_array (x, n); + } +}; +const char* LongHelper::name = "CDR::Long"; + +struct LongLongHelper +{ + static const char* name; + static void read_array (ACE_InputCDR& is, + ACE_CDR::LongLong* x, + ACE_UINT32 n) + { + is.read_longlong_array (x, n); + } + static void write_array (ACE_OutputCDR& os, + ACE_CDR::LongLong* x, + ACE_UINT32 n) + { + os.write_longlong_array (x, n); + } + +}; +const char* LongLongHelper::name = "CDR::LongLong"; + +struct CharHelper +{ + static const char* name; + static void read_array (ACE_InputCDR& is, + ACE_CDR::Char* x, + ACE_UINT32 n) + { + is.read_char_array (x, n); + } + static void write_array (ACE_OutputCDR& os, + ACE_CDR::Char* x, + ACE_UINT32 n) + { + os.write_char_array (x, n); + } +}; +const char* CharHelper::name = "CDR::Char"; + +void usage (ACE_TCHAR* cmd) +{ + ACE_ERROR((LM_ERROR, + ACE_TEXT ("Usage: %s ") + ACE_TEXT ("[-n n] " ) + ACE_TEXT ("[[-d n|-f n|-q n|-w n|-h n|-c n|-t n] | [-t n]]\n") + ACE_TEXT (" -n n: average time for n iterations.\n") + ACE_TEXT (" -d n: n double precision floating point\n") + ACE_TEXT (" -f n: n single precision floating point\n") + ACE_TEXT (" -q n: n quadwords (int64).\n") + ACE_TEXT (" -w n: n words (int32).\n") + ACE_TEXT (" -h n: n halfwords (int16).\n") + ACE_TEXT (" -c n: n chars.\n") + ACE_TEXT (" -t n: n iterations for every type.\n") + ACE_TEXT (" n must be >= 16 for dfqwhct.\n") + ACE_TEXT (" If you provide one of dfqwhc, then only the\n") + ACE_TEXT (" corresponding type tests will be performed.\n"), + cmd)); + ACE_OS::exit(1); +} + +int +main (int argc, ACE_TCHAR *argv[]) +{ + ACE_START_TEST (ACE_TEXT ("CDR_Array_Test")); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"), + ACE::major_version (), + ACE::minor_version(), + ACE::beta_version())); + + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("d:f:q:w:h:c:t:n:")); + int dtotal = 0; + int ftotal = 0; + int qtotal = 0; + int wtotal = 0; + int htotal = 0; + int ctotal = 0; + int total = 0; + int niter = 0; + + struct { int c; int *v; } opts[] = { + { 'd', &dtotal }, + { 'f', &ftotal }, + { 'q', &qtotal }, + { 'w', &wtotal }, + { 'h', &htotal }, + { 'c', &ctotal }, + { 't', &total }, + { 'n', &niter }, + }; + + int n = sizeof(opts)/sizeof(opts[0]); + + int opt; + while ((opt = get_opt ()) != EOF) + { + int got = 0; + int i; + for (i = 0; i < n; i++) + { + if (opts[i].c == opt) + { + *(opts[i].v) = ACE_OS::atoi (get_opt.optarg); + got = 1; + break; + } + } + + if (!got) + { + usage(argv[0]); + } + } + + if (total == 0) + { + total = default_total; + } + else + { + if (total < 16) + { + usage(argv[0]); + } + } + + if (niter == 0) + { + niter = default_niter; + } + + if (dtotal == 0 + && ftotal == 0 + && qtotal == 0 + && wtotal == 0 + && htotal == 0 + && ctotal == 0) + { + dtotal = ftotal = qtotal = wtotal = htotal = ctotal = total; + } + + int use_array; + for (use_array = 0; use_array < 2; use_array++) + { + { + CDR_Test<ACE_CDR::Double, DoubleHelper> + test (dtotal, niter, use_array); + } + { + CDR_Test<ACE_CDR::Float, FloatHelper> + test (ftotal, niter, use_array); + } + { + CDR_Test<ACE_CDR::LongLong, LongLongHelper> + test (qtotal, niter, use_array); + } + { + CDR_Test<ACE_CDR::Long, LongHelper> + test (wtotal, niter, use_array); + } + { + CDR_Test<ACE_CDR::Short, ShortHelper> + test (htotal, niter, use_array); + } + { + CDR_Test<ACE_CDR::Char, CharHelper> + test (ctotal, niter, use_array); + } + } + + ACE_END_TEST; + return 0; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class CDR_Test<ACE_CDR::Double, DoubleHelper>; +template class CDR_Test<ACE_CDR::Float, FloatHelper>; +template class CDR_Test<ACE_CDR::LongLong, LongLongHelper>; +template class CDR_Test<ACE_CDR::Long, LongHelper>; +template class CDR_Test<ACE_CDR::Short, ShortHelper>; +template class CDR_Test<ACE_CDR::Char, CharHelper>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate CDR_Test<ACE_CDR::Double, DoubleHelper> +#pragma instantiate CDR_Test<ACE_CDR::Float, FloatHelper> +#pragma instantiate CDR_Test<ACE_CDR::LongLong, LongLongHelper> +#pragma instantiate CDR_Test<ACE_CDR::Long, LongHelper> +#pragma instantiate CDR_Test<ACE_CDR::Short, ShortHelper> +#pragma instantiate CDR_Test<ACE_CDR::Char, CharHelper> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/tests/CDR_Array_Test.dsp b/tests/CDR_Array_Test.dsp new file mode 100644 index 00000000000..dfbb238b841 --- /dev/null +++ b/tests/CDR_Array_Test.dsp @@ -0,0 +1,101 @@ +# Microsoft Developer Studio Project File - Name="CDR_Array_Test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+# TARGTYPE "Win32 (ALPHA) Console Application" 0x0603
+
+CFG=CDR_Array_Test - Win32 PharLap ETS Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "CDR_Array_Test.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "CDR_Array_Test.mak" CFG="CDR_Array_Test - Win32 PharLap ETS Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "CDR_Array_Test - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "CDR_Array_Test - Win32 Alpha Debug" (based on "Win32 (ALPHA) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "CDR_Array_Test - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir ".\CDR_Array_Test\Debug"
+# PROP BASE Intermediate_Dir ".\CDR_Array_Test\Debug"
+# PROP BASE Target_Dir ".\CDR_Array_Test"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir ".\DLL\Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ".\CDR_Array_Test"
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"..\ace"
+
+!ELSEIF "$(CFG)" == "CDR_Array_Test - Win32 Alpha Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "CDR_Array_Test\Alpha Debug"
+# PROP BASE Intermediate_Dir "CDR_Array_Test\Alpha Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir "CDR_Array_Test"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir "CDR_Array_Test"
+CPP=cl.exe
+# ADD BASE CPP /nologo /Gt0 /W3 /GX /Zi /Od /I"..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /MTd /c
+# ADD CPP /nologo /Gt0 /W3 /GX /Zi /Od /I"..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /MDd /c
+# SUBTRACT CPP /YX
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 wsock32.lib aced.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:ALPHA /libpath:"..\ace"
+# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:ALPHA /libpath:"..\ace"
+
+!ENDIF
+
+# Begin Target
+
+# Name "CDR_Array_Test - Win32 Debug"
+# Name "CDR_Array_Test - Win32 Alpha Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
+# Begin Source File
+
+SOURCE=.\CDR_Array_Test.cpp
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/tests/CDR_Array_Test.icc b/tests/CDR_Array_Test.icc new file mode 100644 index 00000000000..f3dcf14c56c --- /dev/null +++ b/tests/CDR_Array_Test.icc @@ -0,0 +1,15 @@ +// $Id$ + +include "vacpp_setup.icc" +option + link(libSearchPath, platformLibSearchPath), + incl(searchPath, ".."), + link(linkWithMultiThreadLib,yes), + link(debug) + { + target type (exe) "CDR_Array_Test" + { + source type (cpp) "CDR_Array_Test.cpp" + source platformLinkLibs + } + } diff --git a/tests/CDR_File_Test.cpp b/tests/CDR_File_Test.cpp index 34fba990146..b0351ec2db6 100644 --- a/tests/CDR_File_Test.cpp +++ b/tests/CDR_File_Test.cpp @@ -47,7 +47,9 @@ public: // Default constructor. CDR_Test (ACE_CDR::Char o, + ACE_CDR::Short s, ACE_CDR::Long w, + ACE_CDR::LongLong lw, ACE_CDR::Float f, ACE_CDR::Double d); // Constructor. @@ -57,7 +59,9 @@ public: private: ACE_CDR::Char char_; - ACE_CDR::Long word_; + ACE_CDR::Short word2_; + ACE_CDR::Long word4_; + ACE_CDR::LongLong word8_; ACE_CDR::Float fpoint_; ACE_CDR::Double dprec_; }; @@ -66,27 +70,46 @@ ostream & operator << (ostream &os, const CDR_Test &t) { - os << "Char: " << t.char_ << endl - << "Long: " << t.word_ << endl - << "Float: " << t.fpoint_ << endl - << "Double: " << t.dprec_ << endl; + os << "Char: " << t.char_ << endl + << "Short: " << t.word2_ << endl + << "Long: " << t.word4_ << endl +#if !defined(_MSC_VER) + << "LongLong: " << t.word8_ << endl +#else + << "LongLong 1st half: " + << hex + << ACE_reinterpret_cast(ACE_UINT32, (t.word8_ >> 32)) + << dec << endl + << "LongLong 2nd half: " + << hex + << ACE_reinterpret_cast(ACE_UINT32, (t.word8_ & 0xffffffff)) + << dec << endl +#endif + << "Float: " << t.fpoint_ << endl + << "Double: " << t.dprec_ << endl; return os; } CDR_Test::CDR_Test (void) : char_ (0), - word_ (0), + word2_ (0), + word4_ (0), + word8_ (0), fpoint_ (0.0), dprec_ (0.0) { } CDR_Test::CDR_Test (ACE_CDR::Char o, + ACE_CDR::Short s, ACE_CDR::Long w, + ACE_CDR::LongLong lw, ACE_CDR::Float f, ACE_CDR::Double d) : char_ (o), - word_ (w), + word2_ (s), + word4_ (w), + word8_ (lw), fpoint_ (f), dprec_ (d) { @@ -96,7 +119,9 @@ void operator << (ACE_OutputCDR &os, const CDR_Test &t) { os << t.char_; - os << t.word_; + os << t.word2_; + os << t.word4_; + os << t.word8_; os << t.fpoint_; os << t.dprec_; } @@ -105,7 +130,9 @@ void operator >> (ACE_InputCDR &is, CDR_Test &t) { is >> t.char_; - is >> t.word_; + is >> t.word2_; + is >> t.word4_; + is >> t.word8_; is >> t.fpoint_; is >> t.dprec_; } @@ -114,7 +141,9 @@ int CDR_Test::operator == (const CDR_Test &rhs) { return this->char_ == rhs.char_ - && this->word_ == rhs.word_ + && this->word2_ == rhs.word2_ + && this->word4_ == rhs.word4_ + && this->word8_ == rhs.word8_ && this->fpoint_ == rhs.fpoint_ && this->dprec_ == rhs.dprec_; } @@ -127,6 +156,14 @@ run_test (int write_file, { if (write_file) { + char byte_order = ACE_CDR_BYTE_ORDER; + size_t n = file.send (&byte_order, 1); + if (n != 1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("send failed on %p\n"), + filename), + -1); + ACE_OutputCDR output_cdr (0, ACE_CDR_BYTE_ORDER, 0, @@ -147,9 +184,9 @@ run_test (int write_file, filename, ACE_CDR_BYTE_ORDER ? "little" : "big")); - ssize_t n = file.send (output_mb->rd_ptr (), - output_mb->length ()); - if (n != (ssize_t) output_mb->length()) + n = file.send (output_mb->rd_ptr (), + output_mb->length ()); + if (n != (size_t) output_mb->length()) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("send failed on %p\n"), filename), @@ -164,10 +201,12 @@ run_test (int write_file, filename), -1); + size_t msgsize = info.size_ - 1; + // Allocate the input buffer char *buffer; ACE_NEW_RETURN (buffer, - char[info.size_], + char[msgsize], -1); // Make sure <buffer> is released automagically. ACE_Auto_Basic_Array_Ptr<char> b (buffer); @@ -179,28 +218,37 @@ run_test (int write_file, ACE_TEXT ("%p\n"), filename), -1); - // Read the file into the buffer. - ssize_t size = file.recv (buffer, - info.size_); - if (size != info.size_) + + char byte_order; + size_t size = file.recv (&byte_order, 1); + if (size != 1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Read %d bytes, rather than expected ") + ACE_TEXT ("1 bytes\n"), + size), + -1); + + // Read the cdr data from the file into the buffer. + size = file.recv (buffer, msgsize); + if (size != msgsize) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("Read %d bytes, rather than expected ") ACE_TEXT ("%d bytes\n"), size, - info.size_), + msgsize), -1); // Create message block for the whole file. Ensure that it is // aligned to properly handle the double. - ACE_Message_Block mb (ACE_CDR::MAX_ALIGNMENT + info.size_); + ACE_Message_Block mb (ACE_CDR::MAX_ALIGNMENT + msgsize); ACE_CDR::mb_align (&mb); - mb.copy (buffer, - info.size_); + + mb.copy (buffer, msgsize); // Create CDR input stream from the message block. ACE_InputCDR input_cdr (&mb); - input_cdr.reset_byte_order (ACE_CDR_BYTE_ORDER); + input_cdr.reset_byte_order ((int) byte_order); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Reading file %s in %s endian format...\n"), @@ -220,15 +268,65 @@ run_test (int write_file, return 0; } +static void +usage(ACE_TCHAR* cmd) +{ + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Usage: %s ") + ACE_TEXT ("[-f filename [-w|-r]]"), + cmd)); + ACE_OS::exit(1); +} + // Main function int -main (int, ACE_TCHAR *[]) +main (int argc, ACE_TCHAR *argv[]) { ACE_START_TEST (ACE_TEXT ("CDR_File_Test")); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("This is ACE Version %u.%u.%u\n\n"), + ACE::major_version (), + ACE::minor_version(), + ACE::beta_version())); + + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("f:rw")); + int opt; + int reading = 1; + int writing = 1; + ACE_TCHAR* fn = 0; + while ((opt = get_opt ()) != EOF) + { + switch (opt) + { + case 'f': + fn = get_opt.optarg; + break; + case 'r': + writing = 0; + break; + case 'w': + reading = 0; + break; + case '?': + default: + usage(argv[0]); + } + } + + if ((!reading || !writing) && fn == 0) + { + usage(argv[0]); + } + + if (!reading && !writing) + { + usage(argv[0]); + } + // Create a temporary filename. - ACE_FILE_Addr filename (ACE_sap_any_cast (ACE_FILE_Addr &)); + ACE_FILE_Addr filename ((fn == 0) ? ACE_sap_any_cast (ACE_FILE_Addr &) : fn); ACE_FILE_Connector connector; ACE_FILE_IO file; @@ -239,12 +337,24 @@ main (int, ACE_TCHAR *[]) 0, ACE_Addr::sap_any, 0, - O_RDWR | O_CREAT, + ((writing) ? (O_RDWR | O_CREAT) : O_RDONLY), ACE_DEFAULT_FILE_PERMS) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("connect failed for %p\n"), filename.get_path_name ()), 1); + + if (fn == 0) + { + // Unlink this file right away so that it is automatically removed + // when the process exits. + if (file.unlink () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("unlink failed for %p\n"), + filename.get_path_name ()), + 1); + } + // Unlink this file right away so that it is automatically removed // when the process exits. else if (file.unlink () == -1) @@ -253,21 +363,29 @@ main (int, ACE_TCHAR *[]) filename.get_path_name ()), 1); CDR_Test cdr_test ('a', - 1000, + 0x00ff, + 0xaabbccdd, + 0x01234567, 1.54321f, 1.12345); - // First write the file. - run_test (1, - file, - filename.get_path_name (), - cdr_test); - - // Then read the file. - run_test (0, - file, - filename.get_path_name (), - cdr_test); + if (writing) + { + // write the file. + run_test (1, + file, + filename.get_path_name (), + cdr_test); + } + + if (reading) + { + // read the file. + run_test (0, + file, + filename.get_path_name (), + cdr_test); + } ACE_END_TEST; return 0; diff --git a/tests/Makefile b/tests/Makefile index adfd7aae714..c9d9bbb8f7d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -21,6 +21,7 @@ BIN = Aio_Platform_Test \ Cached_Conn_Test \ Capabilities_Test \ CDR_File_Test \ + CDR_Array_Test \ CDR_Test \ Collection_Test \ Conn_Test \ diff --git a/tests/Makefile.am b/tests/Makefile.am index b1f843bcda8..00a783b845c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -62,6 +62,8 @@ check_PROGRAMS = \ Cached_Conn_Test \ Capabilities_Test \ CDR_Test \ + CDR_File_Test \ + CDR_Array_Test \ Collection_Test \ Conn_Test \ DLL_Test \ diff --git a/tests/Makefile.bor b/tests/Makefile.bor index d2d4efb35ea..fd8a2d24059 100644 --- a/tests/Makefile.bor +++ b/tests/Makefile.bor @@ -16,6 +16,8 @@ TESTS = \ Cached_Accept_Conn_Test \ Capabilities_Test \ CDR_Test \ + CDR_File_Test \ + CDR_Array_Test \ Collection_Test \ Conn_Test \ DLList_Test \ diff --git a/tests/run_tests.bat b/tests/run_tests.bat index dd30bf06770..b1ce8d9b07c 100644 --- a/tests/run_tests.bat +++ b/tests/run_tests.bat @@ -96,6 +96,8 @@ call %run_cmd% %dopure% %platform% Cached_Conn_Test call %run_cmd% %dopure% %platform% Cached_Accept_Conn_Test call %run_cmd% %dopure% %platform% Capabilities_Test call %run_cmd% %dopure% %platform% CDR_Test +call %run_cmd% %dopure% %platform% CDR_File_Test +call %run_cmd% %dopure% %platform% CDR_Array_Test call %run_cmd% %dopure% %platform% Collection_Test call %run_cmd% %dopure% %platform% Conn_Test call %run_cmd% %dopure% %platform% DLL_Test diff --git a/tests/run_tests.lst b/tests/run_tests.lst index 5db64650009..646d29ec18b 100644 --- a/tests/run_tests.lst +++ b/tests/run_tests.lst @@ -5,6 +5,7 @@ Capabilities_Test Atomic_Op_Test Auto_IncDec_Test Object_Manager_Test +CDR_Array_Test CDR_File_Test CDR_Test Semaphore_Test diff --git a/tests/run_tests.vxworks b/tests/run_tests.vxworks index d3728e3e1fe..d106fdd33f8 100644 --- a/tests/run_tests.vxworks +++ b/tests/run_tests.vxworks @@ -48,6 +48,17 @@ ld < CDR_Test write 2, "CDR_Test ", 9 ace_main; unld "CDR_Test" +ld < CDR_Array_Test +write 2, "CDR_Array_Test ", 9 +ace_main; unld "CDR_Array_Test" + +## +## @@ I'm not sure if File_Test can run on vxworks. +## +## ld < CDR_File_Test +## write 2, "CDR_File_Test ", 9 +## ace_main; unld "CDR_File_Test" + ld < DLList_Test write 2, "DLList_Test ", 13 ace_main; unld "DLList_Test" diff --git a/tests/tests.dsw b/tests/tests.dsw index 69336a7c9f3..86abc511ed6 100644 --- a/tests/tests.dsw +++ b/tests/tests.dsw @@ -87,6 +87,18 @@ Package=<4> ###############################################################################
+Project: "CDR_Array_Test"=.\CDR_Array_Test.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "CDR_Test"=.\CDR_Test.dsp - Package Owner=<4>
Package=<5>
|