1 | // |
---|---|
2 | // MemoryPool.cpp |
3 | // |
4 | // Library: Foundation |
5 | // Package: Core |
6 | // Module: MemoryPool |
7 | // |
8 | // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/MemoryPool.h" |
16 | #include "Poco/Exception.h" |
17 | |
18 | |
19 | namespace Poco { |
20 | |
21 | |
22 | MemoryPool::MemoryPool(std::size_t blockLength, int preAlloc, int maxAlloc): |
23 | _blockSize(blockLength), |
24 | _maxAlloc(maxAlloc), |
25 | _allocated(preAlloc) |
26 | { |
27 | poco_assert (maxAlloc == 0 || maxAlloc >= preAlloc); |
28 | poco_assert (preAlloc >= 0 && maxAlloc >= 0); |
29 | |
30 | int r = BLOCK_RESERVE; |
31 | if (preAlloc > r) |
32 | r = preAlloc; |
33 | if (maxAlloc > 0 && maxAlloc < r) |
34 | r = maxAlloc; |
35 | _blocks.reserve(r); |
36 | |
37 | try |
38 | { |
39 | for (int i = 0; i < preAlloc; ++i) |
40 | { |
41 | _blocks.push_back(new char[_blockSize]); |
42 | } |
43 | } |
44 | catch (...) |
45 | { |
46 | clear(); |
47 | throw; |
48 | } |
49 | } |
50 | |
51 | |
52 | MemoryPool::~MemoryPool() |
53 | { |
54 | clear(); |
55 | } |
56 | |
57 | |
58 | void MemoryPool::clear() |
59 | { |
60 | for (BlockVec::iterator it = _blocks.begin(); it != _blocks.end(); ++it) |
61 | { |
62 | delete [] *it; |
63 | } |
64 | _blocks.clear(); |
65 | } |
66 | |
67 | |
68 | void* MemoryPool::get() |
69 | { |
70 | FastMutex::ScopedLock lock(_mutex); |
71 | |
72 | if (_blocks.empty()) |
73 | { |
74 | if (_maxAlloc == 0 || _allocated < _maxAlloc) |
75 | { |
76 | ++_allocated; |
77 | return new char[_blockSize]; |
78 | } |
79 | else throw OutOfMemoryException("MemoryPool exhausted"); |
80 | } |
81 | else |
82 | { |
83 | char* ptr = _blocks.back(); |
84 | _blocks.pop_back(); |
85 | return ptr; |
86 | } |
87 | } |
88 | |
89 | |
90 | void MemoryPool::release(void* ptr) |
91 | { |
92 | FastMutex::ScopedLock lock(_mutex); |
93 | |
94 | try |
95 | { |
96 | _blocks.push_back(reinterpret_cast<char*>(ptr)); |
97 | } |
98 | catch (...) |
99 | { |
100 | delete [] reinterpret_cast<char*>(ptr); |
101 | } |
102 | } |
103 | |
104 | |
105 | } // namespace Poco |
106 |