Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

CDR_Base.inl

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // $Id: CDR_Base.inl,v 1.1.1.1 2001/12/04 14:32:59 chad Exp $
00004 
00005 //
00006 // The ACE_CDR::swap_X and ACE_CDR::swap_X_array routines are broken
00007 // in 4 cases for optimization:
00008 //
00009 // * x86 Pentium CPU + gnu g++
00010 //   (ACE_HAS_PENTIUM && __GNUG__)
00011 //   => gcc x86 inline assembly.
00012 //
00013 // * x86 Pentium CPU and (_MSC_VER) or BORLAND C++)
00014 //   (ACE_HAS_PENTIUM && ( _MSC_VER || __BORLANDC__ )
00015 //   => MSC x86 inline assembly.
00016 //
00017 // * 64 bit architecture
00018 //   (ACE_SIZEOF_LONG == 8)
00019 //   => shift/masks using 64bit words.
00020 //
00021 // * default
00022 //   (none of the above)
00023 //   => shift/masks using 32bit words.
00024 //
00025 //
00026 // Some things you could find useful to know if you intend to mess
00027 // with this optimizations for swaps:
00028 //
00029 //      * MSVC++ don't assume register values are conserved between
00030 //        statements. So you can clobber any register you want,
00031 //        whenever you want (well not *anyone* really, see manual).
00032 //        The MSVC++ optimizer will try to pick different registers
00033 //        for the C++ statements sorrounding your asm block, and if
00034 //        it's not possible will use the stack.
00035 //
00036 //      * If you clobber registers with asm statements in gcc, you
00037 //        better do it in an asm-only function, or save/restore them
00038 //        before/after in the stack. If not, sorrounding C statements
00039 //        could end using the same registers and big-badda-bum (been
00040 //        there, done that...). The big-badda-bum could happen *even
00041 //        if you specify the clobbered register in your asm's*.
00042 //        Even better, use gcc asm syntax for detecting the register
00043 //        asigned to a certain variable so you don't have to clobber any
00044 //        register directly.
00045 //
00046 
00047 ACE_INLINE void
00048 ACE_CDR::swap_2 (const char *orig, char* target)
00049 {
00050 #if defined(ACE_HAS_PENTIUM)
00051 # if defined(__GNUG__)
00052   unsigned short a =
00053     *ACE_reinterpret_cast(const unsigned short*, orig);
00054   asm( "rolw $8, %0" : "=r" (a) : "0" (a) );
00055   *ACE_reinterpret_cast(unsigned short*, target) = a;
00056 # elif (defined(_MSC_VER) || defined(__BORLANDC__)) \
00057        && !defined(ACE_LACKS_INLINE_ASSEMBLY)
00058   __asm mov ebx, orig;
00059   __asm mov ecx, target;
00060   __asm mov ax, [ebx];
00061   __asm rol ax, 8;
00062   __asm mov [ecx], ax;
00063 # else
00064   // For CISC Platforms this is faster than shift/masks.
00065   target[1] = orig[0];
00066   target[0] = orig[1];
00067 # endif
00068 #else
00069   register ACE_UINT16 usrc = * ACE_reinterpret_cast(const ACE_UINT16*, orig);
00070   register ACE_UINT16* udst = ACE_reinterpret_cast(ACE_UINT16*, target);
00071   *udst = (usrc << 8) | (usrc >> 8);
00072 #endif /* ACE_HAS_PENTIUM */
00073 }
00074 
00075 ACE_INLINE void
00076 ACE_CDR::swap_4 (const char* orig, char* target)
00077 {
00078 #if defined(ACE_HAS_PENTIUM) && defined(__GNUG__)
00079   // We have ACE_HAS_PENTIUM, so we know the sizeof's.
00080   register unsigned int j =
00081     *ACE_reinterpret_cast(const unsigned int*, orig);
00082   asm ("bswap %1" : "=r" (j) : "0" (j));
00083   *ACE_reinterpret_cast(unsigned int*, target) = j;
00084 #elif defined(ACE_HAS_PENTIUM) \
00085       && (defined(_MSC_VER) || defined(__BORLANDC__)) \
00086       && !defined(ACE_LACKS_INLINE_ASSEMBLY)
00087   __asm mov ebx, orig;
00088   __asm mov ecx, target;
00089   __asm mov eax, [ebx];
00090   __asm bswap eax;
00091   __asm mov [ecx], eax;
00092 #else
00093   register ACE_UINT32 x = * ACE_reinterpret_cast(const ACE_UINT32*, orig);
00094   x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
00095   * ACE_reinterpret_cast(ACE_UINT32*, target) = x;
00096 #endif
00097 }
00098 
00099 ACE_INLINE void
00100 ACE_CDR::swap_8 (const char* orig, char* target)
00101 {
00102 #if defined(ACE_HAS_PENTIUM) && defined(__GNUG__)
00103   register unsigned int i =
00104     *ACE_reinterpret_cast(const unsigned int*, orig);
00105   register unsigned int j =
00106     *ACE_reinterpret_cast(const unsigned int*, orig + 4);
00107   asm ("bswap %1" : "=r" (i) : "0" (i));
00108   asm ("bswap %1" : "=r" (j) : "0" (j));
00109   *ACE_reinterpret_cast(unsigned int*, target + 4) = i;
00110   *ACE_reinterpret_cast(unsigned int*, target) = j;
00111 #elif defined(ACE_HAS_PENTIUM) \
00112       && (defined(_MSC_VER) || defined(__BORLANDC__)) \
00113       && !defined(ACE_LACKS_INLINE_ASSEMBLY)
00114   __asm mov ecx, orig;
00115   __asm mov edx, target;
00116   __asm mov eax, [ecx];
00117   __asm mov ebx, 4[ecx];
00118   __asm bswap eax;
00119   __asm bswap ebx;
00120   __asm mov 4[edx], eax;
00121   __asm mov [edx], ebx;
00122 #elif ACE_SIZEOF_LONG == 8
00123   // 64 bit architecture.
00124   register unsigned long x =
00125     * ACE_reinterpret_cast(const unsigned long*, orig);
00126   register unsigned long x84 = (x & 0x000000ff000000ffUL) << 24;
00127   register unsigned long x73 = (x & 0x0000ff000000ff00UL) << 8;
00128   register unsigned long x62 = (x & 0x00ff000000ff0000UL) >> 8;
00129   register unsigned long x51 = (x & 0xff000000ff000000UL) >> 24;
00130   x = (x84 | x73 | x62 | x51);
00131   x = (x << 32) | (x >> 32);
00132   *ACE_reinterpret_cast(unsigned long*, target) = x;
00133 #else
00134   register ACE_UINT32 x =
00135     * ACE_reinterpret_cast(const ACE_UINT32*, orig);
00136   register ACE_UINT32 y =
00137     * ACE_reinterpret_cast(const ACE_UINT32*, orig + 4);
00138   x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
00139   y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24);
00140   * ACE_reinterpret_cast(ACE_UINT32*, target) = y;
00141   * ACE_reinterpret_cast(ACE_UINT32*, target + 4) = x;
00142 #endif
00143 }
00144 
00145 ACE_INLINE void
00146 ACE_CDR::swap_16 (const char* orig, char* target)
00147 {
00148   swap_8 (orig + 8, target);
00149   swap_8 (orig, target + 8);
00150 }
00151 
00152 ACE_INLINE void
00153 ACE_CDR::mb_align (ACE_Message_Block *mb)
00154 {
00155   char *start = ACE_ptr_align_binary (mb->base (),
00156                                       ACE_CDR::MAX_ALIGNMENT);
00157   mb->rd_ptr (start);
00158   mb->wr_ptr (start);
00159 }
00160 
00161 ACE_INLINE size_t
00162 ACE_CDR::first_size (size_t minsize)
00163 {
00164   if (minsize == 0)
00165     return ACE_CDR::DEFAULT_BUFSIZE;
00166 
00167   size_t newsize = ACE_CDR::DEFAULT_BUFSIZE;
00168   while (newsize < minsize)
00169     {
00170       if (newsize < ACE_CDR::EXP_GROWTH_MAX)
00171         {
00172           // We grow exponentially at the beginning, this is fast and
00173           // reduces the number of allocations.
00174           newsize *= 2;
00175         }
00176       else
00177         {
00178           // but continuing with exponential growth can result in over
00179           // allocations and easily yield an allocation failure.
00180           // So we grow linearly when the buffer is too big.
00181           newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
00182         }
00183     }
00184   return newsize;
00185 }
00186 
00187 ACE_INLINE size_t
00188 ACE_CDR::next_size (size_t minsize)
00189 {
00190   size_t newsize =
00191     ACE_CDR::first_size (minsize);
00192 
00193   if (newsize == minsize)
00194     {
00195       // If necessary increment the size
00196       if (newsize < ACE_CDR::EXP_GROWTH_MAX)
00197         newsize *= 2;
00198       else
00199         newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
00200     }
00201 
00202   return newsize;
00203 }
00204 
00205 // ****************************************************************

Generated on Mon Jun 16 11:19:19 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002