Пример #1
0
int main(int argc, char *argv[])
{
//	printf("sizeof(Busy_Header) == %zu\n", sizeof(Busy_Header));
//	printf("sizeof(Free_Header) == %zu\n", sizeof(Free_Header));
	for (int i=0; i<=MINSIZE-sizeof(Busy_Header); i++) {
//		fprintf(stderr, "request2size(%d) == %lu\n", i, request2size((size_t)i));
		assert(request2size((size_t) i) == MINSIZE );
	}
	if ( MINSIZE==16 )
	{
		static const int N = 9;
		static const size_t sizes[2*N] = {				// (request, adjusted size) pairs
			13, 24,
			14, 24,
			15, 24,
			16, 24,
			17, 24,
			18, 24,
			19, 24,
			20, 24,
			21, 32,
		};
		for (int i=0; i < 2*N; i += 2)
		{
//			fprintf(stderr, "request2size(%zu) == %lu\n", sizes[i], request2size(sizes[i]));
			assert(request2size(sizes[i]) == sizes[i+1]);
		}
	}
}
Пример #2
0
void bin_malloc_free_malloc() {  // test bin malloc and free
    void *p = malloc(99); // should split heap into two chunks
    assert_addr_not_equal(p, NULL);
    Free_Header *freelist = get_heap_freelist();
    Busy_Header *heap = get_heap_base();
    assert_addr_not_equal(freelist, heap);
    // check 1st chunk
    assert_equal(p, heap);
    assert_equal(chunksize(p), request2size(99));
    // check 2nd chunk
    assert_equal(freelist->size, HEAP_SIZE-request2size(99));
    assert_addr_equal(freelist->next, NULL);

    Free_Header *freelist1 = get_bin_freelist(99);// freelist of bin should be NULL
    free(p);                                                       // free to bin
    Free_Header *freelist2 = get_bin_freelist(99);// freelist of bin should be have one element p
    assert_addr_not_equal(freelist1,freelist2);
    void *p1 = malloc(99);                                        // this malloc should be from bin
    assert_addr_not_equal(p1, NULL);
    Free_Header *freelist3 = get_bin_freelist(99); // freelist of bin should be NULL
    assert_addr_equal(freelist3,NULL);

    free(p1);
    Free_Header *freelist4 = get_bin_freelist(99); // freelist should have one element p1
    assert_addr_equal(freelist2,freelist4);
}
Пример #3
0
//five consecutive chunks allocated
void  five_malloc() {
    void *p = get_heap_base();
    Busy_Header *b_1 = malloc(100);
    assert_addr_equal(b_1, p);   //b_1 is at the start of heap
    assert_equal(chunksize(b_1), request2size(100));
    Busy_Header *b_2 = malloc(200);
    Busy_Header *b1_next = find_next(b_1);
    assert_addr_equal(b1_next,b_2);     //b_2 is after b_1
    assert_equal(chunksize(b_2), request2size(200));
    Busy_Header *b_3 = malloc(300);
    Busy_Header *b2_next = find_next(b_2);
    assert_addr_equal(find_next(b_2),b_3);     //b_3 is after b_2
    assert_equal(chunksize(b_3), request2size(300));
    Busy_Header *b_4 = malloc(400);
    Busy_Header *b3_next = find_next(b_3);
    assert_addr_equal(find_next(b_3),b_4);     //b_4 is after b_3
    assert_equal(chunksize(b_4), request2size(400));
    Busy_Header *b_5 = malloc(500);
    Busy_Header *b4_next = find_next(b_4);
    assert_addr_equal(find_next(b_4),b_5);     //b_5 is after b_4
    assert_equal(chunksize(b_5), request2size(500));

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 5);
    assert_equal(info.free, 1);
    assert_equal(info.free_size, HEAP_SIZE - info.busy_size);
}
Пример #4
0
void one_malloc() {
    void *p = malloc(100);
    assert_addr_not_equal(p, NULL);
    Free_Header *freelist = get_heap_freelist();
    Busy_Header *heap = get_heap_base();
    assert_addr_not_equal(freelist, heap);
    // check 1st chunk
    assert_equal(p, heap);
    assert_equal(chunksize(p), request2size(100));
    // check 2nd chunk
    assert_equal(freelist->size, HEAP_SIZE-request2size(100));
    assert_addr_equal(freelist->next, NULL);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 1);
    assert_equal(info.busy_size, request2size(100));
    assert_equal(info.free, 1);
    assert_equal(info.free_size, HEAP_SIZE - request2size(100));
}
Пример #5
0
//skip first free chunk, which is not big enough
void search_along_list() {
    printf("after allocation:\n");
    Busy_Header* b[4];
    for(int i = 0; i < 4; i++){
        b[i] = malloc(450);
        printf("b[%d]: %p\n", i, b[i]);
    }
    assert_equal(b[0]->size & SIZEMASK, request2size(450));
    assert_equal(b[1]->size & SIZEMASK, request2size(450));
    assert_equal(b[2]->size & SIZEMASK, request2size(450));
    assert_equal(b[3]->size & SIZEMASK, request2size(450));
    Free_Header* f4 = find_next(b[3]);
    printf("head: %p\n", f4);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 4);
    assert_equal(info.free, 1);
    assert_equal(info.busy_size, 1824);
    assert_equal(info.free_size, 176);
    assert_addr_equal(get_freelist(), f4);
    assert_addr_equal(get_freelist()->next, NULL);
    assert_addr_equal(get_freelist()->prev, NULL);

    //after malloc, free b3, b0
    free(b[3]);
    free(b[0]);
    Busy_Header *skip = malloc(600);

    printf("after malloc(600)\n");
    Free_Header *head = get_freelist();
    print_both_ways(head);

    info = verify_heap();
    assert_equal(info.busy, 3);
    assert_equal(info.free, 2);
    assert_equal(info.busy_size + info.free_size, get_heap_info().heap_size);
}
Пример #6
0
void malloc_large_size_then_free() {
    Free_Header *freelist = get_heap_freelist();//free list before malloc
    void *p = malloc(2048);
    assert_addr_not_equal(p, NULL);
    assert_equal(chunksize(p), request2size(2048));
    Free_Header *freelist1 = get_heap_freelist(); // free list after malloc
    Busy_Header *heap = get_heap_base();
    assert_addr_equal(p,heap);
    assert_addr_not_equal(heap,freelist1);
    free(p);
    Busy_Header *heap1 = get_heap_base();
    Free_Header *freelist2 = get_heap_freelist(); // free list after free,should back to status before malloc
    assert_addr_equal(freelist,freelist2);
    assert_addr_equal(heap1,freelist2);
}
Пример #7
0
void* realloc(void* mem, size_t       bytes)
{
  if (mem == 0) 
    return malloc(bytes);
  else
  {
    size_t       nb      = request2size(bytes);
    mchunkptr    p       = mem2chunk(mem);
    size_t       oldsize = p->size;
    int          room;
    mchunkptr    nxt;

    UPDATE_STATS((++n_reallocs, requested_mem += bytes-oldsize));
    
    /* try to expand (even if already big enough), to clean up chunk */

    while (!inuse(nxt = next_chunk(p)))
    {
      UPDATE_STATS ((malloced_mem += nxt->size, ++n_consol));
      unlink(nxt);
      set_size(p, p->size + nxt->size);
    }

    room = p->size - nb;
    if (room >= 0)
    {
      split(p, nb);
      UPDATE_STATS(malloced_mem -= room);
      return chunk2mem(p);
    }
    else /* do the obvious */
    {
      void* newmem;
      set_inuse(p);    /* don't let malloc consolidate us yet! */
      newmem = malloc(nb);
      bcopy(mem, newmem, oldsize - SIZE_SZ);
      free(mem);
      UPDATE_STATS(++n_reallocs_with_copy);
      return newmem;
    }
  }
}
Пример #8
0
void two_malloc() {
    one_malloc();
    void *p0 = get_heap_base();
    Free_Header *freelist0 = get_heap_freelist();
    Busy_Header *p = malloc(200);
    assert_addr_not_equal(p, NULL);
    // check 2nd alloc chunk
    assert_equal(p, freelist0); // should return previous free chunk
    assert_equal(chunksize(p), request2size(200));
    // check remaining free chunk
    Free_Header *freelist1 = get_heap_freelist();
    assert_addr_not_equal(freelist0, freelist1);
    assert_addr_not_equal(freelist0, get_heap_base());
    assert_equal(chunksize(freelist1), HEAP_SIZE-request2size(100)-request2size(200));
    assert_equal(chunksize(p0)+chunksize(p)+chunksize(freelist1), HEAP_SIZE);
    assert_addr_equal(freelist1->next, NULL);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 2);
    assert_equal(info.busy_size, request2size(100) + request2size(200));
    assert_equal(info.free, 1);
    assert_equal(info.free_size, HEAP_SIZE - request2size(100) - request2size(200));
}
Пример #9
0
void* malloc(size_t       bytes)
{
  size_t       nb  = request2size(bytes);  /* padded request size */
  mbinptr      b   = size2bin(nb);         /* corresponding bin */
  mchunkptr    hd  = &(b->hd);             /* head of its list */
  mchunkptr    p   = hd->fd;               /* chunk traverser */

  UPDATE_STATS((requested_mem+=bytes, ++n_malloc_bins));

  /* Try a (near) exact match in own bin */
  /* clean out unusable but consolidatable chunks in bin while traversing */

  while (p != hd)
  {
    UPDATE_STATS(++n_malloc_chunks);
    if (p->size >= nb)
      goto found;
    else    /* try to consolidate; same code as malloc_find_space */
    {
      mchunkptr nextp = p->fd;       /* save, in case of relinks */
      int consolidated = 0;          /* only unlink/relink if consolidated */
      
      mchunkptr t;

      while (!inuse(t = prev_chunk(p))) /* consolidate backward */
      {
        if (!consolidated) { consolidated = 1; unlink(p); }
        if (t == nextp) nextp = t->fd;
        unlink(t);
        set_size(t, t->size + p->size);
        p = t;
        UPDATE_STATS (++n_consol);
      }
      
      while (!inuse(t = next_chunk(p))) /* consolidate forward */
      {
        if (!consolidated) { consolidated = 1; unlink(p); }
        if (t == nextp) nextp = t->fd;
        unlink(t);
        set_size(p, p->size + t->size);
        UPDATE_STATS (++n_consol);
      }
      
      if (consolidated)
      {
        if (p->size >= nb)
        {
          /* make it safe to unlink again below */
          UPDATE_STATS(++n_avail);
          p->fd = p->bk = p;
          goto found;
        }
        else
          consollink(p);
      }

      p = nextp;

    }
  }

  b->dirty = 0; /* true if got here */

  /*  Scan bigger bins for a victim */

  while (++b <= malloc_maxbin)
  {
    UPDATE_STATS(++n_malloc_bins);
    if ((p = b->hd.bk) != &(b->hd))    /* no need to check size */
      goto found;
  }

  /* Consolidate or sbrk */

  p = malloc_find_space(nb);

  if (p == 0) return 0; /* allocation failure */

 found:   /* Use what we found */

  unlink(p);
  split(p, nb); 
  UPDATE_STATS(do_malloc_stats(p));
  return chunk2mem(p);
}
Пример #10
0
void* memalign(size_t       alignment, size_t       bytes)
{
  mchunkptr p;
  size_t       nb = request2size(bytes);

  /* find an alignment that both we and the user can live with: */
  /* least common multiple guarantees mutual happiness */
  size_t       align = lcm(alignment, MALLOC_MIN_OVERHEAD);
  size_t       mask = align - 1;

  /* call malloc with worst case padding to hit alignment; */
  /* we will give back extra */

  size_t       req = nb + align + MINSIZE;
  void* m = malloc(req);

  if (m == 0) return m;

  p = mem2chunk(m);

  /* keep statistics on track */

  UPDATE_STATS(--n_mallocs);
  UPDATE_STATS(malloced_mem -= p->size);
  UPDATE_STATS(requested_mem -= req);
  UPDATE_STATS(requested_mem += bytes);

  if (((int)(m) & (mask)) != 0) /* misaligned */
  {

    /* find an aligned spot inside chunk */

    mchunkptr ap = (mchunkptr)(( ((int)(m) + mask) & -align) - SIZE_SZ);

    size_t       gap = (size_t      )(ap) - (size_t      )(p);
    size_t       room;

    /* we need to give back leading space in a chunk of at least MINSIZE */

    if (gap < MINSIZE)
    {
      /* This works since align >= MINSIZE */
      /* and we've malloc'd enough total room */

      ap = (mchunkptr)( (int)(ap) + align );
      gap += align;    
    }

    if (gap + nb > p->size) /* can't happen unless chunk sizes corrupted */
      malloc_user_error();

    room = p->size - gap;

    /* give back leader */
    set_size(p, gap);
    consollink(p);

    /* use the rest */
    p = ap;
    set_size(p, room);
  }

  /* also give back spare room at the end */

  split(p, nb); 
  UPDATE_STATS(do_malloc_stats(p));
  return chunk2mem(p);

}
Пример #11
0
//split chunk
void split_chunk(){
    printf("after allocation:\n");
    Busy_Header* b[4];
    for(int i = 0; i < 4; i++){
        b[i] = malloc(450);
        printf("b[%d]: %p\n", i, b[i]);
    }
    assert_equal(b[0]->size & SIZEMASK, request2size(450));
    assert_equal(b[1]->size & SIZEMASK, request2size(450));
    assert_equal(b[2]->size & SIZEMASK, request2size(450));
    assert_equal(b[3]->size & SIZEMASK, request2size(450));
    Free_Header* f4 = find_next(b[3]);
    printf("head: %p\n", f4);

    Heap_Info info = verify_heap();
    assert_equal(info.busy, 4);
    assert_equal(info.free, 1);
    assert_equal(info.busy_size, 1824);
    assert_equal(info.free_size, 176);
    assert_addr_equal(get_freelist(), f4);
    assert_addr_equal(get_freelist()->next, NULL);
    assert_addr_equal(get_freelist()->prev, NULL);

    free(b[2]);

    info = verify_heap();
    assert_equal(info.busy, 3);
    assert_equal(info.free, 2);
    assert_equal(info.busy_size, 1368);
    assert_equal(info.free_size, 632);
    assert_addr_equal(get_freelist(), b[2]);
    assert_addr_equal(get_freelist()->next, f4);
    assert_addr_equal(get_freelist()->next->next, NULL);
    assert_addr_equal(f4->prev, b[2]);
    assert_addr_equal(f4->prev->prev, NULL);
    printf("after free b[2]\n");
    Free_Header *head = get_freelist();
    print_both_ways(head);


    free(b[0]);
    info = verify_heap();
    assert_equal(info.busy, 2);
    assert_equal(info.free, 3);
    assert_equal(info.busy_size, 912);
    assert_equal(info.free_size, 1088);
    assert_addr_equal(get_freelist(), b[0]);
    assert_addr_equal(get_freelist()->next, b[2]);
    assert_addr_equal(get_freelist()->next->next, f4);
    assert_addr_equal(get_freelist()->next->next->next, NULL);
    assert_addr_equal(f4->prev, b[2]);
    assert_addr_equal(f4->prev->prev, b[0]);
    assert_addr_equal(f4->prev->prev->prev, NULL);

    printf("after free b[0]\n");
    head = get_freelist();
    print_both_ways(head);

    Busy_Header *split = malloc(200);

    printf("after malloc(200)\n");
    head = get_freelist();
    print_both_ways(head);

    assert_addr_equal(split, get_heap_base());
    Free_Header *newhead = get_freelist();
    assert_addr_equal(find_next(split),newhead);
    assert_addr_equal(get_freelist(), find_next(split));
    assert_addr_equal(get_freelist()->next, b[2]);
    assert_addr_equal(get_freelist()->next->next, f4);
    assert_addr_equal(get_freelist()->next->next->next, NULL);
    assert_addr_equal(f4->prev, b[2]);
    assert_addr_equal(f4->prev->prev, newhead);
    assert_addr_equal(f4->prev->prev->prev, NULL);
    info = verify_heap();
    assert_equal(info.busy, 3);
    assert_equal(info.free, 3);
    assert_equal(info.busy_size + info.free_size, get_heap_info().heap_size); // out of heap*/
}