• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

Arena.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 #include "libts.h"
00025 #include <assert.h>
00026 #include <string.h>
00027 
00028 
00029 #define DEFAULT_ALLOC_SIZE   1024
00030 #define DEFAULT_BLOCK_SIZE   (DEFAULT_ALLOC_SIZE - (sizeof (ArenaBlock) - 8))
00031 
00032 
00033 static Allocator defaultSizeArenaBlock("ArenaBlock", DEFAULT_ALLOC_SIZE);
00034 
00035 
00036 /*-------------------------------------------------------------------------
00037   -------------------------------------------------------------------------*/
00038 
00039 static inline ArenaBlock *
00040 blk_alloc(int size)
00041 {
00042   ArenaBlock *blk;
00043 
00044   if (size == DEFAULT_BLOCK_SIZE) {
00045     blk = (ArenaBlock *) defaultSizeArenaBlock.alloc_void();
00046   } else {
00047     blk = (ArenaBlock *)ats_malloc(size + sizeof(ArenaBlock) - 8);
00048   }
00049 
00050   blk->next = NULL;
00051   blk->m_heap_end = &blk->data[size];
00052   blk->m_water_level = &blk->data[0];
00053 
00054   return blk;
00055 }
00056 
00057 /*-------------------------------------------------------------------------
00058   -------------------------------------------------------------------------*/
00059 
00060 static inline void
00061 blk_free(ArenaBlock * blk)
00062 {
00063   int size;
00064 
00065   size = blk->m_heap_end - &blk->data[0];
00066   if (size == DEFAULT_BLOCK_SIZE) {
00067     defaultSizeArenaBlock.free_void(blk);
00068   } else {
00069     ats_free(blk);
00070   }
00071 }
00072 
00073 
00074 /*-------------------------------------------------------------------------
00075   -------------------------------------------------------------------------*/
00076 
00077 static void *
00078 block_alloc(ArenaBlock * block, size_t size, size_t alignment)
00079 {
00080   char *mem;
00081 
00082   mem = block->m_water_level;
00083   if (((size_t) mem) & (alignment - 1)) {
00084     mem += (alignment - ((size_t) mem)) & (alignment - 1);
00085   }
00086 
00087   if ((block->m_heap_end >= mem) && (((size_t) block->m_heap_end - (size_t) mem) >= size)) {
00088     block->m_water_level = mem + size;
00089     return mem;
00090   }
00091 
00092   return NULL;
00093 }
00094 
00095 void *
00096 Arena::alloc(size_t size, size_t alignment)
00097 {
00098   ArenaBlock *b;
00099   unsigned int block_size;
00100   void *mem;
00101 
00102   ink_assert((alignment & (alignment - 1)) == 0);
00103 
00104   b = m_blocks;
00105   while (b) {
00106     mem = block_alloc(b, size, alignment);
00107     if (mem) {
00108       return mem;
00109     }
00110     b = b->next;
00111   }
00112 
00113   block_size = (unsigned int) (size * 1.5);
00114   if (block_size < DEFAULT_BLOCK_SIZE) {
00115     block_size = DEFAULT_BLOCK_SIZE;
00116   }
00117 
00118   b = blk_alloc(block_size);
00119   b->next = m_blocks;
00120   m_blocks = b;
00121 
00122   mem = block_alloc(b, size, alignment);
00123   return mem;
00124 }
00125 
00126 /*-------------------------------------------------------------------------
00127   -------------------------------------------------------------------------*/
00128 
00129 void
00130 Arena::free(void *mem, size_t size)
00131 {
00132   if (m_blocks) {
00133     ArenaBlock *b;
00134 
00135     b = m_blocks;
00136     while (b->next) {
00137       b = b->next;
00138     }
00139 
00140     if (b->m_water_level == ((char *) mem + size)) {
00141       b->m_water_level = (char *) mem;
00142     }
00143   }
00144 }
00145 
00146 /*-------------------------------------------------------------------------
00147   -------------------------------------------------------------------------*/
00148 
00149 void
00150 Arena::reset()
00151 {
00152   ArenaBlock *b;
00153 
00154   while (m_blocks) {
00155     b = m_blocks->next;
00156     blk_free(m_blocks);
00157     m_blocks = b;
00158   }
00159   ink_assert(m_blocks == NULL);
00160 }

Generated by  doxygen 1.7.1