1
/*===========================================================================
3
* About : memory allocators
5
* Copyright (C) 2005-2006 Kazuki Ohta <mover AT hct.zaq.ne.jp>
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. Neither the name of authors nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
22
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
23
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
26
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
===========================================================================*/
36
#include "config-nonstd-string.h"
38
#if HAVE_POSIX_MEMALIGN
39
/* For posix_memalign(3). although this value is overridden by _GNU_SOURCE on
40
* glibc, keep this for other environments. */
41
#define _POSIX_C_SOURCE 200112L
44
/*=======================================
46
=======================================*/
53
/*=======================================
55
=======================================*/
56
#include "my-stdint.h"
57
#include "sigscheme.h"
58
#include "sigschemeinternal.h"
60
/*=======================================
61
File Local Macro Definitions
62
=======================================*/
63
#define ALIGN_CELL (sizeof(ScmCell))
65
/*=======================================
66
File Local Type Definitions
67
=======================================*/
69
/*=======================================
71
=======================================*/
73
/*=======================================
74
File Local Function Declarations
75
=======================================*/
77
/*=======================================
78
Function Implementations
79
=======================================*/
81
scm_malloc_aligned(size_t size)
85
#if HAVE_POSIX_MEMALIGN
87
* Cited from manpage of posix_memalign(3) of glibc:
90
* The function valloc() appeared in 3.0 BSD. It is documented as being
91
* obsolete in BSD 4.3, and as legacy in SUSv2. It no longer occurs in
92
* SUSv3. The function memalign() appears in SunOS 4.1.3 but not in
93
* BSD 4.4. The function posix_memalign() comes from POSIX 1003.1d.
95
posix_memalign(&p, ALIGN_CELL, size);
96
#elif (HAVE_PAGE_ALIGNED_MALLOC && HAVE_GETPAGESIZE)
97
if ((size_t)getpagesize() <= size || size <= sizeof(void *))
100
PLAIN_ERR("cannot ensure memory alignment");
101
#elif defined(__APPLE__)
103
* malloc in Mac OS X guarantees 16 byte alignment. And large
104
* memory allocations are guaranteed to be page-aligned. See
105
* http://developer.apple.com/documentation/Performance/Conceptual/
106
* ManagingMemory/Articles/MemoryAlloc.html
110
if ((ALIGN_CELL % 16 == 0) || (ALIGN_CELL % 8 == 0)
111
|| (ALIGN_CELL % 4 == 0) || (ALIGN_CELL % 2 == 0))
114
PLAIN_ERR("cannot ensure memory alignment");
116
#error "This platform is not supported yet"
118
SCM_ENSURE_ALLOCATED(p);
119
/* heaps must be aligned to sizeof(ScmCell) */
120
SCM_ASSERT(!((uintptr_t)p % ALIGN_CELL));
126
scm_malloc(size_t size)
137
scm_calloc(size_t number, size_t size)
141
p = calloc(number, size);
148
scm_realloc(void *ptr, size_t size)
152
p = realloc(ptr, size);
159
scm_strdup(const char *str)
164
copied = strdup(str);
165
ENSURE_ALLOCATED(copied);
169
size = strlen(str) + sizeof("");
170
copied = scm_malloc(size);
177
/*=======================================
178
Extendable Local Buffer
179
=======================================*/
181
scm_lbuf_init(struct ScmLBuf_void_ *lbuf, void *init_buf, size_t init_size)
183
lbuf->buf = lbuf->init_buf = init_buf;
184
lbuf->size = lbuf->init_size = init_size;
185
lbuf->extended_cnt = 0;
189
scm_lbuf_free(struct ScmLBuf_void_ *lbuf)
191
if (lbuf->buf != lbuf->init_buf)
196
scm_lbuf_alloc(struct ScmLBuf_void_ *lbuf, size_t size)
198
lbuf->buf = scm_malloc(size);
203
scm_lbuf_realloc(struct ScmLBuf_void_ *lbuf, size_t size)
205
if (lbuf->buf == lbuf->init_buf) {
206
if (size < lbuf->size)
208
lbuf->buf = memcpy(scm_malloc(size), lbuf->buf, lbuf->size);
210
lbuf->buf = scm_realloc(lbuf->buf, size);
216
scm_lbuf_extend(struct ScmLBuf_void_ *lbuf,
217
size_t (*f)(struct ScmLBuf_void_ *), size_t least_size)
221
if (lbuf->size < least_size) {
222
new_size = (*f)(lbuf);
223
if (new_size < lbuf->size)
224
PLAIN_ERR("local buffer exceeded");
225
if (new_size < least_size)
226
new_size = least_size;
227
scm_lbuf_realloc(lbuf, new_size);
228
lbuf->extended_cnt++;
233
scm_lbuf_f_linear(struct ScmLBuf_void_ *lbuf)
235
return (lbuf->size + lbuf->init_size);
239
scm_lbuf_f_exponential(struct ScmLBuf_void_ *lbuf)
241
return (lbuf->size << 1);