source: trunk/lib/allocator.hpp @ 2128

Last change on this file since 2128 was 2051, checked in by ksherdy, 7 years ago

Removed BOO.

File size: 4.4 KB
RevLine 
[1748]1#ifndef ALLOCATOR_HPP_
2#define ALLOCATOR_HPP_
[1946]3/*=============================================================================
4  allocator.hpp - Coterminal memory pool allocators.
5  Created on: 18-December-2011
6  Author: Ken Herdy
7=============================================================================*/
[1748]8
9#include "debug.hpp"
[1935]10#include "bitblock.hpp"
[1748]11#include <assert.h>
12#include <stdint.h>
13#include <stdlib.h>
14
15#include <iostream>
16using namespace std;
17
[1946]18///////////////////////////////////////////////////////////////////////////////
19// Base Class
20///////////////////////////////////////////////////////////////////////////////
[1748]21class pool_allocator {
22public:
[1811]23        /* n - bytes requested, allocd_segment_size - bytes allocated */
24        void * allocate (uint64_t n, uint64_t & allocd_segment_size);
25        void * allocate_aligned (uint64_t n, uint64_t & allocd_segment_size);
[1748]26        void destroy ();
27protected:
28        pool_allocator(){}
29        ~pool_allocator(){}
30};
31
[1946]32///////////////////////////////////////////////////////////////////////////////
33// Fast Memory Pool Allocator - Trade memory for speed.
34//
35// Allocates BASE_SIZE initial bytes on the stack.
36// Additional memory allocated on the heap. Coterminal deallocation.
37// Allocation returns void * pointer to memory block,
38// Returns number of bytes allocated.
39//
40///////////////////////////////////////////////////////////////////////////////
[1748]41template<uint32_t BASE_SIZE>
[1758]42class fast_pool_allocator : public pool_allocator {
[1748]43
44public:
[1758]45        fast_pool_allocator(const uint8_t align=64, const uint8_t exp=2): ALIGNMENT(align), EXPANSION_FACTOR(exp) {
[1748]46                tail = &head;
47                tail->segment = stack_segment;
48                tail->next = NULL;
49                available = BASE_SIZE;
50                segment_size = BASE_SIZE;
51        }
52
[1758]53        ~fast_pool_allocator() {}
[1748]54
[1811]55        void * allocate(uint64_t n, uint64_t & allocd_segment_size) {
[1935]56
[1758]57                if(n > available) {
58                        segment_size = next_segment_size(n);
59
60                        node * next = (node *) malloc(sizeof(node));
61                        if (next == NULL) {
62                                cerr << "Out of Memory" << endl;
63                                abort();
64                        }
65
66                        next->segment = (uint8_t *) malloc(segment_size);
67                        if ((next->segment) == NULL) {
68                                cerr << "Out of Memory" << endl;
69                                abort();
70                        }
71
72                        next->next = NULL;
73                        tail->next = next;
74                        tail = next;
[1938]75
76                        uint64_t address = reinterpret_cast<uint64_t>(&(tail->segment[0]));
77                        allocd_segment_size = segment_size;
78                        available = 0;
79
80                        return (void *) (address);
[1758]81                }
82
83                uint32_t i = segment_size - available;
84                uint64_t address = reinterpret_cast<uint64_t>(&(tail->segment[i]));
85
[1937]86                allocd_segment_size = n;
[1763]87                available -= n;
88
[1758]89                return (void *) (address);
90        }
[1938]91
[1935]92        void * allocate_aligned(uint64_t n, uint64_t & allocd_segment_size) {
[1758]93
[1748]94                uint64_t n_padded = (n+ALIGNMENT-1);
95
96                if(n_padded > available) {
[1763]97
[1748]98                        segment_size = next_segment_size(n_padded);
99
100                        node * next = (node *) malloc(sizeof(node));
101                        if (next == NULL) {
102                                cerr << "Out of Memory" << endl;
103                                abort();
104                        }
105
106                        next->segment = (uint8_t *) malloc(segment_size);
107                        if ((next->segment) == NULL) {
108                                cerr << "Out of Memory" << endl;
109                                abort();
110                        }
111
112                        next->next = NULL;
113                        tail->next = next;
114                        tail = next;
[1938]115
116                        uint64_t address = reinterpret_cast<uint64_t>(&(tail->segment[0]));
117                        uint64_t padding = ((address % ALIGNMENT) == 0) ? 0 :  ALIGNMENT - (address % ALIGNMENT);
118                        allocd_segment_size = segment_size - padding;
119                        available = 0;
120
121                        assert(((uint64_t)(address + padding))%ALIGNMENT == 0);
122                        return (void *) (address + padding);
[1748]123                }
124
125                uint32_t i = segment_size - available;
[1758]126                uint64_t address = reinterpret_cast<uint64_t>(&(tail->segment[i]));
[1748]127                uint64_t padding = ((address % ALIGNMENT) == 0) ? 0 :  ALIGNMENT - (address % ALIGNMENT);
[1938]128                allocd_segment_size = n - padding;
[1748]129                available -= (padding + n);
130
131                assert(((uint64_t)(address + padding))%ALIGNMENT == 0);
132
133                return (void *) (address + padding);
134        }
[1938]135
[1748]136        void destroy() {
137                node * crt = head.next;
138                node * next;
139                while(crt != NULL) {
140                        next = crt->next;
141                        free((uint8_t *) crt->segment);
142                        free((node *)crt);
143                        crt = next;
144                        next = NULL;
145                }
146        }
147
[1763]148        uint64_t get_alloc_size() const { return alloc_size; }
149
[1748]150private:
[1763]151        uint64_t alloc_size;
152
[1748]153        const uint8_t ALIGNMENT;
154        const uint8_t EXPANSION_FACTOR;
155        uint64_t available;
156        uint64_t segment_size;
157
158        typedef struct node {
159                node * next;
160                uint8_t * segment;
161        } node;
162
163        uint8_t stack_segment[BASE_SIZE];
164        node head;
165        node * tail;
166
167        uint64_t next_segment_size(uint64_t n) const {
168                return (((n/segment_size) * segment_size) + segment_size) * EXPANSION_FACTOR ; // a multiple of segment_size
169        }
170
171};
172
[1946]173#endif // ALLOCATOR_HPP_
Note: See TracBrowser for help on using the repository browser.