* threads.c (create_thread): Clear parent field in root state in
[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
9bc4701c
MD
133 scm_i_thread_put_to_sleep ();
134
c7743d02
HWN
135 scm_i_sweep_all_segments ("realloc");
136
137 SCM_SYSCALL (ptr = realloc (mem, size));
138 if (ptr)
9bc4701c
MD
139 {
140 scm_i_thread_wake_up ();
141 return ptr;
142 }
c7743d02
HWN
143
144 scm_igc ("realloc");
145 scm_i_sweep_all_segments ("realloc");
146
9bc4701c
MD
147 scm_i_thread_wake_up ();
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 */
175 SCM_SYSCALL(ptr= calloc (sz, 1));
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{
188 char *dst = scm_malloc (n+1);
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
9bc4701c
MD
221 scm_i_thread_put_to_sleep ();
222
223 prev_alloced = scm_mallocated;
c7743d02 224 scm_igc (what);
9bc4701c 225 scm_i_sweep_all_segments ("mtrigger");
c7743d02 226
ffd72400
HWN
227 yield = ((float)prev_alloced - (float) scm_mallocated)
228 / (float) prev_alloced;
229
c2cbcc57 230 scm_gc_malloc_yield_percentage = (int) (100 * yield);
61ef9c1f
HWN
231
232#ifdef DEBUGINFO
c7743d02
HWN
233 fprintf (stderr, "prev %lud , now %lud, yield %4.2lf, want %d",
234 prev_alloced, scm_mallocated, 100.0*yield, scm_i_minyield_malloc);
61ef9c1f
HWN
235#endif
236
c7743d02
HWN
237 if (yield < scm_i_minyield_malloc / 100.0)
238 {
239 /*
240 We make the trigger a little larger, even; If you have a
241 program that builds up a lot of data in strings, then the
242 desired yield will never be satisfied.
243
244 Instead of getting bogged down, we let the mtrigger grow
245 strongly with it.
246 */
e88e4f2e 247 float no_overflow_trigger = scm_mallocated * 110.0;
dac04e9f 248
e88e4f2e 249 no_overflow_trigger /= (float) (100.0 - scm_i_minyield_malloc);
dac04e9f 250 scm_mtrigger = (unsigned long) no_overflow_trigger;
c7743d02 251
61ef9c1f 252#ifdef DEBUGINFO
c7743d02 253 fprintf (stderr, "Mtrigger sweep: ineffective. New trigger %d\n", scm_mtrigger);
61ef9c1f 254#endif
c7743d02 255 }
9bc4701c
MD
256
257 scm_i_thread_wake_up ();
c7743d02
HWN
258 }
259
260#ifdef GUILE_DEBUG_MALLOC
261 if (mem)
262 scm_malloc_register (mem, what);
263#endif
264}
265
266void
267scm_gc_unregister_collectable_memory (void *mem, size_t size, const char *what)
268{
269 scm_mallocated -= size;
270 scm_gc_malloc_collected += size;
271
272#ifdef GUILE_DEBUG_MALLOC
273 if (mem)
274 scm_malloc_unregister (mem);
275#endif
276}
277
278void *
279scm_gc_malloc (size_t size, const char *what)
280{
281 /*
282 The straightforward implementation below has the problem
283 that it might call the GC twice, once in scm_malloc and then
284 again in scm_gc_register_collectable_memory. We don't really
285 want the second GC since it will not find new garbage.
286
287
288 Note: this is a theoretical peeve. In reality, malloc() never
289 returns NULL. Usually, memory is overcommitted, and when you try
290 to write it the program is killed with signal 11. --hwn
291 */
292
293 void *ptr = scm_malloc (size);
294 scm_gc_register_collectable_memory (ptr, size, what);
295 return ptr;
296}
297
39e8f371
HWN
298void *
299scm_gc_calloc (size_t size, const char *what)
300{
301 void *ptr = scm_gc_malloc (size, what);
302 memset (ptr, 0x0, size);
303 return ptr;
304}
305
306
c7743d02
HWN
307void *
308scm_gc_realloc (void *mem, size_t old_size, size_t new_size, const char *what)
309{
310 /* XXX - see scm_gc_malloc. */
311
312 void *ptr = scm_realloc (mem, new_size);
313 scm_gc_unregister_collectable_memory (mem, old_size, what);
314 scm_gc_register_collectable_memory (ptr, new_size, what);
315 return ptr;
316}
317
318void
319scm_gc_free (void *mem, size_t size, const char *what)
320{
321 scm_gc_unregister_collectable_memory (mem, size, what);
322 free (mem);
323}
324
325char *
326scm_gc_strndup (const char *str, size_t n, const char *what)
327{
328 char *dst = scm_gc_malloc (n+1, what);
329 memcpy (dst, str, n);
330 dst[n] = 0;
331 return dst;
332}
333
334char *
335scm_gc_strdup (const char *str, const char *what)
336{
337 return scm_gc_strndup (str, strlen (str), what);
338}
339
340#if SCM_ENABLE_DEPRECATED == 1
341
342/* {Deprecated front end to malloc}
343 *
344 * scm_must_malloc, scm_must_realloc, scm_must_free, scm_done_malloc,
345 * scm_done_free
346 *
347 * These functions provide services comparable to malloc, realloc, and
348 * free. They should be used when allocating memory that will be under
349 * control of the garbage collector, i.e., if the memory may be freed
350 * during garbage collection.
351 *
352 * They are deprecated because they weren't really used the way
353 * outlined above, and making sure to return the right amount from
354 * smob free routines was sometimes difficult when dealing with nested
355 * data structures. We basically want everybody to review their code
356 * and use the more symmetrical scm_gc_malloc/scm_gc_free functions
357 * instead. In some cases, where scm_must_malloc has been used
358 * incorrectly (i.e. for non-GC-able memory), use scm_malloc/free.
359 */
360
361void *
362scm_must_malloc (size_t size, const char *what)
363{
364 scm_c_issue_deprecation_warning
365 ("scm_must_malloc is deprecated. "
366 "Use scm_gc_malloc and scm_gc_free instead.");
367
368 return scm_gc_malloc (size, what);
369}
370
371void *
372scm_must_realloc (void *where,
373 size_t old_size,
374 size_t size,
375 const char *what)
376{
377 scm_c_issue_deprecation_warning
378 ("scm_must_realloc is deprecated. "
379 "Use scm_gc_realloc and scm_gc_free instead.");
380
381 return scm_gc_realloc (where, old_size, size, what);
382}
383
384char *
385scm_must_strndup (const char *str, size_t length)
386{
387 scm_c_issue_deprecation_warning
388 ("scm_must_strndup is deprecated. "
389 "Use scm_gc_strndup and scm_gc_free instead.");
390
391 return scm_gc_strndup (str, length, "string");
392}
393
394char *
395scm_must_strdup (const char *str)
396{
397 scm_c_issue_deprecation_warning
398 ("scm_must_strdup is deprecated. "
399 "Use scm_gc_strdup and scm_gc_free instead.");
400
401 return scm_gc_strdup (str, "string");
402}
403
404void
405scm_must_free (void *obj)
406#define FUNC_NAME "scm_must_free"
407{
408 scm_c_issue_deprecation_warning
409 ("scm_must_free is deprecated. "
410 "Use scm_gc_malloc and scm_gc_free instead.");
411
412#ifdef GUILE_DEBUG_MALLOC
413 scm_malloc_unregister (obj);
414#endif
415 if (obj)
416 free (obj);
417 else
be3ff021
HWN
418 {
419 fprintf (stderr,"freeing NULL pointer");
420 abort ();
421 }
c7743d02
HWN
422}
423#undef FUNC_NAME
424
425
426void
427scm_done_malloc (long size)
428{
429 scm_c_issue_deprecation_warning
430 ("scm_done_malloc is deprecated. "
431 "Use scm_gc_register_collectable_memory instead.");
432
433 scm_gc_register_collectable_memory (NULL, size, "foreign mallocs");
434}
435
436void
437scm_done_free (long size)
438{
439 scm_c_issue_deprecation_warning
440 ("scm_done_free is deprecated. "
441 "Use scm_gc_unregister_collectable_memory instead.");
442
443 scm_gc_unregister_collectable_memory (NULL, size, "foreign mallocs");
444}
445
446#endif /* SCM_ENABLE_DEPRECATED == 1 */