plarena.h
上传用户:goldcmy89
上传日期:2017-12-03
资源大小:2246k
文件大小:8k
源码类别:

PlugIns编程

开发平台:

Visual C++

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  * 
  15.  * The Original Code is the Netscape Portable Runtime (NSPR).
  16.  * 
  17.  * The Initial Developer of the Original Code is Netscape
  18.  * Communications Corporation.  Portions created by Netscape are 
  19.  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
  20.  * Rights Reserved.
  21.  * 
  22.  * Contributor(s):
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK *****
  37.  */
  38. #ifndef plarena_h___
  39. #define plarena_h___
  40. /*
  41.  * Lifetime-based fast allocation, inspired by much prior art, including
  42.  * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
  43.  * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
  44.  *
  45.  * Also supports LIFO allocation (PL_ARENA_MARK/PL_ARENA_RELEASE).
  46.  */
  47. #include "prtypes.h"
  48. #include "plarenas.h"
  49. PR_BEGIN_EXTERN_C
  50. typedef struct PLArena          PLArena;
  51. struct PLArena {
  52.     PLArena     *next;          /* next arena for this lifetime */
  53.     PRUword     base;           /* aligned base address, follows this header */
  54.     PRUword     limit;          /* one beyond last byte in arena */
  55.     PRUword     avail;          /* points to next available byte */
  56. };
  57. #ifdef PL_ARENAMETER
  58. typedef struct PLArenaStats PLArenaStats;
  59. struct PLArenaStats {
  60.     PLArenaStats  *next;        /* next in arenaStats list */
  61.     char          *name;        /* name for debugging */
  62.     PRUint32      narenas;      /* number of arenas in pool */
  63.     PRUint32      nallocs;      /* number of PL_ARENA_ALLOCATE() calls */
  64.     PRUint32      nreclaims;    /* number of reclaims from freeArenas */
  65.     PRUint32      nmallocs;     /* number of malloc() calls */
  66.     PRUint32      ndeallocs;    /* number of lifetime deallocations */
  67.     PRUint32      ngrows;       /* number of PL_ARENA_GROW() calls */
  68.     PRUint32      ninplace;     /* number of in-place growths */
  69.     PRUint32      nreleases;    /* number of PL_ARENA_RELEASE() calls */
  70.     PRUint32      nfastrels;    /* number of "fast path" releases */
  71.     PRUint32      nbytes;       /* total bytes allocated */
  72.     PRUint32      maxalloc;     /* maximum allocation size in bytes */
  73.     PRFloat64     variance;     /* size variance accumulator */
  74. };
  75. #endif
  76. struct PLArenaPool {
  77.     PLArena     first;          /* first arena in pool list */
  78.     PLArena     *current;       /* arena from which to allocate space */
  79.     PRUint32    arenasize;      /* net exact size of a new arena */
  80.     PRUword     mask;           /* alignment mask (power-of-2 - 1) */
  81. #ifdef PL_ARENAMETER
  82.     PLArenaStats stats;
  83. #endif
  84. };
  85. /*
  86.  * If the including .c file uses only one power-of-2 alignment, it may define
  87.  * PL_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
  88.  * per ALLOCATE and GROW.
  89.  */
  90. #ifdef PL_ARENA_CONST_ALIGN_MASK
  91. #define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + PL_ARENA_CONST_ALIGN_MASK) 
  92.                                 & ~PL_ARENA_CONST_ALIGN_MASK)
  93. #define PL_INIT_ARENA_POOL(pool, name, size) 
  94.         PL_InitArenaPool(pool, name, size, PL_ARENA_CONST_ALIGN_MASK + 1)
  95. #else
  96. #define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + (pool)->mask) & ~(pool)->mask)
  97. #endif
  98. #define PL_ARENA_ALLOCATE(p, pool, nb) 
  99.     PR_BEGIN_MACRO 
  100.         PLArena *_a = (pool)->current; 
  101.         PRUint32 _nb = PL_ARENA_ALIGN(pool, nb); 
  102.         PRUword _p = _a->avail; 
  103.         PRUword _q = _p + _nb; 
  104.         if (_q > _a->limit) 
  105.             _p = (PRUword)PL_ArenaAllocate(pool, _nb); 
  106.         else 
  107.             _a->avail = _q; 
  108.         p = (void *)_p; 
  109.         PL_ArenaCountAllocation(pool, nb); 
  110.     PR_END_MACRO
  111. #define PL_ARENA_GROW(p, pool, size, incr) 
  112.     PR_BEGIN_MACRO 
  113.         PLArena *_a = (pool)->current; 
  114.         PRUint32 _incr = PL_ARENA_ALIGN(pool, incr); 
  115.         PRUword _p = _a->avail; 
  116.         PRUword _q = _p + _incr; 
  117.         if (_p == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && 
  118.             _q <= _a->limit) { 
  119.             _a->avail = _q; 
  120.             PL_ArenaCountInplaceGrowth(pool, size, incr); 
  121.         } else { 
  122.             p = PL_ArenaGrow(pool, p, size, incr); 
  123.         } 
  124.         PL_ArenaCountGrowth(pool, size, incr); 
  125.     PR_END_MACRO
  126. #define PL_ARENA_MARK(pool) ((void *) (pool)->current->avail)
  127. #define PR_UPTRDIFF(p,q) ((PRUword)(p) - (PRUword)(q))
  128. #ifdef DEBUG
  129. #define PL_FREE_PATTERN 0xDA
  130. #define PL_CLEAR_UNUSED(a) (PR_ASSERT((a)->avail <= (a)->limit), 
  131.                            memset((void*)(a)->avail, PL_FREE_PATTERN, 
  132.                            (a)->limit - (a)->avail))
  133. #define PL_CLEAR_ARENA(a)  memset((void*)(a), PL_FREE_PATTERN, 
  134.                            (a)->limit - (PRUword)(a))
  135. #else
  136. #define PL_CLEAR_UNUSED(a)
  137. #define PL_CLEAR_ARENA(a)
  138. #endif
  139. #define PL_ARENA_RELEASE(pool, mark) 
  140.     PR_BEGIN_MACRO 
  141.         char *_m = (char *)(mark); 
  142.         PLArena *_a = (pool)->current; 
  143.         if (PR_UPTRDIFF(_m, _a->base) <= PR_UPTRDIFF(_a->avail, _a->base)) { 
  144.             _a->avail = (PRUword)PL_ARENA_ALIGN(pool, _m); 
  145.             PL_CLEAR_UNUSED(_a); 
  146.             PL_ArenaCountRetract(pool, _m); 
  147.         } else { 
  148.             PL_ArenaRelease(pool, _m); 
  149.         } 
  150.         PL_ArenaCountRelease(pool, _m); 
  151.     PR_END_MACRO
  152. #ifdef PL_ARENAMETER
  153. #define PL_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
  154. #else
  155. #define PL_COUNT_ARENA(pool,op)
  156. #endif
  157. #define PL_ARENA_DESTROY(pool, a, pnext) 
  158.     PR_BEGIN_MACRO 
  159.         PL_COUNT_ARENA(pool,--); 
  160.         if ((pool)->current == (a)) (pool)->current = &(pool)->first; 
  161.         *(pnext) = (a)->next; 
  162.         PL_CLEAR_ARENA(a); 
  163.         free(a); 
  164.         (a) = 0; 
  165.     PR_END_MACRO
  166. #ifdef PL_ARENAMETER
  167. #include <stdio.h>
  168. PR_EXTERN(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb);
  169. PR_EXTERN(void) PL_ArenaCountInplaceGrowth(
  170.     PLArenaPool *pool, PRUint32 size, PRUint32 incr);
  171. PR_EXTERN(void) PL_ArenaCountGrowth(
  172.     PLArenaPool *pool, PRUint32 size, PRUint32 incr);
  173. PR_EXTERN(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark);
  174. PR_EXTERN(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark);
  175. PR_EXTERN(void) PL_DumpArenaStats(FILE *fp);
  176. #else  /* !PL_ARENAMETER */
  177. #define PL_ArenaCountAllocation(ap, nb)                 /* nothing */
  178. #define PL_ArenaCountInplaceGrowth(ap, size, incr)      /* nothing */
  179. #define PL_ArenaCountGrowth(ap, size, incr)             /* nothing */
  180. #define PL_ArenaCountRelease(ap, mark)                  /* nothing */
  181. #define PL_ArenaCountRetract(ap, mark)                  /* nothing */
  182. #endif /* !PL_ARENAMETER */
  183. PR_END_EXTERN_C
  184. #endif /* plarena_h___ */