-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmem_mgr.hpp
128 lines (100 loc) · 3.5 KB
/
mem_mgr.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#ifndef _SCTL_MEM_MGR_HPP_
#define _SCTL_MEM_MGR_HPP_
#include <map> // for __map_iterator, multimap
#include <set> // for set
#include <stack> // for stack
#include <typeinfo> // for type_info
#include <vector> // for vector
#include "sctl/common.hpp" // for Long, sctl
// TODO: Implement fast stack allocation.
namespace sctl {
/**
* MemoryManager class declaration.
*/
class MemoryManager {
public:
static constexpr char init_mem_val = 42;
static constexpr Long end_padding = 64;
/**
* Header data for each memory block.
*/
struct MemHead {
typedef decltype(typeid(char).hash_code()) TypeID;
Long n_indx;
Long n_elem;
Long type_size;
Long alloc_ctr;
TypeID type_id;
#ifdef SCTL_MEMDEBUG
unsigned char check_sum;
#endif
};
/**
* Constructor for MemoryManager.
*/
explicit MemoryManager(Long N);
/**
* Constructor for MemoryManager.
*/
~MemoryManager();
static MemHead& GetMemHead(char* p);
static void CheckMemHead(const MemHead& p);
Iterator<char> malloc(const Long n_elem, const Long type_size = sizeof(char), const MemHead::TypeID type_id = typeid(char).hash_code()) const;
void free(Iterator<char> p) const;
void print() const;
static void test();
// Check all free memory equals init_mem_val
void Check() const;
// A global MemoryManager object. This is the default for aligned_new and aligned_free
static MemoryManager& glbMemMgr() {
static MemoryManager m(SCTL_GLOBAL_MEM_BUFF * 1024LL * 1024LL);
return m;
}
private:
// Private constructor
MemoryManager();
// Private copy constructor
MemoryManager(const MemoryManager& m);
/**
* Node structure for a doubly linked list, representing free and
* occupied memory blocks. Blocks are split, merged or state is changed
* between free and occupied in O(1) time given the pointer to the MemNode.
*/
struct MemNode {
bool free;
Long size;
char* mem_ptr;
Long prev, next;
std::multimap<Long, Long>::iterator it;
};
/**
* Return index of one of the available MemNodes from node_stack or
* create new MemNode by resizing node_buff.
*/
Long new_node() const;
/**
* Add node index for now available MemNode to node_stack.
*/
void delete_node(Long indx) const;
char* buff; // pointer to memory buffer.
Long buff_size; // total buffer size in bytes.
Long n_dummy_indx; // index of first (dummy) MemNode in link list.
mutable std::vector<MemNode> node_buff; // storage for MemNode objects, this can only grow.
mutable std::stack<Long> node_stack; // stack of available free MemNodes from node_buff.
mutable std::multimap<Long, Long> free_map; // pair (MemNode.size, MemNode_id) for all free MemNodes.
//mutable omp_lock_t omp_lock; // openmp lock to prevent concurrent changes.
//mutable std::mutex mutex_lock;
mutable std::set<void*> system_malloc; // track pointers allocated using system malloc.
};
/**
* Aligned allocation as an alternative to new. Uses placement new to
* construct objects.
*/
template <class ValueType> Iterator<ValueType> aligned_new(Long n_elem = 1, const MemoryManager* mem_mgr = &MemoryManager::glbMemMgr());
/**
* Aligned de-allocation as an alternative to delete. Calls the object
* destructor.
*/
template <class ValueType> void aligned_delete(Iterator<ValueType> A, const MemoryManager* mem_mgr = &MemoryManager::glbMemMgr());
} // end namespace sctl
#endif // _SCTL_MEM_MGR_HPP_