PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - Zend - zend_alloc.h (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 9 13 69.2 %
Date: 2015-05-21 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2015 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #ifndef ZEND_ALLOC_H
      23             : #define ZEND_ALLOC_H
      24             : 
      25             : #include <stdio.h>
      26             : 
      27             : #include "../TSRM/TSRM.h"
      28             : #include "zend.h"
      29             : 
      30             : #ifndef ZEND_MM_ALIGNMENT
      31             : # define ZEND_MM_ALIGNMENT Z_L(8)
      32             : # define ZEND_MM_ALIGNMENT_LOG2 Z_L(3)
      33             : #elif ZEND_MM_ALIGNMENT < 4
      34             : # undef ZEND_MM_ALIGNMENT
      35             : # undef ZEND_MM_ALIGNMENT_LOG2
      36             : # define ZEND_MM_ALIGNMENT Z_L(4)
      37             : # define ZEND_MM_ALIGNMENT_LOG2 Z_L(2)
      38             : #endif
      39             : 
      40             : #define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT - Z_L(1))
      41             : 
      42             : #define ZEND_MM_ALIGNED_SIZE(size)      (((size) + ZEND_MM_ALIGNMENT - Z_L(1)) & ZEND_MM_ALIGNMENT_MASK)
      43             : 
      44             : typedef struct _zend_leak_info {
      45             :         void *addr;
      46             :         size_t size;
      47             :         const char *filename;
      48             :         const char *orig_filename;
      49             :         uint lineno;
      50             :         uint orig_lineno;
      51             : } zend_leak_info;
      52             : 
      53             : #if ZEND_DEBUG
      54             : typedef struct _zend_mm_debug_info {
      55             :         size_t             size;
      56             :         const char        *filename;
      57             :         const char        *orig_filename;
      58             :         uint               lineno;
      59             :         uint               orig_lineno;
      60             : } zend_mm_debug_info;
      61             : 
      62             : # define ZEND_MM_OVERHEAD ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info))
      63             : #else 
      64             : # define ZEND_MM_OVERHEAD 0
      65             : #endif
      66             : 
      67             : BEGIN_EXTERN_C()
      68             : 
      69             : ZEND_API char*  ZEND_FASTCALL zend_strndup(const char *s, size_t length) ZEND_ATTRIBUTE_MALLOC;
      70             : 
      71             : ZEND_API void*  ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE(1);
      72             : ZEND_API void*  ZEND_FASTCALL _safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
      73             : ZEND_API void*  ZEND_FASTCALL _safe_malloc(size_t nmemb, size_t size, size_t offset) ZEND_ATTRIBUTE_MALLOC;
      74             : ZEND_API void   ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
      75             : ZEND_API void*  ZEND_FASTCALL _ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE2(1,2);
      76             : ZEND_API void*  ZEND_FASTCALL _erealloc(void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_ALLOC_SIZE(2);
      77             : ZEND_API void*  ZEND_FASTCALL _erealloc2(void *ptr, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_ALLOC_SIZE(2);
      78             : ZEND_API void*  ZEND_FASTCALL _safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
      79             : ZEND_API void*  ZEND_FASTCALL _safe_realloc(void *ptr, size_t nmemb, size_t size, size_t offset);
      80             : ZEND_API char*  ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
      81             : ZEND_API char*  ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
      82             : ZEND_API size_t ZEND_FASTCALL _zend_mem_block_size(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
      83             : 
      84             : #include "zend_alloc_sizes.h"
      85             : 
      86             : /* _emalloc() & _efree() specialization */
      87             : #if !ZEND_DEBUG && !defined(_WIN32)
      88             : 
      89             : # define _ZEND_BIN_ALLOCATOR_DEF(_num, _size, _elements, _pages, x, y) \
      90             :         ZEND_API void* ZEND_FASTCALL _emalloc_  ## _size(void) ZEND_ATTRIBUTE_MALLOC;
      91             : 
      92             : ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR_DEF, x, y)
      93             : 
      94             : ZEND_API void* ZEND_FASTCALL _emalloc_large(size_t size) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE(1);
      95             : ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE(1);
      96             : 
      97             : # define _ZEND_BIN_ALLOCATOR_SELECTOR_START(_num, _size, _elements, _pages, size, y) \
      98             :         ((size <= _size) ? _emalloc_ ## _size() :
      99             : # define _ZEND_BIN_ALLOCATOR_SELECTOR_END(_num, _size, _elements, _pages, size, y) \
     100             :         )
     101             : 
     102             : # define ZEND_ALLOCATOR(size) \
     103             :         ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR_SELECTOR_START, size, y) \
     104             :         ((size <= ZEND_MM_MAX_LARGE_SIZE) ? _emalloc_large(size) : _emalloc_huge(size)) \
     105             :         ZEND_MM_BINS_INFO(_ZEND_BIN_ALLOCATOR_SELECTOR_END, size, y)
     106             : 
     107             : # define _emalloc(size) \
     108             :         (__builtin_constant_p(size) ? \
     109             :                 ZEND_ALLOCATOR(size) \
     110             :         : \
     111             :                 _emalloc(size) \
     112             :         )
     113             : 
     114             : # define _ZEND_BIN_DEALLOCATOR_DEF(_num, _size, _elements, _pages, x, y) \
     115             :         ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *);
     116             : 
     117             : ZEND_MM_BINS_INFO(_ZEND_BIN_DEALLOCATOR_DEF, x, y)
     118             : 
     119             : ZEND_API void ZEND_FASTCALL _efree_large(void *, size_t size);
     120             : ZEND_API void ZEND_FASTCALL _efree_huge(void *, size_t size);
     121             : 
     122             : # define _ZEND_BIN_DEALLOCATOR_SELECTOR_START(_num, _size, _elements, _pages, ptr, size) \
     123             :         if (size <= _size) { _efree_ ## _size(ptr); } else
     124             : 
     125             : # define ZEND_DEALLOCATOR(ptr, size) \
     126             :         ZEND_MM_BINS_INFO(_ZEND_BIN_DEALLOCATOR_SELECTOR_START, ptr, size) \
     127             :         if (size <= ZEND_MM_MAX_LARGE_SIZE) { _efree_large(ptr, size); } \
     128             :         else { _efree_huge(ptr, size); }
     129             : 
     130             : # define efree_size(ptr, size) do { \
     131             :                 if (__builtin_constant_p(size)) { \
     132             :                         ZEND_DEALLOCATOR(ptr, size) \
     133             :                 } else { \
     134             :                         _efree(ptr); \
     135             :                 } \
     136             :         } while (0)
     137             : # define efree_size_rel(ptr, size) \
     138             :         efree_size(ptr, size)
     139             : 
     140             : #else
     141             : 
     142             : # define efree_size(ptr, size) \
     143             :         efree(ptr)
     144             : # define efree_size_rel(ptr, size) \
     145             :         efree_rel(ptr)
     146             : 
     147             : #define _emalloc_large _emalloc
     148             : #define _emalloc_huge  _emalloc
     149             : #define _efree_large   _efree
     150             : #define _efree_huge    _efree
     151             : 
     152             : #endif
     153             : 
     154             : /* Standard wrapper macros */
     155             : #define emalloc(size)                                           _emalloc((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     156             : #define emalloc_large(size)                                     _emalloc_large((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     157             : #define emalloc_huge(size)                                      _emalloc_huge((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     158             : #define safe_emalloc(nmemb, size, offset)       _safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     159             : #define efree(ptr)                                                      _efree((ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     160             : #define efree_large(ptr)                                        _efree_large((ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     161             : #define efree_huge(ptr)                                         _efree_huge((ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     162             : #define ecalloc(nmemb, size)                            _ecalloc((nmemb), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     163             : #define erealloc(ptr, size)                                     _erealloc((ptr), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     164             : #define erealloc2(ptr, size, copy_size)         _erealloc2((ptr), (size), (copy_size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     165             : #define safe_erealloc(ptr, nmemb, size, offset) _safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     166             : #define erealloc_recoverable(ptr, size)         _erealloc((ptr), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     167             : #define erealloc2_recoverable(ptr, size, copy_size) _erealloc2((ptr), (size), (copy_size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     168             : #define estrdup(s)                                                      _estrdup((s) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     169             : #define estrndup(s, length)                                     _estrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     170             : #define zend_mem_block_size(ptr)                        _zend_mem_block_size((ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     171             : 
     172             : /* Relay wrapper macros */
     173             : #define emalloc_rel(size)                                               _emalloc((size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     174             : #define safe_emalloc_rel(nmemb, size, offset)   _safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     175             : #define efree_rel(ptr)                                                  _efree((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     176             : #define ecalloc_rel(nmemb, size)                                _ecalloc((nmemb), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     177             : #define erealloc_rel(ptr, size)                                 _erealloc((ptr), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     178             : #define erealloc2_rel(ptr, size, copy_size)             _erealloc2((ptr), (size), (copy_size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     179             : #define erealloc_recoverable_rel(ptr, size)             _erealloc((ptr), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     180             : #define erealloc2_recoverable_rel(ptr, size, copy_size) _erealloc2((ptr), (size), (copy_size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     181             : #define safe_erealloc_rel(ptr, nmemb, size, offset)     _safe_erealloc((ptr), (nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     182             : #define estrdup_rel(s)                                                  _estrdup((s) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     183             : #define estrndup_rel(s, length)                                 _estrndup((s), (length) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     184             : #define zend_mem_block_size_rel(ptr)                    _zend_mem_block_size((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     185             : 
     186             : zend_always_inline static void * __zend_malloc(size_t len)
     187             : {
     188   375590643 :         void *tmp = malloc(len);
     189   375590643 :         if (tmp) {
     190   375590643 :                 return tmp;
     191             :         }
     192           0 :         fprintf(stderr, "Out of memory\n");
     193           0 :         exit(1);
     194             : }
     195             : 
     196             : zend_always_inline static void * __zend_calloc(size_t nmemb, size_t len)
     197             : {
     198       88050 :         void *tmp = _safe_malloc(nmemb, len, 0);
     199       88050 :         memset(tmp, 0, nmemb * len);
     200       88050 :         return tmp;
     201             : }
     202             : 
     203             : zend_always_inline static void * __zend_realloc(void *p, size_t len)
     204             : {
     205     1509226 :         p = realloc(p, len);
     206     1509226 :         if (p) {
     207     1509226 :                 return p;
     208             :         }
     209           0 :         fprintf(stderr, "Out of memory\n");
     210           0 :         exit(1);
     211             : }
     212             : 
     213             : 
     214             : /* Selective persistent/non persistent allocation macros */
     215             : #define pemalloc(size, persistent) ((persistent)?__zend_malloc(size):emalloc(size))
     216             : #define safe_pemalloc(nmemb, size, offset, persistent)  ((persistent)?_safe_malloc(nmemb, size, offset):safe_emalloc(nmemb, size, offset))
     217             : #define pefree(ptr, persistent)  ((persistent)?free(ptr):efree(ptr))
     218             : #define pefree_size(ptr, size, persistent)  ((persistent)?free(ptr):efree_size(ptr, size))
     219             : #define pecalloc(nmemb, size, persistent) ((persistent)?__zend_calloc((nmemb), (size)):ecalloc((nmemb), (size)))
     220             : #define perealloc(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc((ptr), (size)))
     221             : #define perealloc2(ptr, size, copy_size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc2((ptr), (size), (copy_size)))
     222             : #define safe_perealloc(ptr, nmemb, size, offset, persistent)    ((persistent)?_safe_realloc((ptr), (nmemb), (size), (offset)):safe_erealloc((ptr), (nmemb), (size), (offset)))
     223             : #define perealloc_recoverable(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc_recoverable((ptr), (size)))
     224             : #define perealloc2_recoverable(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc2_recoverable((ptr), (size), (copy_size)))
     225             : #define pestrdup(s, persistent) ((persistent)?strdup(s):estrdup(s))
     226             : #define pestrndup(s, length, persistent) ((persistent)?zend_strndup((s),(length)):estrndup((s),(length)))
     227             : 
     228             : #define pemalloc_rel(size, persistent) ((persistent)?__zend_malloc(size):emalloc_rel(size))
     229             : #define pefree_rel(ptr, persistent)     ((persistent)?free(ptr):efree_rel(ptr))
     230             : #define pecalloc_rel(nmemb, size, persistent) ((persistent)?__zend_calloc((nmemb), (size)):ecalloc_rel((nmemb), (size)))
     231             : #define perealloc_rel(ptr, size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc_rel((ptr), (size)))
     232             : #define perealloc2_rel(ptr, size, copy_size, persistent) ((persistent)?__zend_realloc((ptr), (size)):erealloc2_rel((ptr), (size), (copy_size)))
     233             : #define perealloc_recoverable_rel(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc_recoverable_rel((ptr), (size)))
     234             : #define perealloc2_recoverable_rel(ptr, size, copy_size, persistent) ((persistent)?realloc((ptr), (size)):erealloc2_recoverable_rel((ptr), (size), (copy_size)))
     235             : #define pestrdup_rel(s, persistent) ((persistent)?strdup(s):estrdup_rel(s))
     236             : 
     237             : ZEND_API int zend_set_memory_limit(size_t memory_limit);
     238             : 
     239             : ZEND_API void start_memory_manager(void);
     240             : ZEND_API void shutdown_memory_manager(int silent, int full_shutdown);
     241             : ZEND_API int is_zend_mm(void);
     242             : 
     243             : ZEND_API size_t zend_memory_usage(int real_usage);
     244             : ZEND_API size_t zend_memory_peak_usage(int real_usage);
     245             : 
     246             : /* fast cache for HashTables */
     247             : #define ALLOC_HASHTABLE(ht)     \
     248             :         (ht) = (HashTable *) emalloc(sizeof(HashTable))
     249             : 
     250             : #define FREE_HASHTABLE(ht)      \
     251             :         efree_size(ht, sizeof(HashTable))
     252             : 
     253             : #define ALLOC_HASHTABLE_REL(ht) \
     254             :         (ht) = (HashTable *) emalloc_rel(sizeof(HashTable))
     255             : 
     256             : #define FREE_HASHTABLE_REL(ht)  \
     257             :         efree_size_rel(ht, sizeof(HashTable))
     258             : 
     259             : /* Heap functions */
     260             : typedef struct _zend_mm_heap zend_mm_heap;
     261             : 
     262             : ZEND_API zend_mm_heap *zend_mm_startup(void);
     263             : ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent);
     264             : ZEND_API void*  ZEND_FASTCALL _zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
     265             : ZEND_API void   ZEND_FASTCALL _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
     266             : ZEND_API void*  ZEND_FASTCALL _zend_mm_realloc(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
     267             : ZEND_API void*  ZEND_FASTCALL _zend_mm_realloc2(zend_mm_heap *heap, void *p, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
     268             : ZEND_API size_t ZEND_FASTCALL _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
     269             : 
     270             : #define zend_mm_alloc(heap, size)                       _zend_mm_alloc((heap), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     271             : #define zend_mm_free(heap, p)                           _zend_mm_free((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     272             : #define zend_mm_realloc(heap, p, size)          _zend_mm_realloc((heap), (p), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     273             : #define zend_mm_realloc2(heap, p, size, copy_size) _zend_mm_realloc2((heap), (p), (size), (copy_size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     274             : #define zend_mm_block_size(heap, p)                     _zend_mm_block_size((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     275             : 
     276             : #define zend_mm_alloc_rel(heap, size)           _zend_mm_alloc((heap), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     277             : #define zend_mm_free_rel(heap, p)                       _zend_mm_free((heap), (p) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     278             : #define zend_mm_realloc_rel(heap, p, size)      _zend_mm_realloc((heap), (p), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     279             : #define zend_mm_realloc2_rel(heap, p, size, copy_size) _zend_mm_realloc2((heap), (p), (size), (copy_size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
     280             : #define zend_mm_block_size_rel(heap, p)         _zend_mm_block_size((heap), (p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
     281             : 
     282             : ZEND_API zend_mm_heap *zend_mm_set_heap(zend_mm_heap *new_heap);
     283             : 
     284             : ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
     285             :                                           void* (*_malloc)(size_t),
     286             :                                           void  (*_free)(void*),
     287             :                                           void* (*_realloc)(void*, size_t));
     288             : ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
     289             :                                           void* (**_malloc)(size_t),
     290             :                                           void  (**_free)(void*),
     291             :                                           void* (**_realloc)(void*, size_t));
     292             : 
     293             : typedef struct _zend_mm_storage zend_mm_storage;
     294             : 
     295             : typedef void* (*zend_mm_chunk_alloc_t)(zend_mm_storage *storage, size_t size, size_t alignment);
     296             : typedef void  (*zend_mm_chunk_free_t)(zend_mm_storage *storage, void *chunk, size_t size);
     297             : typedef int   (*zend_mm_chunk_truncate_t)(zend_mm_storage *storage, void *chunk, size_t old_size, size_t new_size);
     298             : typedef int   (*zend_mm_chunk_extend_t)(zend_mm_storage *storage, void *chunk, size_t old_size, size_t new_size);
     299             : 
     300             : typedef struct _zend_mm_handlers {
     301             :         zend_mm_chunk_alloc_t       chunk_alloc;
     302             :         zend_mm_chunk_free_t        chunk_free;
     303             :         zend_mm_chunk_truncate_t    chunk_truncate;
     304             :         zend_mm_chunk_extend_t      chunk_extend;
     305             : } zend_mm_handlers;
     306             : 
     307             : struct _zend_mm_storage {
     308             :         const zend_mm_handlers handlers;
     309             :         void *data;
     310             : };
     311             : 
     312             : ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap);
     313             : ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void *data, size_t data_size);
     314             : 
     315             : /*
     316             : 
     317             : // The following example shows how to use zend_mm_heap API with custom storage
     318             : 
     319             : static zend_mm_heap *apc_heap = NULL;
     320             : static HashTable    *apc_ht = NULL;
     321             : 
     322             : typedef struct _apc_data {
     323             :         void     *mem;
     324             :         uint32_t  free_pages;
     325             : } apc_data;
     326             : 
     327             : static void *apc_chunk_alloc(zend_mm_storage *storage, size_t size, size_t alignment)
     328             : {
     329             :         apc_data *data = (apc_data*)(storage->data);
     330             :         size_t real_size = ((size + (ZEND_MM_CHUNK_SIZE-1)) & ~(ZEND_MM_CHUNK_SIZE-1));
     331             :         uint32_t count = real_size / ZEND_MM_CHUNK_SIZE;
     332             :         uint32_t first, last, i;
     333             : 
     334             :         ZEND_ASSERT(alignment == ZEND_MM_CHUNK_SIZE);
     335             : 
     336             :         for (first = 0; first < 32; first++) {
     337             :                 if (!(data->free_pages & (1 << first))) {
     338             :                         last = first;
     339             :                         do {
     340             :                                 if (last - first == count - 1) {
     341             :                                         for (i = first; i <= last; i++) {
     342             :                                                 data->free_pages |= (1 << i);
     343             :                                         }
     344             :                                         return (void *)(((char*)(data->mem)) + ZEND_MM_CHUNK_SIZE * (1 << first));
     345             :                                 }
     346             :                                 last++;
     347             :                         } while (last < 32 && !(data->free_pages & (1 << last)));
     348             :                         first = last;
     349             :                 }
     350             :         }
     351             :         return NULL;
     352             : }
     353             : 
     354             : static void apc_chunk_free(zend_mm_storage *storage, void *chunk, size_t size)
     355             : {
     356             :         apc_data *data = (apc_data*)(storage->data);
     357             :         uint32_t i;
     358             : 
     359             :         ZEND_ASSERT(((uintptr_t)chunk & (ZEND_MM_CHUNK_SIZE - 1)) == 0);
     360             : 
     361             :         i = ((uintptr_t)chunk - (uintptr_t)(data->mem)) / ZEND_MM_CHUNK_SIZE;
     362             :         while (1) {
     363             :                 data->free_pages &= ~(1 << i);
     364             :                 if (size <= ZEND_MM_CHUNK_SIZE) {
     365             :                         break;
     366             :                 }
     367             :                 size -= ZEND_MM_CHUNK_SIZE;
     368             :         }
     369             : }
     370             : 
     371             : static void apc_init_heap(void)
     372             : {
     373             :         zend_mm_handlers apc_handlers = {
     374             :                 apc_chunk_alloc,
     375             :                 apc_chunk_free,
     376             :                 NULL,
     377             :                 NULL,
     378             :         };
     379             :         apc_data tmp_data;
     380             :         zend_mm_heap *old_heap;
     381             : 
     382             :         // Preallocate properly aligned SHM chunks (64MB)
     383             :         tmp_data.mem = shm_memalign(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE * 32);
     384             :         
     385             :         // Initialize temporary storage data
     386             :         tmp_data.free_pages = 0;
     387             : 
     388             :         // Create heap
     389             :         apc_heap = zend_mm_startup_ex(&apc_handlers, &tmp_data, sizeof(tmp_data));
     390             : 
     391             :         // Allocate some data in the heap
     392             :         old_heap = zend_mm_set_heap(apc_heap);
     393             :         ALLOC_HASHTABLE(apc_ht);
     394             :         zend_hash_init(apc_ht, 64, NULL, ZVAL_PTR_DTOR, 0);
     395             :         zend_mm_set_heap(old_heap);
     396             : }
     397             :  
     398             : */
     399             : 
     400             : END_EXTERN_C()
     401             : 
     402             : #endif
     403             : 
     404             : /*
     405             :  * Local variables:
     406             :  * tab-width: 4
     407             :  * c-basic-offset: 4
     408             :  * indent-tabs-mode: t
     409             :  * End:
     410             :  */

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:58:51 +0000 (3 days ago)

Copyright © 2005-2015 The PHP Group
All rights reserved.