comparison src/stdlib/SDL_malloc.c @ 2203:fca1cdc673b2

Fixed bug #428 This fix is overkill, but approved by Doug Lea, and he'll be releasing a new version of his malloc.c sometime next month.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 16 Jul 2007 00:08:35 +0000
parents 2aee80dab68a
children 1de324fce4e8
comparison
equal deleted inserted replaced
2202:98e76ba7d5a4 2203:fca1cdc673b2
2725 if (u->child[0] != 0 && u->child[1] != 0) { 2725 if (u->child[0] != 0 && u->child[1] != 0) {
2726 assert(chunksize(u->child[0]) < chunksize(u->child[1])); 2726 assert(chunksize(u->child[0]) < chunksize(u->child[1]));
2727 } 2727 }
2728 } 2728 }
2729 u = u->fd; 2729 u = u->fd;
2730 } 2730 } while (u != t);
2731 while (u != t);
2732 assert(head != 0); 2731 assert(head != 0);
2733 } 2732 }
2734 2733
2735 /* Check all the chunks in a treebin. */ 2734 /* Check all the chunks in a treebin. */
2736 static void 2735 static void
2782 if (smallmap_is_marked(m, sidx)) { 2781 if (smallmap_is_marked(m, sidx)) {
2783 mchunkptr p = b; 2782 mchunkptr p = b;
2784 do { 2783 do {
2785 if (p == x) 2784 if (p == x)
2786 return 1; 2785 return 1;
2787 } 2786 } while ((p = p->fd) != b);
2788 while ((p = p->fd) != b);
2789 } 2787 }
2790 } else { 2788 } else {
2791 bindex_t tidx; 2789 bindex_t tidx;
2792 compute_tree_index(size, tidx); 2790 compute_tree_index(size, tidx);
2793 if (treemap_is_marked(m, tidx)) { 2791 if (treemap_is_marked(m, tidx)) {
2800 if (t != 0) { 2798 if (t != 0) {
2801 tchunkptr u = t; 2799 tchunkptr u = t;
2802 do { 2800 do {
2803 if (u == (tchunkptr) x) 2801 if (u == (tchunkptr) x)
2804 return 1; 2802 return 1;
2805 } 2803 } while ((u = u->fd) != t);
2806 while ((u = u->fd) != t);
2807 } 2804 }
2808 } 2805 }
2809 } 2806 }
2810 return 0; 2807 return 0;
2811 } 2808 }
3474 ACQUIRE_MORECORE_LOCK(); 3471 ACQUIRE_MORECORE_LOCK();
3475 3472
3476 if (ss == 0) { /* First time through or recovery */ 3473 if (ss == 0) { /* First time through or recovery */
3477 char *base = (char *) CALL_MORECORE(0); 3474 char *base = (char *) CALL_MORECORE(0);
3478 if (base != CMFAIL) { 3475 if (base != CMFAIL) {
3479 asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); 3476 asize =
3477 granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT +
3478 SIZE_T_ONE);
3480 /* Adjust to end on a page boundary */ 3479 /* Adjust to end on a page boundary */
3481 if (!is_page_aligned(base)) 3480 if (!is_page_aligned(base))
3482 asize += (page_align((size_t) base) - (size_t) base); 3481 asize += (page_align((size_t) base) - (size_t) base);
3483 /* Can't call MORECORE if size is negative when treated as signed */ 3482 /* Can't call MORECORE if size is negative when treated as signed */
3484 if (asize < HALF_MAX_SIZE_T && 3483 if (asize < HALF_MAX_SIZE_T &&
3489 } 3488 }
3490 } else { 3489 } else {
3491 /* Subtract out existing available top space from MORECORE request. */ 3490 /* Subtract out existing available top space from MORECORE request. */
3492 asize = 3491 asize =
3493 granularity_align(nb - m->topsize + TOP_FOOT_SIZE + 3492 granularity_align(nb - m->topsize + TOP_FOOT_SIZE +
3494 SIZE_T_ONE); 3493 MALLOC_ALIGNMENT + SIZE_T_ONE);
3495 /* Use mem here only if it did continuously extend old space */ 3494 /* Use mem here only if it did continuously extend old space */
3496 if (asize < HALF_MAX_SIZE_T && 3495 if (asize < HALF_MAX_SIZE_T &&
3497 (br = 3496 (br =
3498 (char *) (CALL_MORECORE(asize))) == ss->base + ss->size) { 3497 (char *) (CALL_MORECORE(asize))) == ss->base + ss->size) {
3499 tbase = br; 3498 tbase = br;
3505 if (br != CMFAIL) { /* Try to use/extend the space we did get */ 3504 if (br != CMFAIL) { /* Try to use/extend the space we did get */
3506 if (asize < HALF_MAX_SIZE_T && 3505 if (asize < HALF_MAX_SIZE_T &&
3507 asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { 3506 asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) {
3508 size_t esize = 3507 size_t esize =
3509 granularity_align(nb + TOP_FOOT_SIZE + 3508 granularity_align(nb + TOP_FOOT_SIZE +
3510 SIZE_T_ONE - asize); 3509 MALLOC_ALIGNMENT + SIZE_T_ONE -
3510 asize);
3511 if (esize < HALF_MAX_SIZE_T) { 3511 if (esize < HALF_MAX_SIZE_T) {
3512 char *end = (char *) CALL_MORECORE(esize); 3512 char *end = (char *) CALL_MORECORE(esize);
3513 if (end != CMFAIL) 3513 if (end != CMFAIL)
3514 asize += esize; 3514 asize += esize;
3515 else { /* Can't use; try to release */ 3515 else { /* Can't use; try to release */
3528 3528
3529 RELEASE_MORECORE_LOCK(); 3529 RELEASE_MORECORE_LOCK();
3530 } 3530 }
3531 3531
3532 if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ 3532 if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */
3533 size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE; 3533 size_t req = nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE;
3534 size_t rsize = granularity_align(req); 3534 size_t rsize = granularity_align(req);
3535 if (rsize > nb) { /* Fail if wraps around zero */ 3535 if (rsize > nb) { /* Fail if wraps around zero */
3536 char *mp = (char *) (CALL_MMAP(rsize)); 3536 char *mp = (char *) (CALL_MMAP(rsize));
3537 if (mp != CMFAIL) { 3537 if (mp != CMFAIL) {
3538 tbase = mp; 3538 tbase = mp;
3541 } 3541 }
3542 } 3542 }
3543 } 3543 }
3544 3544
3545 if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ 3545 if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
3546 size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); 3546 size_t asize =
3547 granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT +
3548 SIZE_T_ONE);
3547 if (asize < HALF_MAX_SIZE_T) { 3549 if (asize < HALF_MAX_SIZE_T) {
3548 char *br = CMFAIL; 3550 char *br = CMFAIL;
3549 char *end = CMFAIL; 3551 char *end = CMFAIL;
3550 ACQUIRE_MORECORE_LOCK(); 3552 ACQUIRE_MORECORE_LOCK();
3551 br = (char *) (CALL_MORECORE(asize)); 3553 br = (char *) (CALL_MORECORE(asize));
3677 pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ 3679 pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
3678 3680
3679 if (m->topsize > pad) { 3681 if (m->topsize > pad) {
3680 /* Shrink top space in granularity-size units, keeping at least one */ 3682 /* Shrink top space in granularity-size units, keeping at least one */
3681 size_t unit = mparams.granularity; 3683 size_t unit = mparams.granularity;
3682 size_t extra = 3684 size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
3683 ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - 3685 SIZE_T_ONE) * unit;
3684 SIZE_T_ONE) * unit;
3685 msegmentptr sp = segment_holding(m, (char *) m->top); 3686 msegmentptr sp = segment_holding(m, (char *) m->top);
3686 3687
3687 if (!is_extern_segment(sp)) { 3688 if (!is_extern_segment(sp)) {
3688 if (is_mmapped_segment(sp)) { 3689 if (is_mmapped_segment(sp)) {
3689 if (HAVE_MMAP && sp->size >= extra && !has_segment_link(m, sp)) { /* can't shrink if pinned */ 3690 if (HAVE_MMAP && sp->size >= extra && !has_segment_link(m, sp)) { /* can't shrink if pinned */
3690 size_t newsize = sp->size - extra; 3691 size_t newsize = sp->size - extra;
3691 /* Prefer mremap, fall back to munmap */ 3692 /* Prefer mremap, fall back to munmap */
3692 if ((CALL_MREMAP 3693 if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) !=
3693 (sp->base, sp->size, newsize, 0) != MFAIL) 3694 MFAIL)
3694 || (CALL_MUNMAP(sp->base + newsize, extra) 3695 || (CALL_MUNMAP(sp->base + newsize, extra) ==
3695 == 0)) { 3696 0)) {
3696 released = extra; 3697 released = extra;
3697 } 3698 }
3698 } 3699 }
3699 } else if (HAVE_MORECORE) { 3700 } else if (HAVE_MORECORE) {
3700 if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ 3701 if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
3960 the first calculation places us at a spot with less than 3961 the first calculation places us at a spot with less than
3961 MIN_CHUNK_SIZE leader, we can move to the next aligned spot. 3962 MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
3962 We've allocated enough total room so that this is always 3963 We've allocated enough total room so that this is always
3963 possible. 3964 possible.
3964 */ 3965 */
3965 char *br = (char *) 3966 char *br = (char *) mem2chunk((size_t) (((size_t) (mem +
3966 mem2chunk((size_t) 3967 alignment -
3967 (((size_t) 3968 SIZE_T_ONE))
3968 (mem + alignment - 3969 & -alignment));
3969 SIZE_T_ONE)) & -alignment));
3970 char *pos = 3970 char *pos =
3971 ((size_t) (br - (char *) (p)) >= 3971 ((size_t) (br - (char *) (p)) >=
3972 MIN_CHUNK_SIZE) ? br : br + alignment; 3972 MIN_CHUNK_SIZE) ? br : br + alignment;
3973 mchunkptr newp = (mchunkptr) pos; 3973 mchunkptr newp = (mchunkptr) pos;
3974 size_t leadsize = pos - (char *) (p); 3974 size_t leadsize = pos - (char *) (p);
5232 structure of old version, but most details differ.) 5232 structure of old version, but most details differ.)
5233 5233
5234 */ 5234 */
5235 5235
5236 #endif /* !HAVE_MALLOC */ 5236 #endif /* !HAVE_MALLOC */
5237
5237 /* vi: set ts=4 sw=4 expandtab: */ 5238 /* vi: set ts=4 sw=4 expandtab: */