1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: BlockCache.cpp 23 // Author(s): Massimiliano Origgi 24 // 25 // Description: Handles a cache of memory blocks of the same size 26 //------------------------------------------------------------------------------ 27 28 // Standard Includes ----------------------------------------------------------- 29 #include <stdlib.h> 30 31 // System Includes ------------------------------------------------------------- 32 #include <Autolock.h> 33 #include <BlockCache.h> 34 35 36 // Private functions 37 static void * 38 object_alloc(size_t Size) 39 { 40 return (void *)(new char[Size]); 41 } 42 43 44 static void 45 object_free(void *Data) 46 { 47 delete[] Data; 48 } 49 50 51 static void* 52 malloc_alloc(size_t Size) 53 { 54 return malloc(Size); 55 } 56 57 58 static void 59 malloc_free(void *Data) 60 { 61 free(Data); 62 } 63 64 65 // Private structure for cache 66 struct _Block 67 { 68 _Block(void); 69 ~_Block(void); 70 void *Data; 71 bool InUse; 72 }; 73 74 75 _Block::_Block(void) : 76 Data(NULL), 77 InUse(false) 78 { 79 } 80 81 82 _Block::~_Block(void) 83 { 84 } 85 86 87 BBlockCache::BBlockCache(size_t CacheSize, size_t BlockSize, uint32 Type) 88 : fCacheSize(CacheSize), 89 fBlockSize(BlockSize), 90 fMark(0) 91 { 92 // Setup function pointers based on Type 93 if(Type == B_OBJECT_CACHE) { 94 fAlloc = &object_alloc; 95 fFree = &object_free; 96 } else { 97 fAlloc = &malloc_alloc; 98 fFree = &malloc_free; 99 } 100 101 // Allocate cache 102 fCache = (void *)new _Block[CacheSize]; 103 104 for(size_t i = 0; i < CacheSize; i++) 105 ((_Block *)fCache)[i].Data = fAlloc(BlockSize); 106 } 107 108 109 BBlockCache::~BBlockCache() 110 { 111 delete[] fCache; 112 } 113 114 115 void * 116 BBlockCache::Get(size_t BlockSize) 117 { 118 BAutolock lock(fLock); 119 120 if(BlockSize != fBlockSize) 121 return fAlloc(BlockSize); 122 123 _Block *block; 124 for(size_t i = fMark; i < fCacheSize; i++) { 125 block = &((_Block *)fCache)[i]; 126 if(block->InUse == false) { 127 block->InUse = true; 128 ++fMark; 129 if(fMark == fCacheSize) 130 fMark = 0; 131 return block->Data; 132 } 133 } 134 135 if(fMark == 0) 136 return fAlloc(BlockSize); 137 138 for(size_t i = 0; i < fMark; i++) { 139 block = &((_Block *)fCache)[i]; 140 if(block->InUse == false) { 141 block->InUse = true; 142 ++fMark; 143 if(fMark == fCacheSize) 144 fMark = 0; 145 return block->Data; 146 } 147 } 148 149 return fAlloc(BlockSize); 150 } 151 152 153 void 154 BBlockCache::Save(void *Data, size_t BlockSize) 155 { 156 BAutolock lock(fLock); 157 158 if(BlockSize != fBlockSize) { 159 fFree(Data); 160 return; 161 } 162 163 _Block *block; 164 for(size_t i = 0; i < fCacheSize; i++) { 165 block = &((_Block *)fCache)[i]; 166 if(block->Data == Data) { 167 block->InUse = false; 168 fMark = i; 169 return; 170 } 171 } 172 fFree(Data); 173 } 174