blob: c6f021ad230f5a2fe2999e906646edf9ec01b7c3 (
plain) (
blame)
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
|
#include <foundation/buffer.h>
#include <foundation/malloc.h>
#include "slab.h"
//------------------------------------------------------------------------------
Allocator::~Allocator()
{
if (_slab != nullptr)
_slab->dec_ref();
}
//------------------------------------------------------------------------------
MutableBuffer Allocator::create_buffer(uint32 size)
{
auto create_slab = [this] (uint32 slab_size) {
auto* slab = tt_malloc<Slab>(slab_size + sizeof(Slab));
slab->_allocator = this;
slab->_size = slab_size;
slab->_refs.store_relaxed(0);
return slab;
};
enum {
PACKET_PAGE_SIZE = 4 << 10,
PACKET_SLAB_SIZE = 1 << 20,
PACKET_ALIGN = 32 - 1,
};
if (size > PACKET_PAGE_SIZE)
{
Slab* slab = create_slab(size);
return MutableBuffer(slab, size, 0);
}
uint32 alloc_size = (size + PACKET_ALIGN) & ~PACKET_ALIGN;
UniqueLock _(_lock);
if (alloc_size > _slab_free && _slab != nullptr)
{
_slab->dec_ref();
_slab = nullptr;
}
if (_slab == nullptr)
{
_slab_free = PACKET_SLAB_SIZE;
_slab = create_slab(_slab_free);
_slab->inc_ref();
}
uint32 offset = PACKET_SLAB_SIZE - _slab_free;
_slab_free -= alloc_size;
return MutableBuffer(_slab, size, offset);
}
//------------------------------------------------------------------------------
void Allocator::free_slab(Slab* slab)
{
tt_free(slab);
}
//------------------------------------------------------------------------------
Allocator& Allocator::get_from(Buffer& buffer) { return get_from(buffer._slab); }
Allocator& Allocator::get_from(BufferRef& ref) { return get_from(ref.get_slab()); }
Allocator& Allocator::get_from(BufferStream& stream){ return get_from(stream.get_slab()); }
Allocator& Allocator::get_from(Pointer& pointer) { return get_from(pointer.get_slab()); }
Allocator& Allocator::get_from(const Slab* slab) { return slab->get_allocator(); }
|