X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/506c9d37d4f03855c37f075b5c88c6efe6958ccb..b092bdee8a6d9f2d32efc51bb6ce3b836822a972:/src/xbt/mmalloc/mm_module.c diff --git a/src/xbt/mmalloc/mm_module.c b/src/xbt/mmalloc/mm_module.c index 6d1baa6b61..5cb60844a5 100644 --- a/src/xbt/mmalloc/mm_module.c +++ b/src/xbt/mmalloc/mm_module.c @@ -35,11 +35,6 @@ Boston, MA 02111-1307, USA. */ #define SEEK_SET 0 #endif - -/* Forward declarations/prototypes for local functions */ - -static struct mdesc *reuse(int fd); - /* Initialize access to a mmalloc managed region. If FD is a valid file descriptor for an open file then data for the @@ -69,7 +64,7 @@ static struct mdesc *reuse(int fd); On failure returns NULL. */ -xbt_mheap_t mmalloc_attach(int fd, void *baseaddr) +xbt_mheap_t xbt_mheap_new(int fd, void *baseaddr) { struct mdesc mtemp; xbt_mheap_t mdp; @@ -87,11 +82,69 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr) if (fstat(fd, &sbuf) < 0) return (NULL); - else if (sbuf.st_size > 0) - return ((void *) reuse(fd)); + else if (sbuf.st_size > 0) { + /* We were given an valid file descriptor on an open file, so try to remap + it into the current process at the same address to which it was previously + mapped. It naturally have to pass some sanity checks for that. + + Note that we have to update the file descriptor number in the malloc- + descriptor read from the file to match the current valid one, before + trying to map the file in, and again after a successful mapping and + after we've switched over to using the mapped in malloc descriptor + rather than the temporary one on the stack. + + Once we've switched over to using the mapped in malloc descriptor, we + have to update the pointer to the morecore function, since it almost + certainly will be at a different address if the process reusing the + mapped region is from a different executable. + + Also note that if the heap being remapped previously used the mmcheckf() + routines, we need to update the hooks since their target functions + will have certainly moved if the executable has changed in any way. + We do this by calling mmcheckf() internally. + + Returns a pointer to the malloc descriptor if successful, or NULL if + unsuccessful for some reason. */ + + struct mdesc mtemp; + struct mdesc *mdp = NULL, *mdptemp = NULL; + + if (lseek(fd, 0L, SEEK_SET) != 0) + return NULL; + if (read(fd, (char *) &mtemp, sizeof(mtemp)) != sizeof(mtemp)) + return NULL; + if (mtemp.headersize != sizeof(mtemp)) + return NULL; + if (strcmp(mtemp.magic, MMALLOC_MAGIC) != 0) + return NULL; + if (mtemp.version > MMALLOC_VERSION) + return NULL; + + mtemp.fd = fd; + if (__mmalloc_remap_core(&mtemp) == mtemp.base) { + mdp = (struct mdesc *) mtemp.base; + mdp->fd = fd; + if(!mdp->refcount){ + sem_init(&mdp->sem, 0, 1); + mdp->refcount++; + } + } + + /* Add the new heap to the linked list of heaps attached by mmalloc */ + mdptemp = __mmalloc_default_mdp; + while(mdptemp->next_mdesc) + mdptemp = mdptemp->next_mdesc; + + LOCK(mdptemp); + mdptemp->next_mdesc = mdp; + UNLOCK(mdptemp); + + return (mdp); + } } - /* If the user provided NULL BASEADDR then fail */ + /* NULL is not a valid baseaddr as we cannot map anything there. + C'mon, user. Think! */ if (baseaddr == NULL) return (NULL); @@ -115,10 +168,8 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr) if (mdp->fd < 0){ mdp->flags |= MMALLOC_ANONYMOUS; - sem_init(&mdp->sem, 0, 1); - }else{ - sem_init(&mdp->sem, 1, 1); } + sem_init(&mdp->sem, 0, 1); /* If we have not been passed a valid open file descriptor for the file to map to, then open /dev/zero and use that to map to. */ @@ -131,7 +182,8 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr) if ((mbase = mmorecore(mdp, sizeof(mtemp))) != NULL) { memcpy(mbase, mdp, sizeof(mtemp)); } else { - THROWF(system_error,0,"morecore failed to get some memory!"); + fprintf(stderr, "morecore failed to get some more memory!\n"); + abort(); } /* Add the new heap to the linked list of heaps attached by mmalloc */ @@ -148,66 +200,6 @@ xbt_mheap_t mmalloc_attach(int fd, void *baseaddr) return mbase; } -/* Given an valid file descriptor on an open file, test to see if that file - is a valid mmalloc produced file, and if so, attempt to remap it into the - current process at the same address to which it was previously mapped. - - Note that we have to update the file descriptor number in the malloc- - descriptor read from the file to match the current valid one, before - trying to map the file in, and again after a successful mapping and - after we've switched over to using the mapped in malloc descriptor - rather than the temporary one on the stack. - - Once we've switched over to using the mapped in malloc descriptor, we - have to update the pointer to the morecore function, since it almost - certainly will be at a different address if the process reusing the - mapped region is from a different executable. - - Also note that if the heap being remapped previously used the mmcheckf() - routines, we need to update the hooks since their target functions - will have certainly moved if the executable has changed in any way. - We do this by calling mmcheckf() internally. - - Returns a pointer to the malloc descriptor if successful, or NULL if - unsuccessful for some reason. */ - -static struct mdesc *reuse(int fd) -{ - struct mdesc mtemp; - struct mdesc *mdp = NULL, *mdptemp = NULL; - - if (lseek(fd, 0L, SEEK_SET) != 0) - return NULL; - if (read(fd, (char *) &mtemp, sizeof(mtemp)) != sizeof(mtemp)) - return NULL; - if (mtemp.headersize != sizeof(mtemp)) - return NULL; - if (strcmp(mtemp.magic, MMALLOC_MAGIC) != 0) - return NULL; - if (mtemp.version > MMALLOC_VERSION) - return NULL; - - mtemp.fd = fd; - if (__mmalloc_remap_core(&mtemp) == mtemp.base) { - mdp = (struct mdesc *) mtemp.base; - mdp->fd = fd; - if(!mdp->refcount){ - sem_init(&mdp->sem, 1, 1); - mdp->refcount++; - } - } - - /* Add the new heap to the linked list of heaps attached by mmalloc */ - mdptemp = __mmalloc_default_mdp; - while(mdptemp->next_mdesc) - mdptemp = mdptemp->next_mdesc; - - LOCK(mdptemp); - mdptemp->next_mdesc = mdp; - UNLOCK(mdptemp); - - return (mdp); -} /** Terminate access to a mmalloc managed region, but do not free its content. @@ -215,7 +207,7 @@ static struct mdesc *reuse(int fd) * 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(xbt_mheap_t md) +void xbt_mheap_destroy_no_free(xbt_mheap_t md) { struct mdesc *mdp = md; @@ -233,13 +225,13 @@ void mmalloc_detach_no_free(xbt_mheap_t md) Returns the malloc descriptor on failure, which can subsequently be used for further action, such as obtaining more information about the nature of - the failure by examining the preserved errno value. + the failure. Note that the malloc descriptor that we are using is currently located in 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(xbt_mheap_t mdp) +void *xbt_mheap_destroy(xbt_mheap_t mdp) { struct mdesc mtemp, *mdptemp; @@ -251,7 +243,7 @@ void *mmalloc_detach(xbt_mheap_t mdp) mdptemp->next_mdesc = mdp->next_mdesc; - mmalloc_detach_no_free(mdp); + xbt_mheap_destroy_no_free(mdp); mtemp = *mdp; /* Now unmap all the pages associated with this region by asking for a @@ -331,7 +323,7 @@ void *mmalloc_preinit(void) 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); + __mmalloc_default_mdp = xbt_mheap_new(-1, addr); /* Fixme? only the default mdp in protected against forks */ res = xbt_os_thread_atfork(mmalloc_fork_prepare, mmalloc_fork_parent, mmalloc_fork_child); @@ -347,5 +339,5 @@ void mmalloc_postexit(void) { /* Do not detach the default mdp or ldl won't be able to free the memory it allocated since we're in memory */ // mmalloc_detach(__mmalloc_default_mdp); - mmalloc_detach_no_free(__mmalloc_default_mdp); + xbt_mheap_destroy_no_free(__mmalloc_default_mdp); }