blob: ab004248c67377e45d724f86900745a50de084ed (
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
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
#pragma once
#include "types.h"
//------------------------------------------------------------------------------
class BufferStream;
class BufferRef;
class Slab;
//------------------------------------------------------------------------------
class Buffer
{
public:
Buffer() = default;
~Buffer();
Buffer(Buffer&& rhs);
void operator = (Buffer&& rhs);
const uint8* get_pointer() const;
uint32 get_size() const;
BufferStream create_stream() const;
BufferRef create_ref() const;
Buffer create_sub_buffer(uint32 left, uint32 right=~0u) const;
Buffer create_sub_buffer(const uint8* ptr, uint32 size) const;
protected:
friend class Allocator;
friend class BufferStream;
void inc_ref();
void dec_ref();
void move(Buffer&& rhs);
Buffer clone() const;
Slab* _slab = nullptr;
uint32 _offset = 0;
uint32 _size;
private:
Buffer(const Buffer&) = delete;
Buffer& operator = (const Buffer&) = delete;
};
//------------------------------------------------------------------------------
class MutableBuffer
: public Buffer
{
public:
MutableBuffer() = default;
uint8* get_pointer();
private:
friend class Allocator;
MutableBuffer(Slab* slab, uint32 size, uint32 offset);
};
//------------------------------------------------------------------------------
class Pointer
{
public:
Pointer() = default;
~Pointer();
Pointer(Pointer&& rhs);
void operator = (Pointer&& rhs);
bool is_valid() const;
void pin();
const uint8* get() const;
protected:
friend class BufferStream;
Pointer(Slab* slab, const uint8* ptr);
private:
friend class Allocator;
Slab* get_slab() const;
union {
struct {
uintptr _ptr : 47;
uintptr _pinned : 1;
uintptr _slab_offset : 16;
};
uintptr _value = 0;
};
};
//------------------------------------------------------------------------------
class BufferRef
: public Pointer
{
private:
friend class Buffer;
BufferRef(Slab* slab, const uint8* ptr);
};
//------------------------------------------------------------------------------
class Allocator
: public NoCopy
, public NoMove
{
public:
~Allocator();
MutableBuffer create_buffer(uint32 size);
static Allocator& get_from(Buffer& buffer);
static Allocator& get_from(BufferRef& ref);
static Allocator& get_from(BufferStream& stream);
static Allocator& get_from(Pointer& pointer);
private:
friend Slab;
void free_slab(Slab* slab);
static Allocator& get_from(const Slab* slab);
Mutex _lock;
Slab* _slab = nullptr;
uint32 _slab_free = 0;
};
//------------------------------------------------------------------------------
class BufferStream
{
public:
BufferStream() = default;
bool has_data() const;
uint32 get_consumed() const;
uint32 get_remaining() const;
const uint8* read(uint32 size);
Buffer read_buf(uint32 size);
Pointer read_ptr(uint32 size);
template <typename T> T read();
private:
friend class Allocator;
friend class Buffer;
BufferStream(Slab* slab, const uint8* ptr, uint32 size);
Slab* get_slab() const;
const uint8* _ptr;
uint32 _slab_offset = 0;
uint32 _end = 0;
uint32 _cursor = 0;
uint32 _unused;
};
|