Add a segment to hold a new noncontiguous region */
| 3975 | |
| 3976 | /* Add a segment to hold a new noncontiguous region */ |
| 3977 | static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { |
| 3978 | /* Determine locations and sizes of segment, fenceposts, old top */ |
| 3979 | char* old_top = (char*)m->top; |
| 3980 | msegmentptr oldsp = segment_holding(m, old_top); |
| 3981 | char* old_end = oldsp->base + oldsp->size; |
| 3982 | size_t ssize = pad_request(sizeof(struct malloc_segment)); |
| 3983 | char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); |
| 3984 | size_t offset = align_offset(chunk2mem(rawsp)); |
| 3985 | char* asp = rawsp + offset; |
| 3986 | char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; |
| 3987 | mchunkptr sp = (mchunkptr)csp; |
| 3988 | msegmentptr ss = (msegmentptr)(chunk2mem(sp)); |
| 3989 | mchunkptr tnext = chunk_plus_offset(sp, ssize); |
| 3990 | mchunkptr p = tnext; |
| 3991 | int nfences = 0; |
| 3992 | |
| 3993 | /* reset top to new space */ |
| 3994 | init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); |
| 3995 | |
| 3996 | /* Set up segment record */ |
| 3997 | assert(is_aligned(ss)); |
| 3998 | set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); |
| 3999 | *ss = m->seg; /* Push current record */ |
| 4000 | m->seg.base = tbase; |
| 4001 | m->seg.size = tsize; |
| 4002 | m->seg.sflags = mmapped; |
| 4003 | m->seg.next = ss; |
| 4004 | |
| 4005 | /* Insert trailing fenceposts */ |
| 4006 | for (;;) { |
| 4007 | mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); |
| 4008 | p->head = FENCEPOST_HEAD; |
| 4009 | ++nfences; |
| 4010 | if ((char*)(&(nextp->head)) < old_end) |
| 4011 | p = nextp; |
| 4012 | else |
| 4013 | break; |
| 4014 | } |
| 4015 | assert(nfences >= 2); |
| 4016 | |
| 4017 | /* Insert the rest of old top into a bin as an ordinary free chunk */ |
| 4018 | if (csp != old_top) { |
| 4019 | mchunkptr q = (mchunkptr)old_top; |
| 4020 | size_t psize = csp - old_top; |
| 4021 | mchunkptr tn = chunk_plus_offset(q, psize); |
| 4022 | set_free_with_pinuse(q, psize, tn); |
| 4023 | insert_chunk(m, q, psize); |
| 4024 | } |
| 4025 | |
| 4026 | check_top_chunk(m, m->top); |
| 4027 | } |
| 4028 | |
| 4029 | /* -------------------------- System allocation -------------------------- */ |
| 4030 |
no test coverage detected