Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #ifndef _ink_memory_h_
00024 #define _ink_memory_h_
00025 
00026 #include <ctype.h>
00027 #include <string.h>
00028 #include <strings.h>
00029 
00030 #include "ink_config.h"
00031 
00032 #if HAVE_UNISTD_H
00033 #include <unistd.h>
00034 #endif
00035 
00036 #if HAVE_SYS_TYPES_H
00037 #include <sys/types.h>
00038 #endif
00039 
00040 #if HAVE_SYS_UIO_H
00041 #include <sys/uio.h>
00042 #endif
00043 
00044 #if HAVE_SYS_MMAN_H
00045 #include <sys/mman.h>
00046 #endif
00047 
00048 #if TS_HAS_JEMALLOC
00049 #include <jemalloc/jemalloc.h>
00050 
00051 #define ATS_MMAP_MAX 0
00052 #else
00053 #if HAVE_MALLOC_H
00054 #include <malloc.h>
00055 #define ATS_MMAP_MAX M_MMAP_MAX
00056 #endif // ! HAVE_MALLOC_H
00057 #endif // ! TS_HAS_JEMALLOC
00058 
00059 #ifndef MADV_NORMAL
00060 #define MADV_NORMAL 0
00061 #endif
00062 
00063 #ifndef MADV_RANDOM
00064 #define MADV_RANDOM 1
00065 #endif
00066 
00067 #ifndef MADV_SEQUENTIAL
00068 #define MADV_SEQUENTIAL 2
00069 #endif
00070 
00071 #ifndef MADV_WILLNEED
00072 #define MADV_WILLNEED 3
00073 #endif
00074 
00075 #ifndef MADV_DONTNEED
00076 #define MADV_DONTNEED 4
00077 #endif
00078 
00079 #ifdef __cplusplus
00080 extern "C" {
00081 #endif                          
00082 
00083   typedef struct iovec IOVec;
00084 
00085   void *  ats_malloc(size_t size);
00086   void *  ats_calloc(size_t nelem, size_t elsize);
00087   void *  ats_realloc(void *ptr, size_t size);
00088   void *  ats_memalign(size_t alignment, size_t size);
00089   void    ats_free(void *ptr);
00090   void *  ats_free_null(void *ptr);
00091   void    ats_memalign_free(void *ptr);
00092   int     ats_mallopt(int param, int value);
00093 
00094   int     ats_msync(caddr_t addr, size_t len, caddr_t end, int flags);
00095   int     ats_madvise(caddr_t addr, size_t len, int flags);
00096   int     ats_mlock(caddr_t addr, size_t len);
00097 
00098   static inline size_t __attribute__((const)) ats_pagesize(void)
00099   {
00100     static size_t page_size;
00101 
00102     if (page_size)
00103       return page_size;
00104 
00105 #if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
00106     page_size = (size_t)sysconf(_SC_PAGESIZE);
00107 #elif defined(HAVE_GETPAGESIZE)
00108     page_size = (size_t)getpagesize()
00109 #else
00110     page_size = (size_t)8192;
00111 #endif
00112 
00113     return page_size;
00114   }
00115 
00116 
00117 char *_xstrdup(const char *str, int length, const char *path);
00118 
00119 #define ats_strdup(p)        _xstrdup((p), -1, NULL)
00120 #define ats_strndup(p,n)     _xstrdup((p), n, NULL)
00121 
00122 #ifdef __cplusplus
00123 }
00124 #endif
00125 
00126 #ifdef __cplusplus
00127 
00128 template <typename PtrType, typename SizeType>
00129 static inline IOVec
00130 make_iovec(PtrType ptr, SizeType sz) {
00131   IOVec iov = { ptr, static_cast<size_t>(sz) };
00132   return iov;
00133 }
00134 
00135 template <typename PtrType, unsigned N>
00136 static inline IOVec
00137 make_iovec(PtrType (&array)[N]) {
00138   IOVec iov = { &array[0], static_cast<size_t>(sizeof(array)) };
00139   return iov;
00140 }
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 template < typename T > inline void
00170 ink_zero(T& t) {
00171   memset(&t, 0, sizeof(t));
00172 }
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 template <
00233   typename TRAITS 
00234 >
00235 class ats_scoped_resource
00236 {
00237 public:
00238   typedef TRAITS Traits; 
00239   typedef typename TRAITS::value_type value_type; 
00240   typedef ats_scoped_resource self; 
00241 
00242 public:
00243 
00244 
00245   ats_scoped_resource() : _r(Traits::initValue()) {}
00246 
00247 
00248   explicit ats_scoped_resource(value_type rt) : _r(rt) {}
00249 
00250 
00251   ~ats_scoped_resource() {
00252     if (Traits::isValid(_r))
00253       Traits::destroy(_r);
00254   }
00255 
00256 
00257   operator value_type () const {
00258     return _r;
00259   }
00260 
00261 
00262 
00263   value_type get() const {
00264     return _r;
00265   }
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279   value_type release() {
00280     value_type zret = _r;
00281     _r = Traits::initValue();
00282     return zret;
00283   }
00284 
00285 
00286 
00287 
00288   self& operator = (value_type rt) {
00289     if (Traits::isValid(_r)) Traits::destroy(_r);
00290     _r = rt;
00291     return *this;
00292   }
00293 
00294   bool operator == (value_type rt) const {
00295     return _r == rt;
00296   }
00297 
00298   bool operator != (value_type rt) const {
00299     return _r != rt;
00300   }
00301 
00302 protected:
00303   value_type _r; 
00304 private:
00305   ats_scoped_resource(self const&); 
00306   self& operator = (self const&); 
00307 
00308 };
00309 
00310 namespace detail {
00311 
00312 
00313   struct SCOPED_FD_TRAITS
00314   {
00315     typedef int value_type;
00316     static int initValue() { return -1; }
00317     static bool isValid(int fd) { return fd >= 0; }
00318     static void destroy(int fd) { close(fd); }
00319   };
00320 }
00321 
00322 
00323 
00324 
00325 
00326 
00327 class ats_scoped_fd : public ats_scoped_resource<detail::SCOPED_FD_TRAITS>
00328 {
00329 public:
00330   typedef ats_scoped_resource<detail::SCOPED_FD_TRAITS> super; 
00331   typedef ats_scoped_fd self; 
00332   typedef bool (self::*pseudo_bool)() const; 
00333 
00334 
00335   ats_scoped_fd()
00336   { }
00337 
00338   explicit ats_scoped_fd(value_type v) : super(v)
00339   { }
00340 
00341 
00342   self& operator = (value_type fd) {
00343     super::operator=(fd);
00344     return *this;
00345   }
00346 
00347 
00348   operator pseudo_bool () const {
00349     return Traits::isValid(_r) ?  &self::operator! : 0;
00350   }
00351 
00352 
00353   bool operator ! () const {
00354     return ! Traits::isValid(_r);
00355   }
00356 };
00357 
00358 namespace detail {
00359 
00360 
00361   template <
00362     typename T 
00363   >
00364   struct SCOPED_MALLOC_TRAITS
00365   {
00366     typedef T* value_type;
00367     static T*  initValue() { return NULL; }
00368     static bool isValid(T* t) { return 0 != t; }
00369     static void destroy(T* t) { ats_free(t); }
00370   };
00371 
00372 
00373   template <
00374     typename T 
00375   >
00376   struct SCOPED_OBJECT_TRAITS
00377   {
00378     typedef T* value_type;
00379     static T* initValue() { return NULL; }
00380     static bool isValid(T* t) { return 0 != t; }
00381     static void destroy(T* t) { delete t; }
00382   };
00383 }
00384 
00385 
00386 
00387 
00388 class ats_scoped_str : public ats_scoped_resource<detail::SCOPED_MALLOC_TRAITS<char> >
00389 {
00390  public:
00391   typedef ats_scoped_resource<detail::SCOPED_MALLOC_TRAITS<char> > super; 
00392   typedef ats_scoped_str self; 
00393 
00394 
00395   ats_scoped_str()
00396   { }
00397 
00398   explicit ats_scoped_str(size_t n) : super(static_cast<char*>(ats_malloc(n)))
00399   { }
00400 
00401   explicit ats_scoped_str(char* s) : super(s)
00402   { }
00403 
00404   self& operator = (char* s) {
00405     super::operator=(s);
00406     return *this;
00407   }
00408 };
00409 
00410 
00411 
00412 template <
00413   typename T 
00414 >
00415 class ats_scoped_mem : public ats_scoped_resource<detail::SCOPED_MALLOC_TRAITS<T> >
00416 {
00417 public:
00418   typedef ats_scoped_resource<detail::SCOPED_MALLOC_TRAITS<T> > super; 
00419   typedef ats_scoped_mem self; 
00420 
00421   self& operator = (T* ptr) {
00422     super::operator=(ptr);
00423     return *this;
00424   }
00425 };
00426 
00427 
00428 
00429 
00430 
00431 template <
00432   typename T 
00433 >
00434 class ats_scoped_obj : public ats_scoped_resource<detail::SCOPED_OBJECT_TRAITS<T> >
00435 {
00436 public:
00437   typedef ats_scoped_resource<detail::SCOPED_OBJECT_TRAITS<T> > super; 
00438   typedef ats_scoped_obj self; 
00439 
00440   self& operator = (T* obj) {
00441     super::operator=(obj);
00442     return *this;
00443   }
00444 };
00445 
00446 
00447 
00448 
00449 
00450 
00451 inline char*
00452 path_join (ats_scoped_str const& lhs, ats_scoped_str  const& rhs)
00453 {
00454   size_t ln = strlen(lhs);
00455   size_t rn = strlen(rhs);
00456   char const* rptr = rhs; 
00457 
00458   if (ln && lhs[ln-1] == '/') --ln; 
00459   if (rn && *rptr == '/') --rn, ++rptr; 
00460 
00461   ats_scoped_str x(ln + rn + 2);
00462 
00463   memcpy(x, lhs, ln);
00464   x[ln] = '/';
00465   memcpy(x + ln + 1,  rptr, rn);
00466   x[ln+rn+1] = 0; 
00467 
00468   return x.release();
00469 }
00470 #endif  
00471 
00472 #endif