forked from msgpack/msgpack-ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrmem.c
More file actions
93 lines (80 loc) · 2.73 KB
/
rmem.c
File metadata and controls
93 lines (80 loc) · 2.73 KB
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
/*
* MessagePack for Ruby
*
* Copyright (C) 2008-2013 Sadayuki Furuhashi
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "rmem.h"
void msgpack_rmem_init(msgpack_rmem_t* pm)
{
memset(pm, 0, sizeof(msgpack_rmem_t));
pm->head.pages = xmalloc(MSGPACK_RMEM_PAGE_SIZE * 32);
pm->head.mask = 0xffffffff; /* all bit is 1 = available */
}
void msgpack_rmem_destroy(msgpack_rmem_t* pm)
{
msgpack_rmem_chunk_t* c = pm->array_first;
msgpack_rmem_chunk_t* cend = pm->array_last;
for(; c != cend; c++) {
xfree(c->pages);
}
xfree(pm->head.pages);
xfree(pm->array_first);
}
void* _msgpack_rmem_alloc2(msgpack_rmem_t* pm)
{
msgpack_rmem_chunk_t* c = pm->array_first;
msgpack_rmem_chunk_t* last = pm->array_last;
for(; c != last; c++) {
if(_msgpack_rmem_chunk_available(c)) {
void* mem = _msgpack_rmem_chunk_alloc(c);
/* move to head */
msgpack_rmem_chunk_t tmp = pm->head;
pm->head = *c;
*c = tmp;
return mem;
}
}
if(c == pm->array_end) {
size_t capacity = c - pm->array_first;
size_t length = last - pm->array_first;
capacity = (capacity == 0) ? 8 : capacity * 2;
msgpack_rmem_chunk_t* array = xrealloc(pm->array_first, capacity * sizeof(msgpack_rmem_chunk_t));
pm->array_first = array;
pm->array_last = array + length;
pm->array_end = array + capacity;
}
/* allocate new chunk */
c = pm->array_last++;
/* move head to array */
*c = pm->head;
pm->head.pages = NULL; /* make sure we don't point to another chunk's pages in case xmalloc triggers GC */
pm->head.mask = 0xffffffff & (~1); /* "& (~1)" means first chunk is already allocated */
pm->head.pages = xmalloc(MSGPACK_RMEM_PAGE_SIZE * 32);
return pm->head.pages;
}
void _msgpack_rmem_chunk_free(msgpack_rmem_t* pm, msgpack_rmem_chunk_t* c)
{
if(pm->array_first->mask == 0xffffffff) {
/* free and move to last */
pm->array_last--;
xfree(c->pages);
*c = *pm->array_last;
return;
}
/* move to first */
msgpack_rmem_chunk_t tmp = *pm->array_first;
*pm->array_first = *c;
*c = tmp;
}