OS_Memory.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   OS_Memory.h
00006  *
00007  *  $Id: OS_Memory.h 80826 2008-03-04 14:51:23Z wotte $
00008  *
00009  *  @author Doug Schmidt <schmidt@cs.wustl.edu>
00010  *  @author Jesper S. M|ller<stophph@diku.dk>
00011  *  @author and a cast of thousands...
00012  */
00013 //=============================================================================
00014 
00015 #ifndef ACE_OS_MEMORY_H
00016 #define ACE_OS_MEMORY_H
00017 #include /**/ "ace/pre.h"
00018 
00019 #include /**/ "ace/ACE_export.h"
00020 
00021 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00022 # pragma once
00023 #endif /* ACE_LACKS_PRAGMA_ONCE */
00024 
00025 #include "ace/OS_Errno.h"
00026 #include "ace/Basic_Types.h"
00027 #include "ace/os_include/os_stddef.h"
00028 
00029 // Allow an installation to replace the lowest-level allocation
00030 // functions without changing the source of ACE.
00031 //
00032 // To do this, simple #define ACE_*_FUNC macros in config.h to
00033 // the names of the site-specific functions, e.g.,
00034 //
00035 //   #define ACE_MALLOC_FUNC  dlmalloc
00036 //   #define ACE_CALLOC_FUNC  dlcalloc
00037 //   #define ACE_FREE_FUNC    dlfree
00038 //   #define ACE_REALLOC_FUNC dlrealloc
00039 //
00040 // For completeness' sake, you should probably put
00041 //   #define ACE_HAS_STRDUP_EMULATION
00042 //   #define ACE_HAS_WCSDUP_EMULATION
00043 // too, so that you guarantee that strdup() and wcsdup() call your
00044 // desired mallocator and not the system mallocator.
00045 //
00046 #if !defined (ACE_MALLOC_FUNC)
00047 #  define ACE_MALLOC_FUNC ::malloc
00048 #endif
00049 #if !defined (ACE_CALLOC_FUNC)
00050 #  define ACE_CALLOC_FUNC ::calloc
00051 #endif
00052 #if !defined (ACE_FREE_FUNC)
00053 #  define ACE_FREE_FUNC ::free
00054 #endif
00055 #if !defined (ACE_REALLOC_FUNC)
00056 #  define ACE_REALLOC_FUNC ::realloc
00057 #endif
00058 
00059 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00060 
00061 #if defined (ACE_HAS_OLD_MALLOC)
00062 typedef char * ACE_MALLOC_T;
00063 #else
00064 typedef void * ACE_MALLOC_T;
00065 #endif /* ACE_HAS_OLD_MALLOC */
00066 
00067 ACE_END_VERSIONED_NAMESPACE_DECL
00068 
00069 // ============================================================================
00070 // ACE_NEW macros
00071 //
00072 // A useful abstraction for expressions involving operator new since
00073 // we can change memory allocation error handling policies (e.g.,
00074 // depending on whether ANSI/ISO exception handling semantics are
00075 // being used).
00076 // ============================================================================
00077 
00078 // If new(std::nothrow) is defined then, by definition, new throws exceptions.
00079 #if defined (ACE_HAS_NEW_NOTHROW)
00080 #  if !defined (ACE_NEW_THROWS_EXCEPTIONS)
00081 #    define ACE_NEW_THROWS_EXCEPTIONS
00082 #  endif
00083 #endif
00084 
00085 // The Windows MFC exception mechanism requires that a caught CException
00086 // (including the CMemoryException in use here) be freed using its Delete()
00087 // method. Thus, when MFC is in use and we're catching exceptions as a result
00088 // of new(), the exception's Delete() method has to be called. No other
00089 // platform imposes this sort of restriction/requirement. The Windows
00090 // config stuff (at least for MSVC/MFC) defines a ACE_del_bad_alloc macro
00091 // that works with its ACE_bad_alloc macro to implement this cleanup
00092 // requirement. Since no other platform requires this, define it as
00093 // empty here.
00094 #if !defined (ACE_del_bad_alloc)
00095 #  define ACE_del_bad_alloc
00096 #endif
00097 
00098 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
00099 
00100 // Since new() throws exceptions, we need a way to avoid passing
00101 // exceptions past the call to new because ACE counts on having a 0
00102 // return value for a failed allocation. Some compilers offer the
00103 // new (nothrow) version, which does exactly what we want. Others
00104 // do not. For those that do not, this sets up what exception is thrown,
00105 // and then below we'll do a try/catch around the new to catch it and
00106 // return a 0 pointer instead.
00107 
00108 #  if defined (__HP_aCC)
00109       // I know this works for HP aC++... if <stdexcept> is used, it
00110       // introduces other stuff that breaks things, like <memory>, which
00111       // screws up auto_ptr.
00112 #    include /**/ <new>
00113     // _HP_aCC was first defined at aC++ 03.13 on HP-UX 11. Prior to that
00114     // (03.10 and before) a failed new threw bad_alloc. After that (03.13
00115     // and above) the exception thrown is dependent on the below settings.
00116 #    if (HPUX_VERS >= 1100)
00117 #      if ((__HP_aCC < 32500 && !defined (RWSTD_NO_NAMESPACE)) || \
00118            defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB))
00119 #        define ACE_bad_alloc ::std::bad_alloc
00120 #        define ACE_nothrow   ::std::nothrow
00121 #        define ACE_nothrow_t ::std::nothrow_t
00122 #      else
00123 #        define ACE_bad_alloc bad_alloc
00124 #        define ACE_nothrow   nothrow
00125 #        define ACE_nothrow_t nothrow_t
00126 #      endif /* __HP_aCC */
00127 #    elif ((__HP_aCC <  12500 && !defined (RWSTD_NO_NAMESPACE)) || \
00128            defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB))
00129 #      define ACE_bad_alloc ::std::bad_alloc
00130 #      define ACE_nothrow   ::std::nothrow
00131 #      define ACE_nothrow_t ::std::nothrow_t
00132 #    else
00133 #      define ACE_bad_alloc bad_alloc
00134 #      define ACE_nothrow   nothrow
00135 #      define ACE_nothrow_t nothrow_t
00136 #    endif /* HPUX_VERS < 1100 */
00137 #    define ACE_throw_bad_alloc throw ACE_bad_alloc ()
00138 #  elif defined (__SUNPRO_CC)
00139 #      if (__SUNPRO_CC < 0x500) || (__SUNPRO_CC_COMPAT == 4)
00140 #        include /**/ <exception.h>
00141          // Note: we catch ::xalloc rather than just xalloc because of
00142          // a name clash with unsafe_ios::xalloc()
00143 #        define ACE_bad_alloc ::xalloc
00144 #        define ACE_throw_bad_alloc throw ACE_bad_alloc ("no more memory")
00145 #      else
00146 #        include /**/ <new>
00147 #        define ACE_bad_alloc ::std::bad_alloc
00148 #        if defined (ACE_HAS_NEW_NOTHROW)
00149 #          if defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB)
00150 #            define ACE_nothrow   ::std::nothrow
00151 #            define ACE_nothrow_t ::std::nothrow_t
00152 #          else
00153 #            define ACE_nothrow   nothrow
00154 #            define ACE_nothrow_t nothrow_t
00155 #          endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */
00156 #        endif /* ACE_HAS_NEW_NOTHROW */
00157 #        define ACE_throw_bad_alloc throw ACE_bad_alloc ()
00158 #      endif /* __SUNPRO_CC < 0x500 */
00159 #  elif defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB)
00160 #    include /**/ <new>
00161 #    if !defined (ACE_bad_alloc)
00162 #      define ACE_bad_alloc ::std::bad_alloc
00163 #    endif
00164 #    define ACE_nothrow   ::std::nothrow
00165 #    define ACE_nothrow_t ::std::nothrow_t
00166      // MFC changes the behavior of operator new at all MSVC versions from 6 up.
00167 #    if defined (ACE_HAS_MFC) && (ACE_HAS_MFC == 1)
00168 #      define ACE_throw_bad_alloc AfxThrowMemoryException ()
00169 #    else
00170 #      define ACE_throw_bad_alloc throw ACE_bad_alloc ()
00171 #    endif
00172 #  else
00173 #    include /**/ <new>
00174 #    if !defined (ACE_bad_alloc)
00175 #      define ACE_bad_alloc bad_alloc
00176 #    endif
00177 #    define ACE_nothrow   nothrow
00178 #    define ACE_nothrow_t nothrow_t
00179      // MFC changes the behavior of operator new at all MSVC versions from 6 up.
00180 #    if defined (ACE_HAS_MFC) && (ACE_HAS_MFC == 1)
00181 #      define ACE_throw_bad_alloc AfxThrowMemoryException ()
00182 #    else
00183 #      define ACE_throw_bad_alloc throw ACE_bad_alloc ()
00184 #    endif
00185 #  endif /* __HP_aCC */
00186 
00187 #  if defined (ACE_HAS_NEW_NOTHROW)
00188 #    define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
00189    do { POINTER = new (ACE_nothrow) CONSTRUCTOR; \
00190      if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \
00191    } while (0)
00192 #    define ACE_NEW(POINTER,CONSTRUCTOR) \
00193    do { POINTER = new(ACE_nothrow) CONSTRUCTOR; \
00194      if (POINTER == 0) { errno = ENOMEM; return; } \
00195    } while (0)
00196 #    define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \
00197    do { POINTER = new(ACE_nothrow) CONSTRUCTOR; \
00198      if (POINTER == 0) { errno = ENOMEM; } \
00199    } while (0)
00200 
00201 #  else
00202 
00203 #    define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
00204    do { try { POINTER = new CONSTRUCTOR; } \
00205      catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; return RET_VAL; } \
00206    } while (0)
00207 
00208 #    define ACE_NEW(POINTER,CONSTRUCTOR) \
00209    do { try { POINTER = new CONSTRUCTOR; } \
00210      catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; return; } \
00211    } while (0)
00212 
00213 #    define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \
00214    do { try { POINTER = new CONSTRUCTOR; } \
00215      catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; POINTER = 0; } \
00216    } while (0)
00217 #  endif /* ACE_HAS_NEW_NOTHROW */
00218 
00219 #else /* ACE_NEW_THROWS_EXCEPTIONS */
00220 
00221 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
00222    do { POINTER = new CONSTRUCTOR; \
00223      if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \
00224    } while (0)
00225 # define ACE_NEW(POINTER,CONSTRUCTOR) \
00226    do { POINTER = new CONSTRUCTOR; \
00227      if (POINTER == 0) { errno = ENOMEM; return; } \
00228    } while (0)
00229 # define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \
00230    do { POINTER = new CONSTRUCTOR; \
00231      if (POINTER == 0) { errno = ENOMEM; } \
00232    } while (0)
00233 
00234 # define ACE_throw_bad_alloc \
00235   void* gcc_will_complain_if_literal_0_is_returned = 0; \
00236   return gcc_will_complain_if_literal_0_is_returned
00237 
00238 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
00239 
00240 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00241 //@{
00242 /**
00243  * @name Efficiently compute aligned pointers to powers of 2 boundaries.
00244  */
00245 
00246 /**
00247  * Efficiently align "value" up to "alignment", knowing that all such
00248  * boundaries are binary powers and that we're using two's complement
00249  * arithmetic.
00250  *
00251  * Since the alignment is a power of two its binary representation is:
00252  *
00253  * alignment      = 0...010...0
00254  *
00255  * hence
00256  *
00257  * alignment - 1  = 0...001...1 = T1
00258  *
00259  * so the complement is:
00260  *
00261  * ~(alignment - 1) = 1...110...0 = T2
00262  *
00263  * Notice that there is a multiple of <alignment> in the range
00264  * [<value>,<value> + T1], also notice that if
00265  *
00266  * X = ( <value> + T1 ) & T2
00267  *
00268  * then
00269  *
00270  * <value> <= X <= <value> + T1
00271  *
00272  * because the & operator only changes the last bits, and since X is a
00273  * multiple of <alignment> (its last bits are zero) we have found the
00274  * multiple we wanted.
00275  */
00276 /// Return the next integer aligned to a required boundary
00277 /**
00278  * @param ptr the base pointer
00279  * @param alignment the required alignment
00280  */
00281 #if defined (ACE_OPENVMS) && (!defined (__INITIAL_POINTER_SIZE) || (__INITIAL_POINTER_SIZE < 64))
00282 inline unsigned int
00283 ACE_align_binary (unsigned int ptr, unsigned int alignment)
00284 {
00285   unsigned int const tmp = alignment - 1;
00286   return (ptr + tmp) & (~tmp);
00287 }
00288 #else
00289 inline uintptr_t
00290 ACE_align_binary (uintptr_t ptr, uintptr_t alignment)
00291 {
00292   uintptr_t const tmp = alignment - 1;
00293   return (ptr + tmp) & (~tmp);
00294 }
00295 #endif
00296 
00297 #if defined (ACE_OPENVMS) && (!defined (__INITIAL_POINTER_SIZE) || (__INITIAL_POINTER_SIZE < 64))
00298 /// Return the next address aligned to a required boundary
00299 inline char *
00300 ACE_ptr_align_binary (char const * ptr, unsigned int alignment)
00301 {
00302   return
00303     reinterpret_cast<char *> (
00304       ACE_align_binary (reinterpret_cast<unsigned int> (ptr), alignment));
00305 }
00306 
00307 /// Return the next address aligned to a required boundary
00308 inline char *
00309 ACE_ptr_align_binary (unsigned char const * ptr, unsigned int alignment)
00310 {
00311   return
00312     ACE_ptr_align_binary (reinterpret_cast<char const *> (ptr), alignment);
00313 }
00314 #else
00315 /// Return the next address aligned to a required boundary
00316 inline char *
00317 ACE_ptr_align_binary (char const * ptr, uintptr_t alignment)
00318 {
00319   return
00320     reinterpret_cast<char *> (
00321       ACE_align_binary (reinterpret_cast<uintptr_t> (ptr), alignment));
00322 }
00323 
00324 /// Return the next address aligned to a required boundary
00325 inline char *
00326 ACE_ptr_align_binary (unsigned char const * ptr, uintptr_t alignment)
00327 {
00328   return
00329     ACE_ptr_align_binary (reinterpret_cast<char const *> (ptr), alignment);
00330 }
00331 #endif  /* ACE_OPENVMS && __INITIAL_POINTER_SIZE < 64 */
00332 //@}
00333 ACE_END_VERSIONED_NAMESPACE_DECL
00334 
00335 #include "ace/OS_NS_stdlib.h"
00336 
00337 #include /**/ "ace/post.h"
00338 #endif /* ACE_OS_MEMORY_H */

Generated on Tue Feb 2 17:18:41 2010 for ACE by  doxygen 1.4.7