reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 1 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 2 | * Copyright 2010 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 6 | */ |
| 7 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 8 | #include "GrAllocPool.h" |
| 9 | |
commit-bot@chromium.org | a0b4028 | 2013-09-18 13:00:55 +0000 | [diff] [blame] | 10 | #include "GrTypes.h" |
| 11 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 12 | #define GrAllocPool_MIN_BLOCK_SIZE ((size_t)128) |
| 13 | |
| 14 | struct GrAllocPool::Block { |
| 15 | Block* fNext; |
| 16 | char* fPtr; |
| 17 | size_t fBytesFree; |
| 18 | size_t fBytesTotal; |
| 19 | |
| 20 | static Block* Create(size_t size, Block* next) { |
tfarina@chromium.org | f6de475 | 2013-08-17 00:02:59 +0000 | [diff] [blame] | 21 | SkASSERT(size >= GrAllocPool_MIN_BLOCK_SIZE); |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 22 | |
reed@google.com | 939ca7c | 2013-09-26 19:56:51 +0000 | [diff] [blame] | 23 | Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 24 | block->fNext = next; |
| 25 | block->fPtr = (char*)block + sizeof(Block); |
| 26 | block->fBytesFree = size; |
| 27 | block->fBytesTotal = size; |
| 28 | return block; |
| 29 | } |
| 30 | |
| 31 | bool canAlloc(size_t bytes) const { |
| 32 | return bytes <= fBytesFree; |
| 33 | } |
| 34 | |
| 35 | void* alloc(size_t bytes) { |
tfarina@chromium.org | f6de475 | 2013-08-17 00:02:59 +0000 | [diff] [blame] | 36 | SkASSERT(bytes <= fBytesFree); |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 37 | fBytesFree -= bytes; |
| 38 | void* ptr = fPtr; |
| 39 | fPtr += bytes; |
| 40 | return ptr; |
| 41 | } |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 42 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 43 | size_t release(size_t bytes) { |
tfarina@chromium.org | f6de475 | 2013-08-17 00:02:59 +0000 | [diff] [blame] | 44 | SkASSERT(bytes > 0); |
commit-bot@chromium.org | 972f9cd | 2014-03-28 17:58:28 +0000 | [diff] [blame] | 45 | size_t free = SkTMin(bytes, fBytesTotal - fBytesFree); |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 46 | fBytesFree += free; |
| 47 | fPtr -= free; |
| 48 | return bytes - free; |
| 49 | } |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 50 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 51 | bool empty() const { return fBytesTotal == fBytesFree; } |
| 52 | }; |
| 53 | |
| 54 | /////////////////////////////////////////////////////////////////////////////// |
| 55 | |
| 56 | GrAllocPool::GrAllocPool(size_t blockSize) { |
| 57 | fBlock = NULL; |
commit-bot@chromium.org | 972f9cd | 2014-03-28 17:58:28 +0000 | [diff] [blame] | 58 | fMinBlockSize = SkTMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE); |
commit-bot@chromium.org | 1acc3d7 | 2013-09-06 23:13:05 +0000 | [diff] [blame] | 59 | SkDEBUGCODE(fBlocksAllocated = 0;) |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | GrAllocPool::~GrAllocPool() { |
| 63 | this->reset(); |
| 64 | } |
| 65 | |
| 66 | void GrAllocPool::reset() { |
| 67 | this->validate(); |
| 68 | |
| 69 | Block* block = fBlock; |
| 70 | while (block) { |
| 71 | Block* next = block->fNext; |
reed@google.com | 939ca7c | 2013-09-26 19:56:51 +0000 | [diff] [blame] | 72 | sk_free(block); |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 73 | block = next; |
| 74 | } |
| 75 | fBlock = NULL; |
commit-bot@chromium.org | 1acc3d7 | 2013-09-06 23:13:05 +0000 | [diff] [blame] | 76 | SkDEBUGCODE(fBlocksAllocated = 0;) |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 77 | } |
| 78 | |
| 79 | void* GrAllocPool::alloc(size_t size) { |
| 80 | this->validate(); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 81 | |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 82 | if (!fBlock || !fBlock->canAlloc(size)) { |
commit-bot@chromium.org | 972f9cd | 2014-03-28 17:58:28 +0000 | [diff] [blame] | 83 | size_t blockSize = SkTMax(fMinBlockSize, size); |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 84 | fBlock = Block::Create(blockSize, fBlock); |
commit-bot@chromium.org | 1acc3d7 | 2013-09-06 23:13:05 +0000 | [diff] [blame] | 85 | SkDEBUGCODE(fBlocksAllocated += 1;) |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 86 | } |
| 87 | return fBlock->alloc(size); |
| 88 | } |
| 89 | |
| 90 | void GrAllocPool::release(size_t bytes) { |
| 91 | this->validate(); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 92 | |
bsalomon | 49f085d | 2014-09-05 13:34:00 -0700 | [diff] [blame] | 93 | while (bytes && fBlock) { |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 94 | bytes = fBlock->release(bytes); |
| 95 | if (fBlock->empty()) { |
| 96 | Block* next = fBlock->fNext; |
reed@google.com | 939ca7c | 2013-09-26 19:56:51 +0000 | [diff] [blame] | 97 | sk_free(fBlock); |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 98 | fBlock = next; |
commit-bot@chromium.org | 1acc3d7 | 2013-09-06 23:13:05 +0000 | [diff] [blame] | 99 | SkDEBUGCODE(fBlocksAllocated -= 1;) |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 100 | } |
| 101 | } |
| 102 | } |
| 103 | |
commit-bot@chromium.org | 515dcd3 | 2013-08-28 14:17:03 +0000 | [diff] [blame] | 104 | #ifdef SK_DEBUG |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 105 | |
| 106 | void GrAllocPool::validate() const { |
| 107 | Block* block = fBlock; |
| 108 | int count = 0; |
| 109 | while (block) { |
| 110 | count += 1; |
| 111 | block = block->fNext; |
| 112 | } |
tfarina@chromium.org | f6de475 | 2013-08-17 00:02:59 +0000 | [diff] [blame] | 113 | SkASSERT(fBlocksAllocated == count); |
reed@google.com | ac10a2d | 2010-12-22 21:39:39 +0000 | [diff] [blame] | 114 | } |
| 115 | |
| 116 | #endif |