Mercurial > sdl-ios-xcode
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: */ |