コード例 #1
0
ファイル: alloc.c プロジェクト: desphunter/shadow
static void *
alloc_do_malloc (struct Alloc *alloc, uint32_t size)
{
  if (size < (alloc->default_mmap_size - chunk_overhead ()))
    {
      uint8_t bucket = size_to_bucket (size);
      if (alloc->buckets[bucket] != 0)
        {
          // fast path.
          struct AllocAvailable *avail = alloc->buckets[bucket];
          MARK_DEFINED (avail, sizeof (void *));
          struct AllocAvailable *next = avail->next;
          MARK_UNDEFINED (avail, sizeof (void *));
          alloc->buckets[bucket] = next;
          REPORT_MALLOC (avail, size);
          return (uint8_t *) avail;
        }
      // slow path
      struct AllocAvailable *avail = (struct AllocAvailable *)
        alloc_brk (alloc, bucket_to_size (bucket));
      REPORT_MALLOC (avail, size);
      avail->next = 0;
      return (uint8_t *) avail;
    }
  else
    {
      alloc_chunk (alloc, size + chunk_overhead ());
      uint8_t *buffer = alloc_brk (alloc, size);
      REPORT_MALLOC (buffer, size);
      return buffer;
    }
}
コード例 #2
0
void* HeapImpl::AllocLocked(size_t size) {
  if (size > kMaxBucketAllocationSize) {
    return MapAlloc(size);
  }
  int bucket = size_to_bucket(size);
  if (free_chunks_[bucket].empty()) {
    Chunk *chunk = new Chunk(this, bucket);
    free_chunks_[bucket].insert(chunk->node_);
  }
  return free_chunks_[bucket].next()->data()->Alloc();
}
コード例 #3
0
ファイル: alloc.c プロジェクト: desphunter/shadow
static void
alloc_do_free (struct Alloc *alloc, uint8_t * buffer, uint32_t size)
{
  if (size < (alloc->default_mmap_size - chunk_overhead ()))
    {
      // return to bucket list.
      uint8_t bucket = size_to_bucket (size);
      struct AllocAvailable *avail = (struct AllocAvailable *) buffer;
      avail->next = alloc->buckets[bucket];
      alloc->buckets[bucket] = avail;
      REPORT_FREE (buffer);
    }
  else
    {
      struct AllocMmapChunk *tmp, *prev;
      for (tmp = alloc->chunks, prev = 0; tmp != 0;
           prev = tmp, tmp = tmp->next)
        {
          if (tmp->buffer == buffer && tmp->size == size)
            {
              if (prev == 0)
                {
                  alloc->chunks = tmp->next;
                }
              else
                {
                  prev->next = tmp->next;
                }
              REPORT_FREE (buffer);
              system_munmap (tmp->buffer, tmp->size);
              return;
            }
        }
      // this should never happen but it happens in case of a double-free
      REPORT_FREE (buffer);
    }
}
コード例 #4
0
ファイル: run-03-coalesce.c プロジェクト: Arkhont/samba
int main(int argc, char *argv[])
{
	tdb_off_t b_off, test;
	struct tdb_context *tdb;
	struct tdb_layout *layout;
	struct tdb_data data, key;
	tdb_len_t len;

	/* FIXME: Test TDB_CONVERT */
	/* FIXME: Test lock order fail. */

	plan_tests(42);
	data = tdb_mkdata("world", 5);
	key = tdb_mkdata("hello", 5);

	/* No coalescing can be done due to EOF */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	len = 1024;
	tdb_layout_add_free(layout, len, 0);
	tdb = tdb_layout_get(layout);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == len);

	/* Figure out which bucket free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(len));
	/* Lock and fail to coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[1].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, len, &test)
	    == 0);
	tdb_unlock_free_bucket(tdb, b_off);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == len);
	ok1(test == layout->elem[1].base.off);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	/* No coalescing can be done due to used record */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	tdb_layout_add_free(layout, 1024, 0);
	tdb_layout_add_used(layout, key, data, 6);
	tdb = tdb_layout_get(layout);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(tdb_check(tdb, NULL, NULL) == 0);

	/* Figure out which bucket free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
	/* Lock and fail to coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[1].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024, &test)
	    == 0);
	tdb_unlock_free_bucket(tdb, b_off);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(test == layout->elem[1].base.off);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	/* Coalescing can be done due to two free records, then EOF */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	tdb_layout_add_free(layout, 1024, 0);
	tdb_layout_add_free(layout, 2048, 0);
	tdb = tdb_layout_get(layout);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(free_record_length(tdb, layout->elem[2].base.off) == 2048);
	ok1(tdb_check(tdb, NULL, NULL) == 0);

	/* Figure out which bucket (first) free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
	/* Lock and coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[2].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024, &test)
	    == 1024 + sizeof(struct tdb_used_record) + 2048);
	/* Should tell us it's erased this one... */
	ok1(test == TDB_ERR_NOEXIST);
	ok1(tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0);
	ok1(free_record_length(tdb, layout->elem[1].base.off)
	    == 1024 + sizeof(struct tdb_used_record) + 2048);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	/* Coalescing can be done due to two free records, then data */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	tdb_layout_add_free(layout, 1024, 0);
	tdb_layout_add_free(layout, 512, 0);
	tdb_layout_add_used(layout, key, data, 6);
	tdb = tdb_layout_get(layout);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(free_record_length(tdb, layout->elem[2].base.off) == 512);
	ok1(tdb_check(tdb, NULL, NULL) == 0);

	/* Figure out which bucket free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
	/* Lock and coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[2].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024, &test)
	    == 1024 + sizeof(struct tdb_used_record) + 512);
	ok1(tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0);
	ok1(free_record_length(tdb, layout->elem[1].base.off)
	    == 1024 + sizeof(struct tdb_used_record) + 512);
	ok1(test == TDB_ERR_NOEXIST);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	/* Coalescing can be done due to three free records, then EOF */
	layout = new_tdb_layout("run-03-coalesce.tdb");
	tdb_layout_add_freetable(layout);
	tdb_layout_add_free(layout, 1024, 0);
	tdb_layout_add_free(layout, 512, 0);
	tdb_layout_add_free(layout, 256, 0);
	tdb = tdb_layout_get(layout);
	ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
	ok1(free_record_length(tdb, layout->elem[2].base.off) == 512);
	ok1(free_record_length(tdb, layout->elem[3].base.off) == 256);
	ok1(tdb_check(tdb, NULL, NULL) == 0);

	/* Figure out which bucket free entry is. */
	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
	/* Lock and coalesce. */
	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
	test = layout->elem[2].base.off;
	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024, &test)
	    == 1024 + sizeof(struct tdb_used_record) + 512
	    + sizeof(struct tdb_used_record) + 256);
	ok1(tdb->file->allrecord_lock.count == 0
	    && tdb->file->num_lockrecs == 0);
	ok1(free_record_length(tdb, layout->elem[1].base.off)
	    == 1024 + sizeof(struct tdb_used_record) + 512
	    + sizeof(struct tdb_used_record) + 256);
	ok1(tdb_check(tdb, NULL, NULL) == 0);
	tdb_close(tdb);
	tdb_layout_free(layout);

	ok1(tap_log_messages == 0);
	return exit_status();
}