void *sal_malloc(u_int32_t n) { byte *allocated; //iterate through to get to the first free space free_header_t *first = (free_header_t *) memory+free_list_ptr; free_header_t *curr = first; int circle = TRUE; printHeader(curr); while (circle)) { //found a chunk that is bigger than we need if (n <= HEADER_SIZE+curr->size) { //check if we can break down chunks if (n <= HEADER_SIZE+(curr->size)/2) { //break chunk, then salloc again (and hence find that chunk) //TODO this is a bad way i think... splitChunk(curr); allocated = sal_malloc(u_int32_t n/2) //if cannot splt, then five them this bit of memory } else { allocated = (byte *)curr + HEADER_SIZE; } break; //else if we get back around the full circle, nothing is big enough so error } else if (curr == first) {
void* VG_(arena_malloc) ( ArenaId aid, Int req_pszB ) { Int req_pszW, req_bszW, frag_bszW, b_bszW, lno; Superblock* new_sb; Word* b; Arena* a; void* v; VGP_PUSHCC(VgpMalloc); ensure_mm_init(); a = arenaId_to_ArenaP(aid); vg_assert(req_pszB >= 0); vg_assert(req_pszB < 0x7FFFFFF0); req_pszW = req_pszB_to_req_pszW(req_pszB); /* Keep gcc -O happy: */ b = NULL; /* Start searching at this list. */ lno = pszW_to_listNo(req_pszW); /* This loop finds a list which has a block big enough, or sets req_listno to N_LISTS if no such block exists. */ while (True) { if (lno == VG_N_MALLOC_LISTS) break; /* If this list is empty, try the next one. */ if (a->freelist[lno] == NULL) { lno++; continue; } /* Scan a->list[lno] to find a big-enough chunk. */ b = a->freelist[lno]; b_bszW = mk_plain_bszW(get_bszW_lo(b)); while (True) { if (bszW_to_pszW(a, b_bszW) >= req_pszW) break; b = get_next_p(b); b_bszW = mk_plain_bszW(get_bszW_lo(b)); if (b == a->freelist[lno]) break; } if (bszW_to_pszW(a, b_bszW) >= req_pszW) break; /* No luck? Try a larger list. */ lno++; } /* Either lno < VG_N_MALLOC_LISTS and b points to the selected block, or lno == VG_N_MALLOC_LISTS, and we have to allocate a new superblock. */ if (lno == VG_N_MALLOC_LISTS) { req_bszW = pszW_to_bszW(a, req_pszW); new_sb = newSuperblock(a, req_bszW); if (NULL == new_sb) { // Should only fail if for client, otherwise, should have aborted // already. vg_assert(VG_AR_CLIENT == aid); return NULL; } new_sb->next = a->sblocks; a->sblocks = new_sb; b = &(new_sb->payload_words[0]); lno = pszW_to_listNo(bszW_to_pszW(a, new_sb->n_payload_words)); mkFreeBlock ( a, b, new_sb->n_payload_words, lno); } /* Ok, we can allocate from b, which lives in list req_listno. */ vg_assert(b != NULL); vg_assert(lno >= 0 && lno < VG_N_MALLOC_LISTS); vg_assert(a->freelist[lno] != NULL); b_bszW = mk_plain_bszW(get_bszW_lo(b)); req_bszW = pszW_to_bszW(a, req_pszW); /* req_bszW is the size of the block we are after. b_bszW is the size of what we've actually got. */ vg_assert(b_bszW >= req_bszW); /* Could we split this block and still get a useful fragment? Where "useful" means that the payload size of the frag is at least one word. */ frag_bszW = b_bszW - req_bszW; if (frag_bszW > overhead_szW(a)) { splitChunk(a, b, lno, req_bszW); } else { /* No, mark as in use and use as-is. */ unlinkBlock(a, b, lno); /* set_bszW_lo(b, mk_inuse_bszW(b_bszW)); set_bszW_hi(b, mk_inuse_bszW(b_bszW)); */ mkInuseBlock(a, b, b_bszW); } vg_assert(req_bszW <= mk_plain_bszW(get_bszW_lo(b))); a->bytes_on_loan += sizeof(Word) * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(b))); if (a->bytes_on_loan > a->bytes_on_loan_max) a->bytes_on_loan_max = a->bytes_on_loan; # ifdef DEBUG_MALLOC mallocSanityCheckArena(aid); # endif VGP_POPCC(VgpMalloc); v = first_to_payload(a, b); vg_assert( (((UInt)v) & 7) == 0 ); return v; }