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