#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */
#endif /* WIN32 */
+#ifdef __OS2__
+#define INCL_DOS
+#include <os2.h>
+#define HAVE_MMAP 1
+#define HAVE_MORECORE 0
+#define LACKS_SYS_MMAN_H
+#endif /* __OS2__ */
+
#if defined(DARWIN) || defined(_DARWIN)
/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
#ifndef HAVE_MORECORE
#include "/usr/include/malloc.h"
#else /* HAVE_USR_INCLUDE_MALLOC_H */
+/* HP-UX's stdlib.h redefines mallinfo unless _STRUCT_MALLINFO is defined */
+#define _STRUCT_MALLINFO
+
struct mallinfo {
MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */
MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */
/*------------------------------ internal #includes ---------------------- */
-#ifdef WIN32
+#ifdef _MSC_VER
#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
-#endif /* WIN32 */
+#endif /* _MSC_VER */
#include <stdio.h> /* for printing in malloc_stats */
#define SIZE_T_BITSIZE (sizeof(size_t) << 3)
/* Some constants coerced to size_t */
-/* Annoying but necessary to avoid errors on some plaftorms */
+/* Annoying but necessary to avoid errors on some platforms */
#define SIZE_T_ZERO ((size_t)0)
#define SIZE_T_ONE ((size_t)1)
#define SIZE_T_TWO ((size_t)2)
#define IS_MMAPPED_BIT (SIZE_T_ONE)
#define USE_MMAP_BIT (SIZE_T_ONE)
-#ifndef WIN32
+#if !defined(WIN32) && !defined (__OS2__)
#define CALL_MUNMAP(a, s) munmap((a), (s))
#define MMAP_PROT (PROT_READ|PROT_WRITE)
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#endif /* MAP_ANONYMOUS */
#define DIRECT_MMAP(s) CALL_MMAP(s)
+
+#elif defined(__OS2__)
+
+/* OS/2 MMAP via DosAllocMem */
+static void* os2mmap(size_t size) {
+ void* ptr;
+ if (DosAllocMem(&ptr, size, OBJ_ANY|PAG_COMMIT|PAG_READ|PAG_WRITE) &&
+ DosAllocMem(&ptr, size, PAG_COMMIT|PAG_READ|PAG_WRITE))
+ return MFAIL;
+ return ptr;
+}
+
+#define os2direct_mmap(n) os2mmap(n)
+
+/* This function supports releasing coalesed segments */
+static int os2munmap(void* ptr, size_t size) {
+ while (size) {
+ ULONG ulSize = size;
+ ULONG ulFlags = 0;
+ if (DosQueryMem(ptr, &ulSize, &ulFlags) != 0)
+ return -1;
+ if ((ulFlags & PAG_BASE) == 0 ||(ulFlags & PAG_COMMIT) == 0 ||
+ ulSize > size)
+ return -1;
+ if (DosFreeMem(ptr) != 0)
+ return -1;
+ ptr = ( void * ) ( ( char * ) ptr + ulSize );
+ size -= ulSize;
+ }
+ return 0;
+}
+
+#define CALL_MMAP(s) os2mmap(s)
+#define CALL_MUNMAP(a, s) os2munmap((a), (s))
+#define DIRECT_MMAP(s) os2direct_mmap(s)
+
#else /* WIN32 */
/* Win32 MMAP via VirtualAlloc */
static void* win32mmap(size_t size) {
- void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
+ void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
return (ptr != 0)? ptr: MFAIL;
}
/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
static void* win32direct_mmap(size_t size) {
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
- PAGE_READWRITE);
+ PAGE_EXECUTE_READWRITE);
return (ptr != 0)? ptr: MFAIL;
}
#define CALL_MORECORE(S) MFAIL
#endif /* HAVE_MORECORE */
-/* mstate bit set if continguous morecore disabled or failed */
+/* mstate bit set if contiguous morecore disabled or failed */
#define USE_NONCONTIGUOUS_BIT (4U)
/* segment bit set in create_mspace_with_base */
unique mparams values are initialized only once.
*/
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
/* By default use posix locks */
#include <pthread.h>
#define MLOCK_T pthread_mutex_t
static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+#elif defined(__OS2__)
+#define MLOCK_T HMTX
+#define INITIAL_LOCK(l) DosCreateMutexSem(0, l, 0, FALSE)
+#define ACQUIRE_LOCK(l) DosRequestMutexSem(*l, SEM_INDEFINITE_WAIT)
+#define RELEASE_LOCK(l) DosReleaseMutexSem(*l)
+#if HAVE_MORECORE
+static MLOCK_T morecore_mutex;
+#endif /* HAVE_MORECORE */
+static MLOCK_T magic_init_mutex;
+
#else /* WIN32 */
/*
Because lock-protected regions have bounded times, and there
typedef struct malloc_chunk mchunk;
typedef struct malloc_chunk* mchunkptr;
typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */
-typedef unsigned int bindex_t; /* Described below */
+typedef size_t bindex_t; /* Described below */
typedef unsigned int binmap_t; /* Described below */
typedef unsigned int flag_t; /* The type of various bit flag sets */
}
RELEASE_MAGIC_INIT_LOCK();
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__OS2__)
mparams.page_size = malloc_getpagesize;
mparams.granularity = ((DEFAULT_GRANULARITY != 0)?
DEFAULT_GRANULARITY : mparams.page_size);
+#elif defined (__OS2__)
+ /* if low-memory is used, os2munmap() would break
+ if it were anything other than 64k */
+ mparams.page_size = 4096u;
+ mparams.granularity = 65536u;
#else /* WIN32 */
{
SYSTEM_INFO system_info;
and choose its bk node as its replacement.
2. If x was the last node of its size, but not a leaf node, it must
be replaced with a leaf node (not merely one with an open left or
- right), to make sure that lefts and rights of descendents
- correspond properly to bit masks. We use the rightmost descendent
+ right), to make sure that lefts and rights of descendants
+ correspond properly to bit masks. We use the rightmost descendant
of x. We could use any other leaf, but this is easy to locate and
tends to counteract removal of leftmosts elsewhere, and so keeps
paths shorter than minimally guaranteed. This doesn't loop much
*ss = m->seg; /* Push current record */
m->seg.base = tbase;
m->seg.size = tsize;
- set_segment_flags(&m->seg, mmapped);
+ (void)set_segment_flags(&m->seg, mmapped);
m->seg.next = ss;
/* Insert trailing fenceposts */
if (!is_initialized(m)) { /* first-time initialization */
m->seg.base = m->least_addr = tbase;
m->seg.size = tsize;
- set_segment_flags(&m->seg, mmap_flag);
+ (void)set_segment_flags(&m->seg, mmap_flag);
m->magic = mparams.magic;
init_bins(m);
if (is_global(m))
void dlfree(void* mem) {
/*
- Consolidate freed chunks with preceeding or succeeding bordering
+ Consolidate freed chunks with preceding or succeeding bordering
free chunks, if they exist, and then place in a bin. Intermixed
with special cases for top, dv, mmapped chunks, and usage errors.
*/
Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
* Use last_remainder in more cases.
* Pack bins using idea from colin@nyx10.cs.du.edu
- * Use ordered bins instead of best-fit threshhold
+ * Use ordered bins instead of best-fit threshold
* Eliminate block-local decls to simplify tracing and debugging.
* Support another case of realloc via move into top
- * Fix error occuring when initial sbrk_base not word-aligned.
+ * Fix error occurring when initial sbrk_base not word-aligned.
* Rely on page size for units instead of SBRK_UNIT to
avoid surprises about sbrk alignment conventions.
* Add mallinfo, mallopt. Thanks to Raymond Nijssen