OS_Memory.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   OS_Memory.h
00006  *
00007  *  OS_Memory.h,v 4.29 2006/04/28 15:25:08 shuston Exp
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/os_include/os_stddef.h"
00027 
00028 // Allow an installation to replace the lowest-level allocation
00029 // functions without changing the source of ACE.
00030 //
00031 // To do this, simple #define ACE_*_FUNC macros in config.h to
00032 // the names of the site-specific functions, e.g.,
00033 //
00034 //   #define ACE_MALLOC_FUNC  dlmalloc
00035 //   #define ACE_CALLOC_FUNC  dlcalloc
00036 //   #define ACE_FREE_FUNC    dlfree
00037 //   #define ACE_REALLOC_FUNC dlrealloc
00038 //
00039 // For completeness' sake, you should probably put
00040 //   #define ACE_HAS_STRDUP_EMULATION
00041 //   #define ACE_HAS_WCSDUP_EMULATION
00042 // too, so that you guarantee that strdup() and wcsdup() call your
00043 // desired mallocator and not the system mallocator.
00044 //
00045 #if !defined (ACE_MALLOC_FUNC)
00046 #  define ACE_MALLOC_FUNC ::malloc
00047 #endif
00048 #if !defined (ACE_CALLOC_FUNC)
00049 #  define ACE_CALLOC_FUNC ::calloc
00050 #endif
00051 #if !defined (ACE_FREE_FUNC)
00052 #  define ACE_FREE_FUNC ::free
00053 #endif
00054 #if !defined (ACE_REALLOC_FUNC)
00055 #  define ACE_REALLOC_FUNC ::realloc
00056 #endif
00057 
00058 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00059 
00060 #if defined (ACE_HAS_OLD_MALLOC)
00061 typedef char * ACE_MALLOC_T;
00062 #else
00063 typedef void * ACE_MALLOC_T;
00064 #endif /* ACE_HAS_OLD_MALLOC */
00065 
00066 ACE_END_VERSIONED_NAMESPACE_DECL
00067 
00068 // ============================================================================
00069 // ACE_NEW macros
00070 //
00071 // A useful abstraction for expressions involving operator new since
00072 // we can change memory allocation error handling policies (e.g.,
00073 // depending on whether ANSI/ISO exception handling semantics are
00074 // being used).
00075 // ============================================================================
00076 
00077 // If new(std::nothrow) is defined then, by definition, new throws exceptions.
00078 #if defined (ACE_HAS_NEW_NOTHROW)
00079 #  if !defined (ACE_NEW_THROWS_EXCEPTIONS)
00080 #    define ACE_NEW_THROWS_EXCEPTIONS
00081 #  endif
00082 #endif
00083 
00084 #if defined (ACE_NEW_THROWS_EXCEPTIONS)
00085 
00086 // Since new() throws exceptions, we need a way to avoid passing
00087 // exceptions past the call to new because ACE counts on having a 0
00088 // return value for a failed allocation. Some compilers offer the
00089 // new (nothrow) version, which does exactly what we want. Others
00090 // do not. For those that do not, this sets up what exception is thrown,
00091 // and then below we'll do a try/catch around the new to catch it and
00092 // return a 0 pointer instead.
00093 
00094 #  if defined (__HP_aCC)
00095       // I know this works for HP aC++... if <stdexcept> is used, it
00096       // introduces other stuff that breaks things, like <memory>, which
00097       // screws up auto_ptr.
00098 #    include /**/ <new>
00099     // _HP_aCC was first defined at aC++ 03.13 on HP-UX 11. Prior to that
00100     // (03.10 and before) a failed new threw bad_alloc. After that (03.13
00101     // and above) the exception thrown is dependent on the below settings.
00102 #    if (HPUX_VERS >= 1100)
00103 #      if ((__HP_aCC < 32500 && !defined (RWSTD_NO_NAMESPACE)) || \
00104            defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB))
00105 #        define ACE_bad_alloc std::bad_alloc
00106 #        define ACE_nothrow   std::nothrow
00107 #        define ACE_nothrow_t std::nothrow_t
00108 #      else
00109 #        define ACE_bad_alloc bad_alloc
00110 #        define ACE_nothrow   nothrow
00111 #        define ACE_nothrow_t nothrow_t
00112 #      endif /* __HP_aCC */
00113 #    elif ((__HP_aCC <  12500 && !defined (RWSTD_NO_NAMESPACE)) || \
00114            defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB))
00115 #      define ACE_bad_alloc std::bad_alloc
00116 #      define ACE_nothrow   std::nothrow
00117 #      define ACE_nothrow_t std::nothrow_t
00118 #    else
00119 #      define ACE_bad_alloc bad_alloc
00120 #      define ACE_nothrow   nothrow
00121 #      define ACE_nothrow_t nothrow_t
00122 #    endif /* HPUX_VERS < 1100 */
00123 #    define ACE_throw_bad_alloc throw ACE_bad_alloc ()
00124 #  elif defined (__SUNPRO_CC)
00125 #      if (__SUNPRO_CC < 0x500) || (__SUNPRO_CC_COMPAT == 4)
00126 #        include /**/ <exception.h>
00127          // Note: we catch ::xalloc rather than just xalloc because of
00128          // a name clash with unsafe_ios::xalloc()
00129 #        define ACE_bad_alloc ::xalloc
00130 #        define ACE_throw_bad_alloc throw ACE_bad_alloc ("no more memory")
00131 #      else
00132 #        include /**/ <new>
00133 #        define ACE_bad_alloc std::bad_alloc
00134 #        if defined (ACE_HAS_NEW_NOTHROW)
00135 #          if defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB)
00136 #            define ACE_nothrow   std::nothrow
00137 #            define ACE_nothrow_t std::nothrow_t
00138 #          else
00139 #            define ACE_nothrow   nothrow
00140 #            define ACE_nothrow_t nothrow_t
00141 #          endif /* ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB */
00142 #        endif /* ACE_HAS_NEW_NOTHROW */
00143 #        define ACE_throw_bad_alloc throw ACE_bad_alloc ()
00144 #      endif /* __SUNPRO_CC < 0x500 */
00145 #  elif defined (ACE_USES_STD_NAMESPACE_FOR_STDCPP_LIB)
00146 #    include /**/ <new>
00147 #    if !defined (ACE_bad_alloc)
00148 #      define ACE_bad_alloc std::bad_alloc
00149 #    endif
00150 #    define ACE_nothrow   std::nothrow
00151 #    define ACE_nothrow_t std::nothrow_t
00152 #    define ACE_throw_bad_alloc throw ACE_bad_alloc ()
00153 #  else
00154 #    include /**/ <new>
00155 #    if !defined (ACE_bad_alloc)
00156 #      define ACE_bad_alloc bad_alloc
00157 #    endif
00158 #    define ACE_nothrow   nothrow
00159 #    define ACE_nothrow_t nothrow_t
00160 #    define ACE_throw_bad_alloc throw ACE_bad_alloc ()
00161 #  endif /* __HP_aCC */
00162 
00163 #  if defined (ACE_HAS_NEW_NOTHROW)
00164 #    define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
00165    do { POINTER = new (ACE_nothrow) CONSTRUCTOR; \
00166      if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \
00167    } while (0)
00168 #    define ACE_NEW(POINTER,CONSTRUCTOR) \
00169    do { POINTER = new(ACE_nothrow) CONSTRUCTOR; \
00170      if (POINTER == 0) { errno = ENOMEM; return; } \
00171    } while (0)
00172 #    define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \
00173    do { POINTER = new(ACE_nothrow) CONSTRUCTOR; \
00174      if (POINTER == 0) { errno = ENOMEM; } \
00175    } while (0)
00176 
00177 #  else
00178 
00179 #    define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
00180    do { try { POINTER = new CONSTRUCTOR; } \
00181         catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0; return RET_VAL; } \
00182    } while (0)
00183 
00184 #    define ACE_NEW(POINTER,CONSTRUCTOR) \
00185    do { try { POINTER = new CONSTRUCTOR; } \
00186         catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0; return; } \
00187    } while (0)
00188 
00189 #    define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \
00190    do { try { POINTER = new CONSTRUCTOR; } \
00191         catch (ACE_bad_alloc) { errno = ENOMEM; POINTER = 0; } \
00192    } while (0)
00193 #  endif /* ACE_HAS_NEW_NOTHROW */
00194 
00195 #else /* ACE_NEW_THROWS_EXCEPTIONS */
00196 
00197 # define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
00198    do { POINTER = new CONSTRUCTOR; \
00199      if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \
00200    } while (0)
00201 # define ACE_NEW(POINTER,CONSTRUCTOR) \
00202    do { POINTER = new CONSTRUCTOR; \
00203      if (POINTER == 0) { errno = ENOMEM; return; } \
00204    } while (0)
00205 # define ACE_NEW_NORETURN(POINTER,CONSTRUCTOR) \
00206    do { POINTER = new CONSTRUCTOR; \
00207      if (POINTER == 0) { errno = ENOMEM; } \
00208    } while (0)
00209 
00210 # define ACE_throw_bad_alloc \
00211   void* gcc_will_complain_if_literal_0_is_returned = 0; \
00212   return gcc_will_complain_if_literal_0_is_returned
00213 
00214 #endif /* ACE_NEW_THROWS_EXCEPTIONS */
00215 
00216 //@{
00217 /**
00218  * @name Efficiently compute aligned pointers to powers of 2 boundaries.
00219  */
00220 
00221 /**
00222  * Efficiently align "value" up to "alignment", knowing that all such
00223  * boundaries are binary powers and that we're using two's complement
00224  * arithmetic.
00225  *
00226  * Since the alignment is a power of two its binary representation is:
00227  *
00228  * alignment      = 0...010...0
00229  *
00230  * hence
00231  *
00232  * alignment - 1  = 0...001...1 = T1
00233  *
00234  * so the complement is:
00235  *
00236  * ~(alignment - 1) = 1...110...0 = T2
00237  *
00238  * Notice that there is a multiple of <alignment> in the range
00239  * [<value>,<value> + T1], also notice that if
00240  *
00241  * X = ( <value> + T1 ) & T2
00242  *
00243  * then
00244  *
00245  * <value> <= X <= <value> + T1
00246  *
00247  * because the & operator only changes the last bits, and since X is a
00248  * multiple of <alignment> (its last bits are zero) we have found the
00249  * multiple we wanted.
00250  */
00251 /// Return the next integer aligned to a required boundary
00252 /**
00253  * @param ptr the base pointer
00254  * @param alignment the required alignment
00255  */
00256 #define ACE_align_binary(ptr, alignment) \
00257     ((ptr + ((ptrdiff_t)((alignment)-1))) & (~((ptrdiff_t)((alignment)-1))))
00258 
00259 /// Return the next address aligned to a required boundary
00260 #define ACE_ptr_align_binary(ptr, alignment) \
00261         ((char *) ACE_align_binary (((ptrdiff_t) (ptr)), (alignment)))
00262 //@}
00263 
00264 #include "ace/OS_NS_stdlib.h"
00265 
00266 #include /**/ "ace/post.h"
00267 #endif /* ACE_OS_MEMORY_H */

Generated on Thu Nov 9 09:41:57 2006 for ACE by doxygen 1.3.6