* gc-card.c: rename usage of HAVE_ARRAYS to SCM_HAVE_ARRAYS.
[bpt/guile.git] / libguile / gc-malloc.c
CommitLineData
c7743d02
HWN
1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
41
42
43\f
44#include <stdio.h>
45#include <errno.h>
46#include <string.h>
47
48#ifdef __ia64__
49#include <ucontext.h>
50extern unsigned long * __libc_ia64_register_backing_store_base;
51#endif
52
53#include "libguile/_scm.h"
54#include "libguile/eval.h"
55#include "libguile/stime.h"
56#include "libguile/stackchk.h"
57#include "libguile/struct.h"
58#include "libguile/smob.h"
59#include "libguile/unif.h"
60#include "libguile/async.h"
61#include "libguile/ports.h"
62#include "libguile/root.h"
63#include "libguile/strings.h"
64#include "libguile/vectors.h"
65#include "libguile/weaks.h"
66#include "libguile/hashtab.h"
67#include "libguile/tags.h"
68
69#include "libguile/validate.h"
70#include "libguile/deprecation.h"
71#include "libguile/gc.h"
72
73#include "libguile/private-gc.h"
74
75#ifdef GUILE_DEBUG_MALLOC
76#include "libguile/debug-malloc.h"
77#endif
78
79#ifdef HAVE_MALLOC_H
80#include <malloc.h>
81#endif
82
83#ifdef HAVE_UNISTD_H
84#include <unistd.h>
85#endif
86
87/*
88 INIT_MALLOC_LIMIT is the initial amount of malloc usage which will
89 trigger a GC.
90
91 After startup (at the guile> prompt), we have approximately 100k of
92 alloced memory, which won't go away on GC. Let's set the init such
93 that we get a nice yield on the next allocation:
94*/
c2cbcc57 95#define SCM_DEFAULT_INIT_MALLOC_LIMIT 200*1024
c7743d02
HWN
96#define SCM_DEFAULT_MALLOC_MINYIELD 40
97
61ef9c1f 98/* #define DEBUGINFO */
c7743d02
HWN
99
100static int scm_i_minyield_malloc;
101
102void
103scm_gc_init_malloc (void)
104{
105 scm_mtrigger = scm_getenv_int ("GUILE_INIT_MALLOC_LIMIT",
106 SCM_DEFAULT_INIT_MALLOC_LIMIT);
107 scm_i_minyield_malloc = scm_getenv_int ("GUILE_MIN_YIELD_MALLOC",
108 SCM_DEFAULT_MALLOC_MINYIELD);
dac04e9f
HWN
109
110 if (scm_i_minyield_malloc >= 100)
111 scm_i_minyield_malloc = 99;
112 if (scm_i_minyield_malloc < 1)
113 scm_i_minyield_malloc = 1;
114
115 if (scm_mtrigger < 0)
116 scm_mtrigger = SCM_DEFAULT_INIT_MALLOC_LIMIT;
c7743d02
HWN
117}
118
119
120\f
121/* Function for non-cell memory management.
122 */
123
c7743d02
HWN
124void *
125scm_realloc (void *mem, size_t size)
126{
127 void *ptr;
128
129 SCM_SYSCALL (ptr = realloc (mem, size));
130 if (ptr)
131 return ptr;
132
fb50ef08 133 scm_rec_mutex_lock (&scm_i_sweep_mutex);
9bc4701c 134
c7743d02
HWN
135 scm_i_sweep_all_segments ("realloc");
136
137 SCM_SYSCALL (ptr = realloc (mem, size));
138 if (ptr)
9bc4701c 139 {
fb50ef08 140 scm_rec_mutex_unlock (&scm_i_sweep_mutex);
9bc4701c
MD
141 return ptr;
142 }
c7743d02
HWN
143
144 scm_igc ("realloc");
145 scm_i_sweep_all_segments ("realloc");
146
fb50ef08 147 scm_rec_mutex_unlock (&scm_i_sweep_mutex);
9bc4701c 148
c7743d02
HWN
149 SCM_SYSCALL (ptr = realloc (mem, size));
150 if (ptr)
151 return ptr;
152
153 scm_memory_error ("realloc");
154}
155
39e8f371
HWN
156void *
157scm_malloc (size_t sz)
158{
159 return scm_realloc (NULL, sz);
160}
ba1b2226
HWN
161
162/*
163 Hmm. Should we use the C convention for arguments (i.e. N_ELTS,
164 SIZEOF_ELT)? --hwn
165 */
166void *
167scm_calloc (size_t sz)
168{
1383773b
HWN
169 void * ptr;
170
171 /*
172 By default, try to use calloc, as it is likely more efficient than
173 calling memset by hand.
174 */
fb50ef08 175 SCM_SYSCALL (ptr = calloc (sz, 1));
1383773b
HWN
176 if (ptr)
177 return ptr;
178
179 ptr = scm_realloc (NULL, sz);
ba1b2226
HWN
180 memset (ptr, 0x0, sz);
181 return ptr;
182}
183
39e8f371 184
c7743d02
HWN
185char *
186scm_strndup (const char *str, size_t n)
187{
fb50ef08 188 char *dst = scm_malloc (n + 1);
c7743d02
HWN
189 memcpy (dst, str, n);
190 dst[n] = 0;
191 return dst;
192}
193
194char *
195scm_strdup (const char *str)
196{
197 return scm_strndup (str, strlen (str));
198}
199
200void
201scm_gc_register_collectable_memory (void *mem, size_t size, const char *what)
202{
203 scm_mallocated += size;
204
205 /*
206 we could finish the full sweep (without mark) here, but in
207 practice this turns out to be ineffective.
208 */
209
210 /*
211 A program that uses a lot of malloced collectable memory (vectors,
212 strings), will use a lot of memory off the cell-heap; it needs to
213 do GC more often (before cells are exhausted), otherwise swapping
214 and malloc management will tie it down.
215 */
216 if (scm_mallocated > scm_mtrigger)
217 {
9bc4701c 218 unsigned long prev_alloced;
c7743d02
HWN
219 float yield;
220
fb50ef08 221 scm_rec_mutex_lock (&scm_i_sweep_mutex);
9bc4701c
MD
222
223 prev_alloced = scm_mallocated;
c7743d02 224 scm_igc (what);
9bc4701c 225 scm_i_sweep_all_segments ("mtrigger");
c7743d02 226
fb50ef08
MD
227 yield = (((float) prev_alloced - (float) scm_mallocated)
228 / (float) prev_alloced);
ffd72400 229
c2cbcc57 230 scm_gc_malloc_yield_percentage = (int) (100 * yield);
61ef9c1f
HWN
231
232#ifdef DEBUGINFO
c7743d02 233 fprintf (stderr, "prev %lud , now %lud, yield %4.2lf, want %d",
fb50ef08
MD
234 prev_alloced,
235 scm_mallocated,
236 100.0 * yield,
237 scm_i_minyield_malloc);
61ef9c1f
HWN
238#endif
239
c7743d02
HWN
240 if (yield < scm_i_minyield_malloc / 100.0)
241 {
242 /*
243 We make the trigger a little larger, even; If you have a
244 program that builds up a lot of data in strings, then the
245 desired yield will never be satisfied.
246
247 Instead of getting bogged down, we let the mtrigger grow
248 strongly with it.
249 */
e88e4f2e 250 float no_overflow_trigger = scm_mallocated * 110.0;
dac04e9f 251
e88e4f2e 252 no_overflow_trigger /= (float) (100.0 - scm_i_minyield_malloc);
dac04e9f 253 scm_mtrigger = (unsigned long) no_overflow_trigger;
c7743d02 254
61ef9c1f 255#ifdef DEBUGINFO
fb50ef08
MD
256 fprintf (stderr, "Mtrigger sweep: ineffective. New trigger %d\n",
257 scm_mtrigger);
61ef9c1f 258#endif
c7743d02 259 }
9bc4701c 260
fb50ef08 261 scm_rec_mutex_unlock (&scm_i_sweep_mutex);
c7743d02
HWN
262 }
263
264#ifdef GUILE_DEBUG_MALLOC
265 if (mem)
266 scm_malloc_register (mem, what);
267#endif
268}
269
270void
271scm_gc_unregister_collectable_memory (void *mem, size_t size, const char *what)
272{
273 scm_mallocated -= size;
274 scm_gc_malloc_collected += size;
275
276#ifdef GUILE_DEBUG_MALLOC
277 if (mem)
278 scm_malloc_unregister (mem);
279#endif
280}
281
282void *
283scm_gc_malloc (size_t size, const char *what)
284{
285 /*
286 The straightforward implementation below has the problem
287 that it might call the GC twice, once in scm_malloc and then
288 again in scm_gc_register_collectable_memory. We don't really
289 want the second GC since it will not find new garbage.
290
291
292 Note: this is a theoretical peeve. In reality, malloc() never
293 returns NULL. Usually, memory is overcommitted, and when you try
294 to write it the program is killed with signal 11. --hwn
295 */
296
297 void *ptr = scm_malloc (size);
298 scm_gc_register_collectable_memory (ptr, size, what);
299 return ptr;
300}
301
39e8f371
HWN
302void *
303scm_gc_calloc (size_t size, const char *what)
304{
305 void *ptr = scm_gc_malloc (size, what);
306 memset (ptr, 0x0, size);
307 return ptr;
308}
309
310
c7743d02
HWN
311void *
312scm_gc_realloc (void *mem, size_t old_size, size_t new_size, const char *what)
313{
314 /* XXX - see scm_gc_malloc. */
315
316 void *ptr = scm_realloc (mem, new_size);
317 scm_gc_unregister_collectable_memory (mem, old_size, what);
318 scm_gc_register_collectable_memory (ptr, new_size, what);
319 return ptr;
320}
321
322void
323scm_gc_free (void *mem, size_t size, const char *what)
324{
325 scm_gc_unregister_collectable_memory (mem, size, what);
326 free (mem);
327}
328
329char *
330scm_gc_strndup (const char *str, size_t n, const char *what)
331{
332 char *dst = scm_gc_malloc (n+1, what);
333 memcpy (dst, str, n);
334 dst[n] = 0;
335 return dst;
336}
337
338char *
339scm_gc_strdup (const char *str, const char *what)
340{
341 return scm_gc_strndup (str, strlen (str), what);
342}
343
344#if SCM_ENABLE_DEPRECATED == 1
345
346/* {Deprecated front end to malloc}
347 *
348 * scm_must_malloc, scm_must_realloc, scm_must_free, scm_done_malloc,
349 * scm_done_free
350 *
351 * These functions provide services comparable to malloc, realloc, and
352 * free. They should be used when allocating memory that will be under
353 * control of the garbage collector, i.e., if the memory may be freed
354 * during garbage collection.
355 *
356 * They are deprecated because they weren't really used the way
357 * outlined above, and making sure to return the right amount from
358 * smob free routines was sometimes difficult when dealing with nested
359 * data structures. We basically want everybody to review their code
360 * and use the more symmetrical scm_gc_malloc/scm_gc_free functions
361 * instead. In some cases, where scm_must_malloc has been used
362 * incorrectly (i.e. for non-GC-able memory), use scm_malloc/free.
363 */
364
365void *
366scm_must_malloc (size_t size, const char *what)
367{
368 scm_c_issue_deprecation_warning
369 ("scm_must_malloc is deprecated. "
370 "Use scm_gc_malloc and scm_gc_free instead.");
371
372 return scm_gc_malloc (size, what);
373}
374
375void *
376scm_must_realloc (void *where,
377 size_t old_size,
378 size_t size,
379 const char *what)
380{
381 scm_c_issue_deprecation_warning
382 ("scm_must_realloc is deprecated. "
383 "Use scm_gc_realloc and scm_gc_free instead.");
384
385 return scm_gc_realloc (where, old_size, size, what);
386}
387
388char *
389scm_must_strndup (const char *str, size_t length)
390{
391 scm_c_issue_deprecation_warning
392 ("scm_must_strndup is deprecated. "
393 "Use scm_gc_strndup and scm_gc_free instead.");
394
395 return scm_gc_strndup (str, length, "string");
396}
397
398char *
399scm_must_strdup (const char *str)
400{
401 scm_c_issue_deprecation_warning
402 ("scm_must_strdup is deprecated. "
403 "Use scm_gc_strdup and scm_gc_free instead.");
404
405 return scm_gc_strdup (str, "string");
406}
407
408void
409scm_must_free (void *obj)
410#define FUNC_NAME "scm_must_free"
411{
412 scm_c_issue_deprecation_warning
413 ("scm_must_free is deprecated. "
414 "Use scm_gc_malloc and scm_gc_free instead.");
415
416#ifdef GUILE_DEBUG_MALLOC
417 scm_malloc_unregister (obj);
418#endif
419 if (obj)
420 free (obj);
421 else
be3ff021
HWN
422 {
423 fprintf (stderr,"freeing NULL pointer");
424 abort ();
425 }
c7743d02
HWN
426}
427#undef FUNC_NAME
428
429
430void
431scm_done_malloc (long size)
432{
433 scm_c_issue_deprecation_warning
434 ("scm_done_malloc is deprecated. "
435 "Use scm_gc_register_collectable_memory instead.");
436
437 scm_gc_register_collectable_memory (NULL, size, "foreign mallocs");
438}
439
440void
441scm_done_free (long size)
442{
443 scm_c_issue_deprecation_warning
444 ("scm_done_free is deprecated. "
445 "Use scm_gc_unregister_collectable_memory instead.");
446
447 scm_gc_unregister_collectable_memory (NULL, size, "foreign mallocs");
448}
449
450#endif /* SCM_ENABLE_DEPRECATED == 1 */