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) {
Exemplo n.º 2
0
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;
}