-#ifndef SYSTEM_MALLOC
-
-/* Arranging to disable input signals while we're in malloc.
-
- This only works with GNU malloc. To help out systems which can't
- use GNU malloc, all the calls to malloc, realloc, and free
- elsewhere in the code should be inside a BLOCK_INPUT/UNBLOCK_INPUT
- pair; unfortunately, we have no idea what C library functions
- might call malloc, so we can't really protect them unless you're
- using GNU malloc. Fortunately, most of the major operating systems
- can use GNU malloc. */
-
-#ifndef SYNC_INPUT
-/* When using SYNC_INPUT, we don't call malloc from a signal handler, so
- there's no need to block input around malloc. */
-
-#ifndef DOUG_LEA_MALLOC
-extern void * (*__malloc_hook) (size_t, const void *);
-extern void * (*__realloc_hook) (void *, size_t, const void *);
-extern void (*__free_hook) (void *, const void *);
-/* Else declared in malloc.h, perhaps with an extra arg. */
-#endif /* DOUG_LEA_MALLOC */
-static void * (*old_malloc_hook) (size_t, const void *);
-static void * (*old_realloc_hook) (void *, size_t, const void*);
-static void (*old_free_hook) (void*, const void*);
-
-#ifdef DOUG_LEA_MALLOC
-# define BYTES_USED (mallinfo ().uordblks)
-#else
-# define BYTES_USED _bytes_used
-#endif
-
-#ifdef GC_MALLOC_CHECK
-static bool dont_register_blocks;
-#endif
-
-static size_t bytes_used_when_reconsidered;
-
-/* Value of _bytes_used, when spare_memory was freed. */
-
-static size_t bytes_used_when_full;
-
-/* This function is used as the hook for free to call. */
-
-static void
-emacs_blocked_free (void *ptr, const void *ptr2)
-{
- BLOCK_INPUT_ALLOC;
-
-#ifdef GC_MALLOC_CHECK
- if (ptr)
- {
- struct mem_node *m;
-
- m = mem_find (ptr);
- if (m == MEM_NIL || m->start != ptr)
- {
- fprintf (stderr,
- "Freeing `%p' which wasn't allocated with malloc\n", ptr);
- emacs_abort ();
- }
- else
- {
- /* fprintf (stderr, "free %p...%p (%p)\n", m->start, m->end, ptr); */
- mem_delete (m);
- }
- }
-#endif /* GC_MALLOC_CHECK */
-
- __free_hook = old_free_hook;
- free (ptr);
-
- /* If we released our reserve (due to running out of memory),
- and we have a fair amount free once again,
- try to set aside another reserve in case we run out once more. */
- if (! NILP (Vmemory_full)
- /* Verify there is enough space that even with the malloc
- hysteresis this call won't run out again.
- The code here is correct as long as SPARE_MEMORY
- is substantially larger than the block size malloc uses. */
- && (bytes_used_when_full
- > ((bytes_used_when_reconsidered = BYTES_USED)
- + max (malloc_hysteresis, 4) * SPARE_MEMORY)))
- refill_memory_reserve ();
-
- __free_hook = emacs_blocked_free;
- UNBLOCK_INPUT_ALLOC;
-}
-
-
-/* This function is the malloc hook that Emacs uses. */
-
-static void *
-emacs_blocked_malloc (size_t size, const void *ptr)
-{
- void *value;
-
- BLOCK_INPUT_ALLOC;
- __malloc_hook = old_malloc_hook;
-#ifdef DOUG_LEA_MALLOC
- /* Segfaults on my system. --lorentey */
- /* mallopt (M_TOP_PAD, malloc_hysteresis * 4096); */
-#else
- __malloc_extra_blocks = malloc_hysteresis;
-#endif
-
- value = malloc (size);
-
-#ifdef GC_MALLOC_CHECK
- {
- struct mem_node *m = mem_find (value);
- if (m != MEM_NIL)
- {
- fprintf (stderr, "Malloc returned %p which is already in use\n",
- value);
- fprintf (stderr, "Region in use is %p...%p, %td bytes, type %d\n",
- m->start, m->end, (char *) m->end - (char *) m->start,
- m->type);
- emacs_abort ();
- }
-
- if (!dont_register_blocks)
- {
- mem_insert (value, (char *) value + max (1, size), allocated_mem_type);
- allocated_mem_type = MEM_TYPE_NON_LISP;
- }
- }
-#endif /* GC_MALLOC_CHECK */
-
- __malloc_hook = emacs_blocked_malloc;
- UNBLOCK_INPUT_ALLOC;
-
- /* fprintf (stderr, "%p malloc\n", value); */
- return value;
-}
-
-
-/* This function is the realloc hook that Emacs uses. */
-
-static void *
-emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2)
-{
- void *value;
-
- BLOCK_INPUT_ALLOC;
- __realloc_hook = old_realloc_hook;
-
-#ifdef GC_MALLOC_CHECK
- if (ptr)
- {
- struct mem_node *m = mem_find (ptr);
- if (m == MEM_NIL || m->start != ptr)
- {
- fprintf (stderr,
- "Realloc of %p which wasn't allocated with malloc\n",
- ptr);
- emacs_abort ();
- }
-
- mem_delete (m);
- }
-
- /* fprintf (stderr, "%p -> realloc\n", ptr); */
-
- /* Prevent malloc from registering blocks. */
- dont_register_blocks = 1;
-#endif /* GC_MALLOC_CHECK */
-
- value = realloc (ptr, size);
-
-#ifdef GC_MALLOC_CHECK
- dont_register_blocks = 0;
-
- {
- struct mem_node *m = mem_find (value);
- if (m != MEM_NIL)
- {
- fprintf (stderr, "Realloc returns memory that is already in use\n");
- emacs_abort ();
- }
-
- /* Can't handle zero size regions in the red-black tree. */
- mem_insert (value, (char *) value + max (size, 1), MEM_TYPE_NON_LISP);
- }
-
- /* fprintf (stderr, "%p <- realloc\n", value); */
-#endif /* GC_MALLOC_CHECK */
-
- __realloc_hook = emacs_blocked_realloc;
- UNBLOCK_INPUT_ALLOC;
-
- return value;
-}
-
-
-#ifdef HAVE_PTHREAD
-/* Called from Fdump_emacs so that when the dumped Emacs starts, it has a
- normal malloc. Some thread implementations need this as they call
- malloc before main. The pthread_self call in BLOCK_INPUT_ALLOC then
- calls malloc because it is the first call, and we have an endless loop. */
-
-void
-reset_malloc_hooks (void)
-{
- __free_hook = old_free_hook;
- __malloc_hook = old_malloc_hook;
- __realloc_hook = old_realloc_hook;
-}
-#endif /* HAVE_PTHREAD */
-
-
-/* Called from main to set up malloc to use our hooks. */
-
-void
-uninterrupt_malloc (void)
-{
-#ifdef HAVE_PTHREAD
-#ifdef DOUG_LEA_MALLOC
- pthread_mutexattr_t attr;
-
- /* GLIBC has a faster way to do this, but let's keep it portable.
- This is according to the Single UNIX Specification. */
- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init (&alloc_mutex, &attr);
-#else /* !DOUG_LEA_MALLOC */
- /* Some systems such as Solaris 2.6 don't have a recursive mutex,
- and the bundled gmalloc.c doesn't require it. */
- pthread_mutex_init (&alloc_mutex, NULL);
-#endif /* !DOUG_LEA_MALLOC */
-#endif /* HAVE_PTHREAD */
-
- if (__free_hook != emacs_blocked_free)
- old_free_hook = __free_hook;
- __free_hook = emacs_blocked_free;
-
- if (__malloc_hook != emacs_blocked_malloc)
- old_malloc_hook = __malloc_hook;
- __malloc_hook = emacs_blocked_malloc;
-
- if (__realloc_hook != emacs_blocked_realloc)
- old_realloc_hook = __realloc_hook;
- __realloc_hook = emacs_blocked_realloc;
-}
-
-#endif /* not SYNC_INPUT */
-#endif /* not SYSTEM_MALLOC */
-
-
-\f