Click
Loading...
Searching...
No Matches
hashallocator.hh
1// -*- related-file-name: "../../lib/hashallocator.cc" -*-
2#ifndef CLICK_HASHALLOCATOR_HH
3#define CLICK_HASHALLOCATOR_HH
4#if HAVE_VALGRIND && HAVE_VALGRIND_MEMCHECK_H
5# include <valgrind/memcheck.h>
6#endif
7CLICK_DECLS
8
9class HashAllocator { public:
10
11 HashAllocator(size_t size);
12 ~HashAllocator();
13
14 inline void increase_size(size_t new_size) {
15 assert(!_free && !_buffer && new_size >= _size);
16 _size = new_size;
17 }
18
19 inline void *allocate();
20 inline void deallocate(void *p);
21
22 void swap(HashAllocator &x);
23
24 private:
25
26#if HAVE_HASH_ALLOCATOR_POISONING
27 // Freed blocks are poisoned with this byte value.
28 static const uint8_t poison_byte = 0x0d;
29#endif
30
31 struct link {
32 link *next;
33 };
34
35 struct buffer {
36 buffer *next;
37 size_t pos;
38 size_t maxpos;
39 };
40
41 enum {
42 min_buffer_size = 1024,
43#if CLICK_LINUXMODULE
44 max_buffer_size = 16384,
45#else
46 max_buffer_size = 1048576,
47#endif
48 min_nelements = 8
49 };
50
51 link *_free;
52 buffer *_buffer;
53 size_t _size;
54
55 void *hard_allocate();
56
57 HashAllocator(const HashAllocator &x);
58 HashAllocator &operator=(const HashAllocator &x);
59
60};
61
62
63template <size_t size>
64class SizedHashAllocator : public HashAllocator { public:
65
66 SizedHashAllocator()
67 : HashAllocator(size) {
68 }
69
70};
71
72
73inline void *HashAllocator::allocate()
74{
75 if (link *l = _free) {
76#ifdef VALGRIND_MEMPOOL_ALLOC
77 VALGRIND_MEMPOOL_ALLOC(this, l, _size);
78 VALGRIND_MAKE_MEM_DEFINED(&l->next, sizeof(l->next));
79#endif
80 _free = l->next;
81#ifdef VALGRIND_MAKE_MEM_DEFINED
82 VALGRIND_MAKE_MEM_UNDEFINED(&l->next, sizeof(l->next));
83#endif
84 return l;
85 } else if (_buffer && _buffer->pos < _buffer->maxpos) {
86 void *data = reinterpret_cast<char *>(_buffer) + _buffer->pos;
87 _buffer->pos += _size;
88#ifdef VALGRIND_MEMPOOL_ALLOC
89 VALGRIND_MEMPOOL_ALLOC(this, data, _size);
90#endif
91 return data;
92 } else
93 return hard_allocate();
94}
95
96inline void HashAllocator::deallocate(void *p)
97{
98 if (p) {
99#if HAVE_HASH_ALLOCATOR_POISONING
100 memset(p, poison_byte, _size);
101#endif
102 reinterpret_cast<link *>(p)->next = _free;
103 _free = reinterpret_cast<link *>(p);
104#ifdef VALGRIND_MEMPOOL_FREE
105 VALGRIND_MEMPOOL_FREE(this, p);
106#endif
107 }
108}
109
110CLICK_ENDDECLS
111#endif