#endif
#if ((defined __cplusplus || (defined (__STDC__) && __STDC__) \
- || defined STDC_HEADERS || defined PROTOTYPES) \
- && ! defined (BROKEN_PROTOTYPES))
+ || defined STDC_HEADERS || defined PROTOTYPES))
#undef PP
#define PP(args) args
#undef __ptr_t
#define NULL 0
#endif
-#ifndef FREE_RETURN_TYPE
-#define FREE_RETURN_TYPE void
-#endif
-
/* Allocate SIZE bytes of memory. */
extern __ptr_t malloc PP ((__malloc_size_t __size));
/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
extern __ptr_t calloc PP ((__malloc_size_t __nmemb, __malloc_size_t __size));
/* Free a block allocated by `malloc', `realloc' or `calloc'. */
-extern FREE_RETURN_TYPE free PP ((__ptr_t __ptr));
+extern void free PP ((__ptr_t __ptr));
/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
-#if ! (defined (_MALLOC_INTERNAL) && __DJGPP__ - 0 == 1) /* Avoid conflict. */
+#if !defined (_MALLOC_INTERNAL) || defined (MSDOS) /* Avoid conflict. */
extern __ptr_t memalign PP ((__malloc_size_t __alignment,
__malloc_size_t __size));
+extern int posix_memalign PP ((__ptr_t *, __malloc_size_t,
+ __malloc_size_t size));
#endif
/* Allocate SIZE bytes on a page boundary. */
extern __ptr_t valloc PP ((__malloc_size_t __size));
#endif
+#ifdef USE_PTHREAD
+/* Set up mutexes and make malloc etc. thread-safe. */
+extern void malloc_enable_thread PP ((void));
+#endif
#ifdef _MALLOC_INTERNAL
#ifdef USE_PTHREAD
extern pthread_mutex_t _malloc_mutex, _aligned_blocks_mutex;
-#define LOCK() pthread_mutex_lock (&_malloc_mutex)
-#define UNLOCK() pthread_mutex_unlock (&_malloc_mutex)
-#define LOCK_ALIGNED_BLOCKS() pthread_mutex_lock (&_aligned_blocks_mutex)
-#define UNLOCK_ALIGNED_BLOCKS() pthread_mutex_unlock (&_aligned_blocks_mutex)
+extern int _malloc_thread_enabled_p;
+#define LOCK() \
+ do { \
+ if (_malloc_thread_enabled_p) \
+ pthread_mutex_lock (&_malloc_mutex); \
+ } while (0)
+#define UNLOCK() \
+ do { \
+ if (_malloc_thread_enabled_p) \
+ pthread_mutex_unlock (&_malloc_mutex); \
+ } while (0)
+#define LOCK_ALIGNED_BLOCKS() \
+ do { \
+ if (_malloc_thread_enabled_p) \
+ pthread_mutex_lock (&_aligned_blocks_mutex); \
+ } while (0)
+#define UNLOCK_ALIGNED_BLOCKS() \
+ do { \
+ if (_malloc_thread_enabled_p) \
+ pthread_mutex_unlock (&_aligned_blocks_mutex); \
+ } while (0)
#else
#define LOCK()
#define UNLOCK()
}
#ifdef USE_PTHREAD
-static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT;
pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t _aligned_blocks_mutex = PTHREAD_MUTEX_INITIALIZER;
+int _malloc_thread_enabled_p;
+
+static void
+malloc_atfork_handler_prepare ()
+{
+ LOCK ();
+ LOCK_ALIGNED_BLOCKS ();
+}
+
+static void
+malloc_atfork_handler_parent ()
+{
+ UNLOCK_ALIGNED_BLOCKS ();
+ UNLOCK ();
+}
+
+static void
+malloc_atfork_handler_child ()
+{
+ UNLOCK_ALIGNED_BLOCKS ();
+ UNLOCK ();
+}
+
+/* Set up mutexes and make malloc etc. thread-safe. */
+void
+malloc_enable_thread ()
+{
+ if (_malloc_thread_enabled_p)
+ return;
+
+ /* Some pthread implementations call malloc for statically
+ initialized mutexes when they are used first. To avoid such a
+ situation, we initialize mutexes here while their use is
+ disabled in malloc etc. */
+ pthread_mutex_init (&_malloc_mutex, NULL);
+ pthread_mutex_init (&_aligned_blocks_mutex, NULL);
+ pthread_atfork (malloc_atfork_handler_prepare,
+ malloc_atfork_handler_parent,
+ malloc_atfork_handler_child);
+ _malloc_thread_enabled_p = 1;
+}
#endif
static void
if (__malloc_initialize_hook)
(*__malloc_initialize_hook) ();
- /* We don't use recursive mutex because pthread_mutexattr_init may
- call malloc internally. */
-#if 0 /* defined (USE_PTHREAD) */
- {
- pthread_mutexattr_t attr;
-
- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init (&_malloc_mutex, &attr);
- pthread_mutexattr_destroy (&attr);
- }
-#endif
-
heapsize = HEAP / BLOCKSIZE;
_heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info));
if (_heapinfo == NULL)
return;
}
-/* Set everything up and remember that we have. */
+/* Set everything up and remember that we have.
+ main will call malloc which calls this function. That is before any threads
+ or signal handlers has been set up, so we don't need thread protection. */
int
__malloc_initialize ()
{
-#ifdef USE_PTHREAD
- pthread_once (&malloc_init_once_control, malloc_initialize_1);
-#else
if (__malloc_initialized)
return 0;
malloc_initialize_1 ();
-#endif
return __malloc_initialized;
}
if (size < sizeof (struct list))
size = sizeof (struct list);
-#ifdef SUNOS_LOCALTIME_BUG
- if (size < 16)
- size = 16;
-#endif
-
/* Determine the allocation policy based on the request size. */
if (size <= BLOCKSIZE / 2)
{
final free block; if so we don't need to get as much. */
if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
/* We can't do this if we will have to make the heap info
- table bigger to accomodate the new space. */
+ table bigger to accommodate the new space. */
block + wantblocks <= heapsize &&
get_contiguous_space ((wantblocks - lastblocks) * BLOCKSIZE,
ADDRESS (block + lastblocks)))
/* Cope with systems lacking `memmove'. */
#ifndef memmove
-#if (defined (MEMMOVE_MISSING) || \
- !defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
+#if (!defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
#ifdef emacs
#undef __malloc_safe_bcopy
#define __malloc_safe_bcopy safe_bcopy
/* Return memory to the heap. */
-FREE_RETURN_TYPE
+void
free (ptr)
__ptr_t ptr;
{
/* Cope with systems lacking `memmove'. */
-#if (defined (MEMMOVE_MISSING) || \
- !defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
+#if (!defined(_LIBC) && !defined(STDC_HEADERS) && !defined(USG))
#ifdef emacs
#undef __malloc_safe_bcopy
#include <malloc.h>
#endif
-#ifndef __GNU_LIBRARY__
+/* uClibc defines __GNU_LIBRARY__, but it is not completely
+ compatible. */
+#if !defined(__GNU_LIBRARY__) || defined(__UCLIBC__)
#define __sbrk sbrk
-#endif
-
-#ifdef __GNU_LIBRARY__
+#else /* __GNU_LIBRARY__ && ! defined (__UCLIBC__) */
/* It is best not to declare this and cast its result on foreign operating
systems with potentially hostile include files. */
#include <stddef.h>
extern __ptr_t __sbrk PP ((ptrdiff_t increment));
-#endif
+#endif /* __GNU_LIBRARY__ && ! defined (__UCLIBC__) */
#ifndef NULL
#define NULL 0
#include <malloc.h>
#endif
-#if __DJGPP__ - 0 == 1
-
-/* There is some problem with memalign in DJGPP v1 and we are supposed
- to omit it. Noone told me why, they just told me to do it. */
-
-#else
-
__ptr_t (*__memalign_hook) PP ((__malloc_size_t __size,
__malloc_size_t __alignment));
return result;
}
-#endif /* Not DJGPP v1 */
+#ifndef ENOMEM
+#define ENOMEM 12
+#endif
+
+#ifndef EINVAL
+#define EINVAL 22
+#endif
+
+int
+posix_memalign (memptr, alignment, size)
+ __ptr_t *memptr;
+ __malloc_size_t alignment;
+ __malloc_size_t size;
+{
+ __ptr_t mem;
+
+ if (alignment == 0
+ || alignment % sizeof (__ptr_t) != 0
+ || (alignment & (alignment - 1)) != 0)
+ return EINVAL;
+
+ mem = memalign (alignment, size);
+ if (mem == NULL)
+ return ENOMEM;
+
+ *memptr = mem;
+
+ return 0;
+}
+
/* Allocate memory on a page boundary.
Copyright (C) 1991, 92, 93, 94, 96 Free Software Foundation, Inc.
#endif
/* Old hook values. */
-static void (*old_free_hook) __P ((__ptr_t ptr));
-static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size));
-static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
+static void (*old_free_hook) (__ptr_t ptr);
+static __ptr_t (*old_malloc_hook) (__malloc_size_t size);
+static __ptr_t (*old_realloc_hook) (__ptr_t ptr, __malloc_size_t size);
/* Function to call when something awful happens. */
-static void (*abortfunc) __P ((enum mcheck_status));
+static void (*abortfunc) (enum mcheck_status);
/* Arbitrary magical numbers. */
#define MAGICWORD 0xfedabeeb
#if defined(_LIBC) || defined(STDC_HEADERS) || defined(USG)
#define flood memset
#else
-static void flood __P ((__ptr_t, int, __malloc_size_t));
+static void flood (__ptr_t, int, __malloc_size_t);
static void
flood (ptr, val, size)
__ptr_t ptr;
}
#endif
-static enum mcheck_status checkhdr __P ((const struct hdr *));
+static enum mcheck_status checkhdr (const struct hdr *);
static enum mcheck_status
checkhdr (hdr)
const struct hdr *hdr;
return status;
}
-static void freehook __P ((__ptr_t));
+static void freehook (__ptr_t);
static void
freehook (ptr)
__ptr_t ptr;
__free_hook = freehook;
}
-static __ptr_t mallochook __P ((__malloc_size_t));
+static __ptr_t mallochook (__malloc_size_t);
static __ptr_t
mallochook (size)
__malloc_size_t size;
return (__ptr_t) (hdr + 1);
}
-static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t));
+static __ptr_t reallochook (__ptr_t, __malloc_size_t);
static __ptr_t
reallochook (ptr, size)
__ptr_t ptr;
int
mcheck (func)
- void (*func) __P ((enum mcheck_status));
+ void (*func) (enum mcheck_status);
{
abortfunc = (func != NULL) ? func : &mabort;