/* The malloc headers and source files from the C library follow here. */
/* Declarations for `malloc' and friends.
- Copyright 1990, 91, 92, 93, 95, 96, 99 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1992, 1993, 1995, 1996, 1999, 2002, 2003, 2004,
+ 2005, 2006, 2007 Free Software Foundation, Inc.
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
+modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
+General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public
+License along with this library; see the file COPYING. If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#include <config.h>
#endif
+#ifdef HAVE_GTK_AND_PTHREAD
+#define USE_PTHREAD
+#endif
+
#if ((defined __cplusplus || (defined (__STDC__) && __STDC__) \
|| defined STDC_HEADERS || defined PROTOTYPES) \
&& ! defined (BROKEN_PROTOTYPES))
#include <unistd.h>
#endif
+#ifdef USE_PTHREAD
+#include <pthread.h>
+#endif
+
#endif /* _MALLOC_INTERNAL. */
#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
extern __ptr_t _malloc_internal PP ((__malloc_size_t __size));
extern __ptr_t _realloc_internal PP ((__ptr_t __ptr, __malloc_size_t __size));
extern void _free_internal PP ((__ptr_t __ptr));
+extern __ptr_t _malloc_internal_nolock PP ((__malloc_size_t __size));
+extern __ptr_t _realloc_internal_nolock PP ((__ptr_t __ptr, __malloc_size_t __size));
+extern void _free_internal_nolock PP ((__ptr_t __ptr));
+
+#ifdef USE_PTHREAD
+extern pthread_mutex_t _malloc_mutex, _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()
+#define LOCK_ALIGNED_BLOCKS()
+#define UNLOCK_ALIGNED_BLOCKS()
+#endif
#endif /* _MALLOC_INTERNAL. */
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
+modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
+General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public
+License along with this library; see the file COPYING. If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#include <errno.h>
/* How to really get more memory. */
-__ptr_t (*__morecore) PP ((ptrdiff_t __size)) = __default_morecore;
+#if defined(CYGWIN)
+extern __ptr_t bss_sbrk PP ((ptrdiff_t __size));
+extern int bss_sbrk_did_unexec;
+#endif
+__ptr_t (*__morecore) PP ((__malloc_ptrdiff_t __size)) = __default_morecore;
/* Debugging hook for `malloc'. */
__ptr_t (*__malloc_hook) PP ((__malloc_size_t __size));
_heapinfo[block + blocks].busy.info.size = -blocks;
}
-/* Set everything up and remember that we have. */
-int
-__malloc_initialize ()
+#ifdef USE_PTHREAD
+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 ()
{
- if (__malloc_initialized)
- return 0;
+ 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
+malloc_initialize_1 ()
+{
#ifdef GC_MCHECK
mcheck (NULL);
#endif
heapsize = HEAP / BLOCKSIZE;
_heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info));
if (_heapinfo == NULL)
- return 0;
+ return;
memset (_heapinfo, 0, heapsize * sizeof (malloc_info));
_heapinfo[0].free.size = 0;
_heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
__malloc_initialized = 1;
PROTECT_MALLOC_STATE (1);
- return 1;
+ return;
+}
+
+/* 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 ()
+{
+ if (__malloc_initialized)
+ return 0;
+
+ malloc_initialize_1 ();
+
+ return __malloc_initialized;
}
static int morecore_recursing;
/* Get neatly aligned memory, initializing or
growing the heap info table as necessary. */
-static __ptr_t morecore PP ((__malloc_size_t));
+static __ptr_t morecore_nolock PP ((__malloc_size_t));
static __ptr_t
-morecore (size)
+morecore_nolock (size)
__malloc_size_t size;
{
__ptr_t result;
`morecore_recursing' flag and return null. */
int save = errno; /* Don't want to clobber errno with ENOMEM. */
morecore_recursing = 1;
- newinfo = (malloc_info *) _realloc_internal
+ newinfo = (malloc_info *) _realloc_internal_nolock
(_heapinfo, newsize * sizeof (malloc_info));
morecore_recursing = 0;
if (newinfo == NULL)
/* Reset _heaplimit so _free_internal never decides
it can relocate or resize the info table. */
_heaplimit = 0;
- _free_internal (oldinfo);
+ _free_internal_nolock (oldinfo);
PROTECT_MALLOC_STATE (0);
/* The new heap limit includes the new table just allocated. */
/* Allocate memory from the heap. */
__ptr_t
-_malloc_internal (size)
+_malloc_internal_nolock (size)
__malloc_size_t size;
{
__ptr_t result;
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)
{
/* No free fragments of the desired size, so get a new block
and break it into fragments, returning the first. */
#ifdef GC_MALLOC_CHECK
- result = _malloc_internal (BLOCKSIZE);
+ result = _malloc_internal_nolock (BLOCKSIZE);
PROTECT_MALLOC_STATE (0);
+#elif defined (USE_PTHREAD)
+ result = _malloc_internal_nolock (BLOCKSIZE);
#else
result = malloc (BLOCKSIZE);
#endif
if (result == NULL)
{
PROTECT_MALLOC_STATE (1);
- return NULL;
+ goto out;
}
/* Link all fragments but the first into the free list. */
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)))
_heaplimit += wantblocks - lastblocks;
continue;
}
- result = morecore (wantblocks * BLOCKSIZE);
+ result = morecore_nolock (wantblocks * BLOCKSIZE);
if (result == NULL)
- return NULL;
+ goto out;
block = BLOCK (result);
/* Put the new block at the end of the free list. */
_heapinfo[block].free.size = wantblocks;
}
PROTECT_MALLOC_STATE (1);
+ out:
+ return result;
+}
+
+__ptr_t
+_malloc_internal (size)
+ __malloc_size_t size;
+{
+ __ptr_t result;
+
+ LOCK ();
+ result = _malloc_internal_nolock (size);
+ UNLOCK ();
+
return result;
}
malloc (size)
__malloc_size_t size;
{
+ __ptr_t (*hook) (__malloc_size_t);
+
if (!__malloc_initialized && !__malloc_initialize ())
return NULL;
- return (__malloc_hook != NULL ? *__malloc_hook : _malloc_internal) (size);
+ /* Copy the value of __malloc_hook to an automatic variable in case
+ __malloc_hook is modified in another thread between its
+ NULL-check and the use.
+
+ Note: Strictly speaking, this is not a right solution. We should
+ use mutexes to access non-read-only variables that are shared
+ among multiple threads. We just leave it for compatibility with
+ glibc malloc (i.e., assignments to __malloc_hook) for now. */
+ hook = __malloc_hook;
+ return (hook != NULL ? *hook : _malloc_internal) (size);
}
\f
#ifndef _LIBC
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
+modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
+General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public
+License along with this library; see the file COPYING. If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
/* 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
struct alignlist *_aligned_blocks = NULL;
/* Return memory to the heap.
- Like `free' but don't call a __free_hook if there is one. */
+ Like `_free_internal' but don't lock mutex. */
void
-_free_internal (ptr)
+_free_internal_nolock (ptr)
__ptr_t ptr;
{
int type;
PROTECT_MALLOC_STATE (0);
+ LOCK_ALIGNED_BLOCKS ();
for (l = _aligned_blocks; l != NULL; l = l->next)
if (l->aligned == ptr)
{
ptr = l->exact;
break;
}
+ UNLOCK_ALIGNED_BLOCKS ();
block = BLOCK (ptr);
table's blocks to the system before we have copied them to
the new location. */
_heaplimit = 0;
- _free_internal (_heapinfo);
+ _free_internal_nolock (_heapinfo);
_heaplimit = oldlimit;
/* Tell malloc to search from the beginning of the heap for
_heapindex = 0;
/* Allocate new space for the info table and move its data. */
- newinfo = (malloc_info *) _malloc_internal (info_blocks
- * BLOCKSIZE);
+ newinfo = (malloc_info *) _malloc_internal_nolock (info_blocks
+ * BLOCKSIZE);
PROTECT_MALLOC_STATE (0);
memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE);
_heapinfo = newinfo;
_chunks_free -= BLOCKSIZE >> type;
_bytes_free -= BLOCKSIZE;
-#ifdef GC_MALLOC_CHECK
- _free_internal (ADDRESS (block));
+#if defined (GC_MALLOC_CHECK) || defined (USE_PTHREAD)
+ _free_internal_nolock (ADDRESS (block));
#else
free (ADDRESS (block));
#endif
PROTECT_MALLOC_STATE (1);
}
+/* Return memory to the heap.
+ Like `free' but don't call a __free_hook if there is one. */
+void
+_free_internal (ptr)
+ __ptr_t ptr;
+{
+ LOCK ();
+ _free_internal_nolock (ptr);
+ UNLOCK ();
+}
+
/* Return memory to the heap. */
-FREE_RETURN_TYPE
+void
free (ptr)
__ptr_t ptr;
{
- if (__free_hook != NULL)
- (*__free_hook) (ptr);
+ void (*hook) (__ptr_t) = __free_hook;
+
+ if (hook != NULL)
+ (*hook) (ptr);
else
_free_internal (ptr);
}
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
+modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
+General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public
+License along with this library; see the file COPYING. If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
/* 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
new region. This module has incestuous knowledge of the
internals of both free and malloc. */
__ptr_t
-_realloc_internal (ptr, size)
+_realloc_internal_nolock (ptr, size)
__ptr_t ptr;
__malloc_size_t size;
{
if (size == 0)
{
- _free_internal (ptr);
- return _malloc_internal (0);
+ _free_internal_nolock (ptr);
+ return _malloc_internal_nolock (0);
}
else if (ptr == NULL)
- return _malloc_internal (size);
+ return _malloc_internal_nolock (size);
block = BLOCK (ptr);
/* Maybe reallocate a large block to a small fragment. */
if (size <= BLOCKSIZE / 2)
{
- result = _malloc_internal (size);
+ result = _malloc_internal_nolock (size);
if (result != NULL)
{
memcpy (result, ptr, size);
- _free_internal (ptr);
- return result;
+ _free_internal_nolock (ptr);
+ goto out;
}
}
Now we will free this chunk; increment the statistics counter
so it doesn't become wrong when _free_internal decrements it. */
++_chunks_used;
- _free_internal (ADDRESS (block + blocks));
+ _free_internal_nolock (ADDRESS (block + blocks));
result = ptr;
}
else if (blocks == _heapinfo[block].busy.info.size)
/* Prevent free from actually returning memory to the system. */
oldlimit = _heaplimit;
_heaplimit = 0;
- _free_internal (ptr);
- result = _malloc_internal (size);
+ _free_internal_nolock (ptr);
+ result = _malloc_internal_nolock (size);
PROTECT_MALLOC_STATE (0);
if (_heaplimit == 0)
_heaplimit = oldlimit;
the thing we just freed. Unfortunately it might
have been coalesced with its neighbors. */
if (_heapindex == block)
- (void) _malloc_internal (blocks * BLOCKSIZE);
+ (void) _malloc_internal_nolock (blocks * BLOCKSIZE);
else
{
__ptr_t previous
- = _malloc_internal ((block - _heapindex) * BLOCKSIZE);
- (void) _malloc_internal (blocks * BLOCKSIZE);
- _free_internal (previous);
+ = _malloc_internal_nolock ((block - _heapindex) * BLOCKSIZE);
+ (void) _malloc_internal_nolock (blocks * BLOCKSIZE);
+ _free_internal_nolock (previous);
}
- return NULL;
+ goto out;
}
if (ptr != result)
memmove (result, ptr, blocks * BLOCKSIZE);
{
/* The new size is different; allocate a new space,
and copy the lesser of the new size and the old. */
- result = _malloc_internal (size);
+ result = _malloc_internal_nolock (size);
if (result == NULL)
- return NULL;
+ goto out;
memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type));
- _free_internal (ptr);
+ _free_internal_nolock (ptr);
}
break;
}
PROTECT_MALLOC_STATE (1);
+ out:
+ return result;
+}
+
+__ptr_t
+_realloc_internal (ptr, size)
+ __ptr_t ptr;
+ __malloc_size_t size;
+{
+ __ptr_t result;
+
+ LOCK();
+ result = _realloc_internal_nolock (ptr, size);
+ UNLOCK ();
+
return result;
}
__ptr_t ptr;
__malloc_size_t size;
{
+ __ptr_t (*hook) (__ptr_t, __malloc_size_t);
+
if (!__malloc_initialized && !__malloc_initialize ())
return NULL;
- return (__realloc_hook != NULL ? *__realloc_hook : _realloc_internal)
- (ptr, size);
+ hook = __realloc_hook;
+ return (hook != NULL ? *hook : _realloc_internal) (ptr, size);
}
/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
+modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
+General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public
+License along with this library; see the file COPYING. If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
You should have received a copy of the GNU General Public License
along with the GNU C Library; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+MA 02110-1301, USA. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#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
__default_morecore (increment)
__malloc_ptrdiff_t increment;
{
- __ptr_t result = (__ptr_t) __sbrk (increment);
+ __ptr_t result;
+#if defined(CYGWIN)
+ if (!bss_sbrk_did_unexec)
+ {
+ return bss_sbrk (increment);
+ }
+#endif
+ result = (__ptr_t) __sbrk (increment);
if (result == (__ptr_t) -1)
return NULL;
return result;
/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
+modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
+General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
+You should have received a copy of the GNU General Public
+License along with this library; see the file COPYING. If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#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));
{
__ptr_t result;
unsigned long int adj, lastadj;
+ __ptr_t (*hook) (__malloc_size_t, __malloc_size_t) = __memalign_hook;
- if (__memalign_hook)
- return (*__memalign_hook) (alignment, size);
+ if (hook)
+ return (*hook) (alignment, size);
/* Allocate a block with enough extra space to pad the block with up to
(ALIGNMENT - 1) bytes if necessary. */
of an allocated block. */
struct alignlist *l;
+ LOCK_ALIGNED_BLOCKS ();
for (l = _aligned_blocks; l != NULL; l = l->next)
if (l->aligned == NULL)
/* This slot is free. Use it. */
if (l == NULL)
{
l = (struct alignlist *) malloc (sizeof (struct alignlist));
- if (l == NULL)
+ if (l != NULL)
{
- free (result);
- return NULL;
+ l->next = _aligned_blocks;
+ _aligned_blocks = l;
}
- l->next = _aligned_blocks;
- _aligned_blocks = l;
}
- l->exact = result;
- result = l->aligned = (char *) result + alignment - adj;
+ if (l != NULL)
+ {
+ l->exact = result;
+ result = l->aligned = (char *) result + alignment - adj;
+ }
+ UNLOCK_ALIGNED_BLOCKS ();
+ if (l == NULL)
+ {
+ free (result);
+ result = NULL;
+ }
}
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.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
+modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
+General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public
+License along with this library; see the file COPYING. If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
+modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
+General Public License for more details.
-You should have received a copy of the GNU Library General Public
-License along with this library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.
+You should have received a copy of the GNU General Public
+License along with this library; see the file COPYING. If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+Fifth Floor, Boston, MA 02110-1301, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */