~ubuntu-branches/ubuntu/hardy/sigscheme/hardy-proposed

« back to all changes in this revision

Viewing changes to src/alloc.c

  • Committer: Bazaar Package Importer
  • Author(s): NIIBE Yutaka
  • Date: 2006-05-23 21:46:41 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060523214641-6ix4gz34wpiehub8
Tags: 0.5.0-2
* debian/control (Build-Depends): Added ruby.
  Thanks to Frederik Schueler.  Closes: #368571
* debian/rules (clean): invoke 'distclean' instead of 'clean'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*===========================================================================
 
2
 *  FileName : alloc.c
 
3
 *  About    : memory allocators
 
4
 *
 
5
 *  Copyright (C) 2005-2006 Kazuki Ohta <mover AT hct.zaq.ne.jp>
 
6
 *
 
7
 *  All rights reserved.
 
8
 *
 
9
 *  Redistribution and use in source and binary forms, with or without
 
10
 *  modification, are permitted provided that the following conditions
 
11
 *  are met:
 
12
 *
 
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.
 
21
 *
 
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
===========================================================================*/
 
34
 
 
35
#include "config.h"
 
36
#include "config-nonstd-string.h"
 
37
 
 
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
 
42
#endif
 
43
 
 
44
/*=======================================
 
45
  System Include
 
46
=======================================*/
 
47
#include <stdlib.h>
 
48
#include <string.h>
 
49
#if HAVE_GETPAGESIZE
 
50
#include <unistd.h>
 
51
#endif
 
52
 
 
53
/*=======================================
 
54
  Local Include
 
55
=======================================*/
 
56
#include "my-stdint.h"
 
57
#include "sigscheme.h"
 
58
#include "sigschemeinternal.h"
 
59
 
 
60
/*=======================================
 
61
  File Local Macro Definitions
 
62
=======================================*/
 
63
#define ALIGN_CELL (sizeof(ScmCell))
 
64
 
 
65
/*=======================================
 
66
  File Local Type Definitions
 
67
=======================================*/
 
68
 
 
69
/*=======================================
 
70
  Variable Declarations
 
71
=======================================*/
 
72
 
 
73
/*=======================================
 
74
  File Local Function Declarations
 
75
=======================================*/
 
76
 
 
77
/*=======================================
 
78
  Function Implementations
 
79
=======================================*/
 
80
void *
 
81
scm_malloc_aligned(size_t size)
 
82
{
 
83
    void *p;
 
84
 
 
85
#if HAVE_POSIX_MEMALIGN
 
86
    /*
 
87
     * Cited from manpage of posix_memalign(3) of glibc:
 
88
     *
 
89
     * CONFORMING TO
 
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.
 
94
     */
 
95
    posix_memalign(&p, ALIGN_CELL, size);
 
96
#elif (HAVE_PAGE_ALIGNED_MALLOC && HAVE_GETPAGESIZE)
 
97
    if ((size_t)getpagesize() <= size || size <= sizeof(void *))
 
98
        p = scm_malloc(size);
 
99
    else
 
100
        PLAIN_ERR("cannot ensure memory alignment");
 
101
#elif defined(__APPLE__)
 
102
    /*
 
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
 
107
     * -- 
 
108
     * ekato Jan 23 2006
 
109
     */
 
110
    if ((ALIGN_CELL % 16 == 0) || (ALIGN_CELL % 8 == 0)
 
111
        || (ALIGN_CELL % 4 == 0) || (ALIGN_CELL % 2 == 0))
 
112
        p = malloc(size);
 
113
    else
 
114
        PLAIN_ERR("cannot ensure memory alignment");
 
115
#else
 
116
#error "This platform is not supported yet"
 
117
#endif
 
118
    SCM_ENSURE_ALLOCATED(p);
 
119
    /* heaps must be aligned to sizeof(ScmCell) */
 
120
    SCM_ASSERT(!((uintptr_t)p % ALIGN_CELL));
 
121
 
 
122
    return p;
 
123
}
 
124
 
 
125
void *
 
126
scm_malloc(size_t size)
 
127
{
 
128
    void *p;
 
129
 
 
130
    p = malloc(size);
 
131
    ENSURE_ALLOCATED(p);
 
132
 
 
133
    return p;
 
134
}
 
135
 
 
136
void *
 
137
scm_calloc(size_t number, size_t size)
 
138
{
 
139
    void *p;
 
140
 
 
141
    p = calloc(number, size);
 
142
    ENSURE_ALLOCATED(p);
 
143
 
 
144
    return p;
 
145
}
 
146
 
 
147
void *
 
148
scm_realloc(void *ptr, size_t size)
 
149
{
 
150
    void *p;
 
151
 
 
152
    p = realloc(ptr, size);
 
153
    ENSURE_ALLOCATED(p);
 
154
 
 
155
    return p;
 
156
}
 
157
 
 
158
char *
 
159
scm_strdup(const char *str)
 
160
{
 
161
    char *copied;
 
162
 
 
163
#if HAVE_STRDUP
 
164
    copied = strdup(str);
 
165
    ENSURE_ALLOCATED(copied);
 
166
#else
 
167
    size_t size;
 
168
 
 
169
    size = strlen(str) + sizeof("");
 
170
    copied = scm_malloc(size);
 
171
    strcpy(copied, str);
 
172
#endif
 
173
 
 
174
    return copied;
 
175
}
 
176
 
 
177
/*=======================================
 
178
   Extendable Local Buffer
 
179
=======================================*/
 
180
void
 
181
scm_lbuf_init(struct ScmLBuf_void_ *lbuf, void *init_buf, size_t init_size)
 
182
{
 
183
    lbuf->buf  = lbuf->init_buf  = init_buf;
 
184
    lbuf->size = lbuf->init_size = init_size;
 
185
    lbuf->extended_cnt = 0;
 
186
}
 
187
 
 
188
void
 
189
scm_lbuf_free(struct ScmLBuf_void_ *lbuf)
 
190
{
 
191
    if (lbuf->buf != lbuf->init_buf)
 
192
        free(lbuf->buf);
 
193
}
 
194
 
 
195
void
 
196
scm_lbuf_alloc(struct ScmLBuf_void_ *lbuf, size_t size)
 
197
{
 
198
    lbuf->buf = scm_malloc(size);
 
199
    lbuf->size = size;
 
200
}
 
201
 
 
202
void
 
203
scm_lbuf_realloc(struct ScmLBuf_void_ *lbuf, size_t size)
 
204
{
 
205
    if (lbuf->buf == lbuf->init_buf) {
 
206
        if (size < lbuf->size)
 
207
            lbuf->size = size;
 
208
        lbuf->buf = memcpy(scm_malloc(size), lbuf->buf, lbuf->size);
 
209
    } else {
 
210
        lbuf->buf = scm_realloc(lbuf->buf, size);
 
211
    }
 
212
    lbuf->size = size;
 
213
}
 
214
 
 
215
void
 
216
scm_lbuf_extend(struct ScmLBuf_void_ *lbuf,
 
217
                size_t (*f)(struct ScmLBuf_void_ *), size_t least_size)
 
218
{
 
219
    size_t new_size;
 
220
 
 
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++;
 
229
    }
 
230
}
 
231
 
 
232
size_t
 
233
scm_lbuf_f_linear(struct ScmLBuf_void_ *lbuf)
 
234
{
 
235
    return (lbuf->size + lbuf->init_size);
 
236
}
 
237
 
 
238
size_t
 
239
scm_lbuf_f_exponential(struct ScmLBuf_void_ *lbuf)
 
240
{
 
241
    return (lbuf->size << 1);
 
242
}