source: EcnlProtoTool/trunk/mruby-1.3.0/src/pool.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 3.7 KB
Line 
1/*
2** pool.c - memory pool
3**
4** See Copyright Notice in mruby.h
5*/
6
7#include <stddef.h>
8#include <stdint.h>
9#include <string.h>
10#include <mruby.h>
11
12/* configuration section */
13/* allocated memory address should be multiple of POOL_ALIGNMENT */
14/* or undef it if alignment does not matter */
15#ifndef POOL_ALIGNMENT
16#if INTPTR_MAX == INT64_MAX
17#define POOL_ALIGNMENT 8
18#else
19#define POOL_ALIGNMENT 4
20#endif
21#endif
22/* page size of memory pool */
23#ifndef POOL_PAGE_SIZE
24#define POOL_PAGE_SIZE 16000
25#endif
26/* end of configuration section */
27
28struct mrb_pool_page {
29 struct mrb_pool_page *next;
30 size_t offset;
31 size_t len;
32 void *last;
33 char page[];
34};
35
36struct mrb_pool {
37 mrb_state *mrb;
38 struct mrb_pool_page *pages;
39};
40
41#undef TEST_POOL
42#ifdef TEST_POOL
43
44#define mrb_malloc_simple(m,s) malloc(s)
45#define mrb_free(m,p) free(p)
46#endif
47
48#ifdef POOL_ALIGNMENT
49# define ALIGN_PADDING(x) ((SIZE_MAX - (x) + 1) & (POOL_ALIGNMENT - 1))
50#else
51# define ALIGN_PADDING(x) (0)
52#endif
53
54MRB_API mrb_pool*
55mrb_pool_open(mrb_state *mrb)
56{
57 mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool));
58
59 if (pool) {
60 pool->mrb = mrb;
61 pool->pages = NULL;
62 }
63
64 return pool;
65}
66
67MRB_API void
68mrb_pool_close(mrb_pool *pool)
69{
70 struct mrb_pool_page *page, *tmp;
71
72 if (!pool) return;
73 page = pool->pages;
74 while (page) {
75 tmp = page;
76 page = page->next;
77 mrb_free(pool->mrb, tmp);
78 }
79 mrb_free(pool->mrb, pool);
80}
81
82static struct mrb_pool_page*
83page_alloc(mrb_pool *pool, size_t len)
84{
85 struct mrb_pool_page *page;
86
87 if (len < POOL_PAGE_SIZE)
88 len = POOL_PAGE_SIZE;
89 page = (struct mrb_pool_page *)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len);
90 if (page) {
91 page->offset = 0;
92 page->len = len;
93 }
94
95 return page;
96}
97
98MRB_API void*
99mrb_pool_alloc(mrb_pool *pool, size_t len)
100{
101 struct mrb_pool_page *page;
102 size_t n;
103
104 if (!pool) return NULL;
105 len += ALIGN_PADDING(len);
106 page = pool->pages;
107 while (page) {
108 if (page->offset + len <= page->len) {
109 n = page->offset;
110 page->offset += len;
111 page->last = (char*)page->page+n;
112 return page->last;
113 }
114 page = page->next;
115 }
116 page = page_alloc(pool, len);
117 if (!page) return NULL;
118 page->offset = len;
119 page->next = pool->pages;
120 pool->pages = page;
121
122 page->last = (void*)page->page;
123 return page->last;
124}
125
126MRB_API mrb_bool
127mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len)
128{
129 struct mrb_pool_page *page;
130
131 if (!pool) return FALSE;
132 len += ALIGN_PADDING(len);
133 page = pool->pages;
134 while (page) {
135 if (page->last == p) {
136 size_t beg;
137
138 beg = (char*)p - page->page;
139 if (beg + len > page->len) return FALSE;
140 return TRUE;
141 }
142 page = page->next;
143 }
144 return FALSE;
145}
146
147MRB_API void*
148mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen)
149{
150 struct mrb_pool_page *page;
151 void *np;
152
153 if (!pool) return NULL;
154 oldlen += ALIGN_PADDING(oldlen);
155 newlen += ALIGN_PADDING(newlen);
156 page = pool->pages;
157 while (page) {
158 if (page->last == p) {
159 size_t beg;
160
161 beg = (char*)p - page->page;
162 if (beg + oldlen != page->offset) break;
163 if (beg + newlen > page->len) {
164 page->offset = beg;
165 break;
166 }
167 page->offset = beg + newlen;
168 return p;
169 }
170 page = page->next;
171 }
172 np = mrb_pool_alloc(pool, newlen);
173 if (np == NULL) {
174 return NULL;
175 }
176 memcpy(np, p, oldlen);
177 return np;
178}
179
180#ifdef TEST_POOL
181int
182main(void)
183{
184 int i, len = 250;
185 mrb_pool *pool;
186 void *p;
187
188 pool = mrb_pool_open(NULL);
189 p = mrb_pool_alloc(pool, len);
190 for (i=1; i<20; i++) {
191 printf("%p (len=%d) %ud\n", p, len, mrb_pool_can_realloc(pool, p, len*2));
192 p = mrb_pool_realloc(pool, p, len, len*2);
193 len *= 2;
194 }
195 mrb_pool_close(pool);
196 return 0;
197}
198#endif
Note: See TracBrowser for help on using the repository browser.