Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
pool.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Pool memory allocation
4 *
5 * Authors:
6 * Stéphane Gimenez <dev@gim.name>
7 *
8 * Copyright (C) 2004-2006 Authors
9 *
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 */
12
13// not thread safe (a pool cannot be shared by threads safely)
14
15/*
16-- principle:
17
18 - user operations on a pool of objects of type T are:
19 - T *draw() : obtain a unused slot to store an object T
20 - void drop(T *) : release a slot
21
22-- implementation:
23
24 - a pool for objects T is:
25
26 * blocks[64] : an array of allocated blocks of memory:
27 |---0--> block with capacity 64
28 |---1--> block with capacity 64
29 |---2--> block with capacity 128
30 |---3--> block with capacity 128
31 |---4--> block with capacity 256
32 |---5--> block with capacity 256
33 |---6--> block with capacity 512
34 |---7--> not yet allocated
35 :
36 |---k--> not yet allocated (future capacity ~ 2^(6+k/2))
37 :
38 '--63--> not yet allocated
39 * cblock : the index of the next unallocated block (here 7).
40 * next : a pointer to an unused slot inside an allocated bloc
41
42 - the first bytes of an unallocated slot inside a bloc are used to store a
43 pointer to some other unallocated slot. (this way, we keep a list of all
44 unused slots starting at <next>)
45
46 - insertions and deletions in this list are done at the root <next>.
47 if <next> points to NULL (no slots are available) when a draw()
48 operation is performed a new block is allocated, and the unused slots
49 list is filled with the allocated slots.
50
51 - memory is freed only at pool's deletion.
52*/
53#ifndef INKSCAPE_TRACE_POOL_H
54#define INKSCAPE_TRACE_POOL_H
55
56#include <cstdlib>
57#include <exception>
58#include <algorithm>
59
60template <typename T>
61class Pool
62{
63public:
65 {
66 cblock = 0;
67 size = std::max(sizeof(T), sizeof(void *));
68 next = nullptr;
69 for (auto &k : block) {
70 k = nullptr;
71 }
72 }
73
75 {
76 for (int k = 0; k < cblock; k++) {
77 std::free(block[k]);
78 }
79 }
80
81 T *draw()
82 {
83 if (!next) addblock();
84 void *p = next;
85 next = *(void **)p;
86 return (T *)p;
87 }
88
89 void drop(T *p)
90 {
91 *(void **)p = next;
92 next = (void *)p;
93 }
94
95private:
96 int size;
97 int cblock;
98 void *block[64]; // enough to store unlimited number of objects, if 64 is changed: see constructor too
99 void *next;
100
101 void addblock()
102 {
103 int i = cblock++;
104 int blocksize = 1 << (6 + (i / 2));
105 block[i] = (void *)std::malloc(blocksize * size);
106 if (!block[i]) throw std::bad_alloc();
107 char *p = (char *)block[i];
108 for (int k = 0; k < blocksize - 1; k++) {
109 *(void**)p = (void *)(p + size);
110 p += size;
111 }
112 *(void **)p = next;
113 next = block[i];
114 }
115};
116
117#endif // INKSCAPE_TRACE_POOL_H
Definition pool.h:62
void * next
Definition pool.h:99
T * draw()
Definition pool.h:81
int size
Definition pool.h:96
void drop(T *p)
Definition pool.h:89
void * block[64]
Definition pool.h:98
int cblock
Definition pool.h:97
Pool()
Definition pool.h:64
~Pool()
Definition pool.h:74
void addblock()
Definition pool.h:101