a8fa13c114c5bb8a1750fa410341483f89349372
[com/gs-lite.git] / src / lib / gscpaux / block_allocator.cpp
1 // Distributed under the MIT license. Copyright (c) 2010, Ivan Vashchaev\r
2 \r
3 #include <stdlib.h>\r
4 #include <algorithm>\r
5 #include "block_allocator.h"\r
6 \r
7 block_allocator::block_allocator(size_t blocksize): m_head(0), m_blocksize(blocksize)\r
8 {\r
9 }\r
10 \r
11 block_allocator::~block_allocator()\r
12 {\r
13         while (m_head)\r
14         {\r
15                 block *temp = m_head->next;\r
16                 ::free(m_head);\r
17                 m_head = temp;\r
18         }\r
19 }\r
20 \r
21 void block_allocator::swap(block_allocator &rhs)\r
22 {\r
23         std::swap(m_blocksize, rhs.m_blocksize);\r
24         std::swap(m_head, rhs.m_head);\r
25 }\r
26 \r
27 void *block_allocator::malloc(size_t size)\r
28 {\r
29         if ((m_head && m_head->used + size > m_head->size) || !m_head)\r
30         {\r
31                 // calc needed size for allocation\r
32                 size_t alloc_size = std::max(sizeof(block) + size, m_blocksize);\r
33 \r
34                 // create new block\r
35                 char *buffer = (char *)::malloc(alloc_size);\r
36                 block *b = reinterpret_cast<block *>(buffer);\r
37                 b->size = alloc_size;\r
38                 b->used = sizeof(block);\r
39                 b->buffer = buffer;\r
40                 b->next = m_head;\r
41                 m_head = b;\r
42         }\r
43 \r
44         void *ptr = m_head->buffer + m_head->used;\r
45         m_head->used += size;\r
46         return ptr;\r
47 }\r
48 \r
49 void block_allocator::free()\r
50 {\r
51         block_allocator(0).swap(*this);\r
52 }\r