# include <stdio.h> /* for NULL */
#endif
+/* Datatype representing a separate heap. The whole point of the mmalloc module
+ * is to allow several such heaps in the process. It thus works by redefining
+ * all the classical memory management functions (malloc and friends) with an
+ * extra first argument: the heap in which the memory is to be taken.
+ *
+ * The heap structure itself is an opaque object that shouldnt be messed with.
+ */
+typedef struct mdesc *xbt_mheap_t;
+
/* Allocate SIZE bytes of memory. */
-extern void *mmalloc(void *md, size_t size);
+extern void *mmalloc(xbt_mheap_t md, size_t size);
/* Re-allocate the previously allocated block in void*, making the new block
SIZE bytes long. */
-extern void *mrealloc(void *md, void *ptr, size_t size);
+extern void *mrealloc(xbt_mheap_t md, void *ptr, size_t size);
/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
-extern void *mcalloc(void *md, size_t nmemb, size_t size);
+extern void *mcalloc(xbt_mheap_t md, size_t nmemb, size_t size);
/* Free a block allocated by `mmalloc', `mrealloc' or `mcalloc'. */
-extern void mfree(void *md, void *ptr);
+extern void mfree(xbt_mheap_t md, void *ptr);
/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
-extern void *mmemalign(void *md, size_t alignment, size_t size);
+extern void *mmemalign(xbt_mheap_t md, size_t alignment, size_t size);
/* Allocate SIZE bytes on a page boundary. */
-extern void *mvalloc(void *md, size_t size);
+extern void *mvalloc(xbt_mheap_t md, size_t size);
-extern void *mmalloc_attach(int fd, void *baseaddr);
+extern xbt_mheap_t mmalloc_attach(int fd, void *baseaddr);
-extern void mmalloc_detach_no_free(void *md);
+extern void mmalloc_detach_no_free(xbt_mheap_t md);
-extern void *mmalloc_detach(void *md);
+extern void *mmalloc_detach(xbt_mheap_t md);
/* return the heap used when NULL is passed as first argument to any mm* function */
-extern void *mmalloc_get_default_md(void);
+extern xbt_mheap_t mmalloc_get_default_md(void);
extern void *mmalloc_findbase(int size);
-extern int mmalloc_compare_heap(void *h1, void *h2, void *std_heap_addr);
-
-extern void mmalloc_display_info_heap(void *h);
+extern void mmalloc_display_info_heap(xbt_mheap_t h);
/* To change the heap used when using the legacy version malloc/free/realloc and such */
-void mmalloc_set_current_heap(void *new_heap);
-void *mmalloc_get_current_heap(void);
+void mmalloc_set_current_heap(xbt_mheap_t new_heap);
+xbt_mheap_t mmalloc_get_current_heap(void);
+int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr);
#endif /* MMALLOC_H */
On failure returns NULL. */
-void *mmalloc_attach(int fd, void *baseaddr)
+xbt_mheap_t mmalloc_attach(int fd, void *baseaddr)
{
struct mdesc mtemp;
- struct mdesc *mdp;
+ xbt_mheap_t mdp;
void *mbase;
struct stat sbuf;
mdp->next_mdesc = (struct mdesc *)mbase;
UNLOCK(mdp);
}
-
- return ((void *) mbase);
+
+ return mbase;
}
/* Given an valid file descriptor on an open file, test to see if that file
* This is for example useful for the base region where ldl stores its data
* because it leaves the place after us.
*/
-void mmalloc_detach_no_free(void *md)
+void mmalloc_detach_no_free(xbt_mheap_t md)
{
struct mdesc *mdp = md;
region we are about to unmap, so we first make a local copy of it on the
stack and use the copy. */
-void *mmalloc_detach(void *md)
+void *mmalloc_detach(xbt_mheap_t mdp)
{
- struct mdesc *mdp = (struct mdesc *)md;
struct mdesc mtemp, *mdptemp;
if (mdp != NULL) {
mdptemp->next_mdesc = mdp->next_mdesc;
- mmalloc_detach_no_free(md);
- mtemp = *(struct mdesc *) md;
+ mmalloc_detach_no_free(mdp);
+ mtemp = *mdp;
/* Now unmap all the pages associated with this region by asking for a
negative increment equal to the current size of the region. */
NULL) {
/* Deallocating failed. Update the original malloc descriptor
with any changes */
- *(struct mdesc *) md = mtemp;
+ *mdp = mtemp;
} else {
if (mtemp.flags & MMALLOC_DEVZERO) {
close(mtemp.fd);
}
- md = NULL;
+ mdp = NULL;
}
}
- return (md);
+ return (mdp);
}
/* Allocate an array of NMEMB elements each SIZE bytes long.
The entire array is initialized to zeros. */
-void *mcalloc(void *md, register size_t nmemb, register size_t size)
+void *mcalloc(xbt_mheap_t md, register size_t nmemb, register size_t size)
{
register void *result;
/* Return memory to the heap. */
-void mfree(void *md, void *ptr)
+void mfree(xbt_mheap_t mdp, void *ptr)
{
- struct mdesc *mdp;
register struct alignlist *l;
if (ptr != NULL) {
- mdp = MD_TO_MDP(md);
for (l = mdp->aligned_blocks; l != NULL; l = l->next) {
if (l->aligned == ptr) {
l->aligned = NULL; /* Mark the slot in the list as free. */
for mmalloc/mrealloc/mfree operations which do not supply an explicit
descriptor. This allows mmalloc() to provide
backwards compatibility with the non-mmap'd version. */
-struct mdesc *__mmalloc_default_mdp;
+xbt_mheap_t __mmalloc_default_mdp = NULL;
-static void *__mmalloc_current_heap = NULL; /* The heap we are currently using. */
+static xbt_mheap_t __mmalloc_current_heap = NULL; /* The heap we are currently using. */
#include "xbt_modinter.h"
-void *mmalloc_get_current_heap(void)
+xbt_mheap_t mmalloc_get_current_heap(void)
{
return __mmalloc_current_heap;
}
-void mmalloc_set_current_heap(void *new_heap)
+void mmalloc_set_current_heap(xbt_mheap_t new_heap)
{
__mmalloc_current_heap = new_heap;
}
#ifdef MMALLOC_WANT_OVERIDE_LEGACY
void *malloc(size_t n)
{
- void *mdp = __mmalloc_current_heap;
-#ifdef HAVE_MMAP
- if (!mdp)
- mmalloc_preinit();
-#endif
+ xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+
LOCK(mdp);
void *ret = mmalloc(mdp, n);
UNLOCK(mdp);
void *calloc(size_t nmemb, size_t size)
{
size_t total_size = nmemb * size;
- void *mdp = __mmalloc_current_heap;
-#ifdef HAVE_MMAP
- if (!mdp)
- mmalloc_preinit();
-#endif
+ xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+
LOCK(mdp);
void *ret = mmalloc(mdp, total_size);
UNLOCK(mdp);
void *realloc(void *p, size_t s)
{
void *ret = NULL;
- void *mdp = __mmalloc_current_heap;
-#ifdef HAVE_MMAP
- if (!mdp)
- mmalloc_preinit();
-#endif
+ xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+
LOCK(mdp);
if (s) {
if (p)
void free(void *p)
{
- void *mdp = __mmalloc_current_heap;
-#ifdef HAVE_GTNETS
- if(!mdp) return;
-#endif
+ xbt_mheap_t mdp = __mmalloc_current_heap ?: (xbt_mheap_t) mmalloc_preinit();
+
LOCK(mdp);
mfree(mdp, p);
UNLOCK(mdp);
* valgrind. */
#define HEAP_OFFSET (128UL<<20)
-void *mmalloc_get_default_md(void)
+xbt_mheap_t mmalloc_get_default_md(void)
{
xbt_assert(__mmalloc_default_mdp);
return __mmalloc_default_mdp;
static void mmalloc_fork_prepare(void)
{
- struct mdesc* mdp = NULL;
+ xbt_mheap_t mdp = NULL;
if ((mdp =__mmalloc_default_mdp)){
while(mdp){
LOCK(mdp);
static void mmalloc_fork_parent(void)
{
- struct mdesc* mdp = NULL;
+ xbt_mheap_t mdp = NULL;
if ((mdp =__mmalloc_default_mdp)){
while(mdp){
if(mdp->fd < 0)
}
/* Initialize the default malloc descriptor. */
-void mmalloc_preinit(void)
+void *mmalloc_preinit(void)
{
int res;
- if (!__mmalloc_default_mdp) {
+ if (__mmalloc_default_mdp == NULL) {
unsigned long mask = ~((unsigned long)getpagesize() - 1);
void *addr = (void*)(((unsigned long)sbrk(0) + HEAP_OFFSET) & mask);
__mmalloc_default_mdp = mmalloc_attach(-1, addr);
THROWF(system_error,0,"xbt_os_thread_atfork() failed: return value %d",res);
}
xbt_assert(__mmalloc_default_mdp != NULL);
+
+ return __mmalloc_default_mdp;
}
void mmalloc_postexit(void)
mmalloc_detach_no_free(__mmalloc_default_mdp);
}
-int mmalloc_compare_heap(void *h1, void *h2, void *std_heap_addr){
+int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2, void *std_heap_addr){
- if(h1 == NULL && h2 == NULL){
+ if(mdp1 == NULL && mdp2 == NULL){
XBT_DEBUG("Malloc descriptors null");
return 0;
}
/* Heapstats */
- struct mdesc *mdp1, *mdp2;
- mdp1 = MD_TO_MDP(h1);
- mdp2 = MD_TO_MDP(h2);
-
int errors = mmalloc_compare_mdesc(mdp1, mdp2, std_heap_addr);
return (errors > 0);
}
-void mmalloc_display_info_heap(void *h){
+void mmalloc_display_info_heap(xbt_mheap_t h){
}
+
+/* Useless prototype to make gcc happy */
+void *valloc(size_t size);
+
+void *valloc(size_t size)
+{ //FIXME: won't work
+ return mvalloc(NULL, size);
+}
+
/* Allocate memory from the heap. */
-void *mmalloc(void *md, size_t size)
+void *mmalloc(xbt_mheap_t mdp, size_t size)
{
- struct mdesc *mdp;
void *result;
size_t block, blocks, lastblocks, start;
register size_t i;
if (size == 0)
size = 1;
- mdp = MD_TO_MDP(md);
// printf("(%s) Mallocing %d bytes on %p (default: %p)...",xbt_thread_self_name(),size,mdp,__mmalloc_default_mdp);fflush(stdout);
if (!(mdp->flags & MMALLOC_INITIALIZED)) {
/* No free fragments of the desired size, so get a new block
and break it into fragments, returning the first. */
//printf("(%s) No free fragment...",xbt_thread_self_name());
- result = mmalloc(md, BLOCKSIZE);
+ result = mmalloc(mdp, BLOCKSIZE);
//printf("(%s) Fragment: %p...",xbt_thread_self_name(),result);
if (result == NULL) {
return (NULL);
#include "mmprivate.h"
-void *mmemalign(void *md, size_t alignment, size_t size)
+void *mmemalign(xbt_mheap_t mdp, size_t alignment, size_t size)
{
void *result;
unsigned long int adj;
struct alignlist *l;
- struct mdesc *mdp;
- if ((result = mmalloc(md, size + alignment - 1)) != NULL) {
+ if ((result = mmalloc(mdp, size + alignment - 1)) != NULL) {
adj = RESIDUAL(result, alignment);
if (adj != 0) {
- mdp = MD_TO_MDP(md);
for (l = mdp->aligned_blocks; l != NULL; l = l->next) {
if (l->aligned == NULL) {
/* This slot is free. Use it. */
}
}
if (l == NULL) {
- l = (struct alignlist *) mmalloc(md, sizeof(struct alignlist));
+ l = (struct alignlist *) mmalloc(mdp, sizeof(struct alignlist));
if (l == NULL) {
- mfree(md, result);
+ mfree(mdp, result);
return (NULL);
}
l->next = mdp->aligned_blocks;
};
-int mmalloc_compare_heap(void *h1, void *h2, void *std_heap_addr);
-
int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2, void *std_heap_addr);
void mmalloc_display_info(void *h);
extern struct mdesc *__mmalloc_create_default_mdp(void);
-/* Grow or shrink a contiguous mapped region using mmap().
- Works much like sbrk(), only faster */
-
-extern void *__mmalloc_mmap_morecore(struct mdesc *mdp, int size);
-
-
/* Remap a mmalloc region that was previously mapped. */
extern void *__mmalloc_remap_core(struct mdesc *mdp);
like sbrk(), but using mmap(). */
extern void *mmorecore(struct mdesc *mdp, int size);
-/* Macro to convert from a user supplied malloc descriptor to pointer to the
- internal malloc descriptor. If the user supplied descriptor is NULL, then
- use the default internal version, initializing it if necessary. Otherwise
- just cast the user supplied version (which is void *) to the proper type
- (struct mdesc *). */
-
-#define MD_TO_MDP(md) \
- ((md) == NULL \
- ? __mmalloc_default_mdp \
- : (struct mdesc *) (md))
-
-/* Thread-safety (if the sem is already created)*/
-#define LOCK(md) \
- do {\
- struct mdesc *lock_local_mdp = MD_TO_MDP(md); \
- sem_wait(&lock_local_mdp->sem); \
- } while (0)
-
-#define UNLOCK(md) \
- do { \
- struct mdesc *unlock_local_mdp = MD_TO_MDP(md); \
- sem_post(&unlock_local_mdp->sem); \
- } while (0)
+/* Thread-safety (if the sem is already created) FIXME: KILLIT*/
+#define LOCK(mdp) \
+ sem_wait(&mdp->sem)
+
+#define UNLOCK(mdp) \
+ sem_post(&mdp->sem)
#endif /* __MMPRIVATE_H */
new region. This module has incestuous knowledge of the
internals of both mfree and mmalloc. */
-void *mrealloc(void *md, void *ptr, size_t size)
+void *mrealloc(xbt_mheap_t mdp, void *ptr, size_t size)
{
- struct mdesc *mdp;
void *result;
int type;
size_t block, blocks, oldlimit;
if (size == 0) {
- mfree(md, ptr);
- return (mmalloc(md, 0));
+ mfree(mdp, ptr);
+ return (mmalloc(mdp, 0));
} else if (ptr == NULL) {
- return (mmalloc(md, size));
+ return (mmalloc(mdp, size));
}
- mdp = MD_TO_MDP(md);
//printf("(%s)realloc %p to %d...",xbt_thread_self_name(),ptr,(int)size);
if ((char *) ptr < (char *) mdp->heapbase || BLOCK(ptr) > mdp->heapsize) {
printf
("FIXME. Ouch, this pointer is not mine, refusing to proceed (another solution would be to malloc it instead of reallocing it, see source code)\n");
- result = mmalloc(md, size);
+ result = mmalloc(mdp, size);
abort();
return result;
}
/* Maybe reallocate a large block to a small fragment. */
if (size <= BLOCKSIZE / 2) {
//printf("(%s) alloc large block...",xbt_thread_self_name());
- result = mmalloc(md, size);
+ result = mmalloc(mdp, size);
if (result != NULL) {
memcpy(result, ptr, size);
- mfree(md, ptr);
+ mfree(mdp, ptr);
return (result);
}
}
= mdp->heapinfo[block].busy.info.block.size - blocks;
mdp->heapinfo[block].busy.info.block.size = blocks;
mdp->heapinfo[block].busy.info.block.busy_size = size;
- mfree(md, ADDRESS(block + blocks));
+ mfree(mdp, ADDRESS(block + blocks));
result = ptr;
} else if (blocks == mdp->heapinfo[block].busy.info.block.size) {
/* No size change necessary. */
/* Prevent free from actually returning memory to the system. */
oldlimit = mdp->heaplimit;
mdp->heaplimit = 0;
- mfree(md, ptr);
+ mfree(mdp, ptr);
mdp->heaplimit = oldlimit;
- result = mmalloc(md, size);
+ result = mmalloc(mdp, size);
if (result == NULL) {
- mmalloc(md, blocks * BLOCKSIZE);
+ mmalloc(mdp, blocks * BLOCKSIZE);
return (NULL);
}
if (ptr != result)
and copy the lesser of the new size and the old. */
//printf("(%s) new size is different...",xbt_thread_self_name());
- result = mmalloc(md, size);
+ result = mmalloc(mdp, size);
if (result == NULL)
return (NULL);
memcpy(result, ptr, MIN(size, (size_t) 1 << type));
- mfree(md, ptr);
+ mfree(mdp, ptr);
}
break;
}
extern int getpagesize PARAMS((void));
#endif
-void *mvalloc(void *md, size_t size)
+void *mvalloc(xbt_mheap_t mdp, size_t size)
{
if (cache_pagesize == 0) {
cache_pagesize = getpagesize();
}
- return (mmemalign(md, cache_pagesize, size));
+ return (mmemalign(mdp, cache_pagesize, size));
}
-/* Useless prototype to make gcc happy */
-void *valloc(size_t size);
-
-void *valloc(size_t size)
-{
- return mvalloc(NULL, size);
-}
void xbt_datadesc_preinit(void);
void xbt_datadesc_postexit(void);
-void mmalloc_preinit(void);
+void *mmalloc_preinit(void);
void mmalloc_postexit(void);