Ejemplo n.º 1
0
/**
 * Deallocate space in memory
 * 
 * A block of memory previously allocated using a call to malloc(),
 * calloc() or realloc() is deallocated, making it available again for
 * further allocations.
 *
 * Notice that this function leaves the value of ptr unchanged, hence
 * it still points to the same (now invalid) location, and not to the
 * null pointer.
 *
 * @param ptr
 *    Pointer to a memory block previously allocated with malloc(),
 *    calloc() or realloc() to be deallocated.  If a null pointer is
 *    passed as argument, no action occurs.
 */
void free(void *ptr)
{
	// "If a null pointer is passed as argument, no action occurs."
	if (!ptr)
		return;

	void* block_ptr = ptr - sizeof(mem_dic);
	if ( MDIC(block_ptr)->occupy==false )
	{
		D( printf("error in free(): the pos in %ld is not used\n",block_ptr - heap_ptr) );
	}

	MDIC(block_ptr)->occupy = false;
	free_list_add(block_ptr, size2order( MDIC(block_ptr)->size ));

	void* merge_ptr = NULL;
	void* buddy_ptr = NULL;

	while( (merge_ptr = buddy_exist_not_occupied(block_ptr)) != NULL )
	{
		// delete from free_list block_ptr and its buddy
		buddy_ptr = buddy_address(block_ptr);
		free_list_delete(block_ptr, size2order( MDIC(block_ptr)->size ));
		free_list_delete(buddy_ptr, size2order( MDIC(buddy_ptr)->size ));

		// merge buddy_ptr and block_ptr
		MDIC(merge_ptr)->size *= 2;
		MDIC(merge_ptr)->occupy = false;
		free_list_add(merge_ptr,size2order( MDIC(merge_ptr)->size ));

		block_ptr = merge_ptr;
	}
	
	return;
}
Ejemplo n.º 2
0
void* split_block(void* block_ptr, size_t small_block_size)
{
	/* error check */
	if(MDIC(block_ptr) -> size < small_block_size)
	{
		D(
		printf("split_block: the oritinal size: %zu is smaller than the splitted size %zu\n",
			MDIC(block_ptr) -> size, small_block_size)
		);
		return NULL;
	}
	else if (MDIC(block_ptr) -> size == small_block_size)
		return block_ptr;

	if (!divided2(small_block_size,MDIC(block_ptr)->size))
	{
		D(
		printf("Error in split_block(): the original %zu can not be divided by %zu \n", 
			 MDIC(block_ptr)->size, small_block_size)
		);
		return NULL;
	}
	/* end error check */
	// if occupied, it is possbile that the block is being realloc.
	if(MDIC(block_ptr) -> occupy){
		L(printf("split_block(): the block to be splitted is occupied, realloc is running\n"));
	}

	void* front_ptr = block_ptr;
	void* back_ptr = NULL;
	while(MDIC(front_ptr)->size > small_block_size)
	{
		if(!MDIC(front_ptr)->occupy)
			free_list_delete(front_ptr,size2order(MDIC(front_ptr)->size));
		MDIC(front_ptr)->size /= 2;
		if(!MDIC(front_ptr)->occupy)
			free_list_add(front_ptr,size2order(MDIC(front_ptr)->size));

		back_ptr = front_ptr + MDIC(front_ptr)->size;
		MDIC(back_ptr)->size = MDIC(front_ptr)->size;
		MDIC(back_ptr)->area_head = MDIC(front_ptr)->area_head;
		MDIC(back_ptr)->area_end = MDIC(front_ptr)->area_end;
		MDIC(back_ptr)->occupy = false;
		free_list_add(back_ptr,size2order(MDIC(back_ptr)->size));
	}

	if (MDIC(front_ptr)->size != small_block_size)
	{
		D( printf("Fatal Error in split_block(): size is splited too small!\n") );
		exit(0);
	}
	else return front_ptr;
}
Ejemplo n.º 3
0
void* allocate_new_space(size_t size)
{
	void* extend_heap_ptr = NULL;
	size_t one_time_alloc = find_one_time_sbrk_size(size);
	 

	extend_heap_ptr = sbrk(one_time_alloc);
	MDIC(extend_heap_ptr) -> size = one_time_alloc;
	MDIC(extend_heap_ptr) -> occupy = false;
	free_list_add(extend_heap_ptr,size2order(MDIC(extend_heap_ptr)->size));
	MDIC(extend_heap_ptr) -> area_head = extend_heap_ptr;
	MDIC(extend_heap_ptr) -> area_end = extend_heap_ptr + one_time_alloc;

	total_size += one_time_alloc;

	if(heap_ptr == NULL) heap_ptr = extend_heap_ptr;

	L(printf("allocate_new_space(): sbrked %zu bytes at loc %zu, total_size: %zu\n",
		MDIC(extend_heap_ptr) -> size, (size_t)(extend_heap_ptr - heap_ptr) ,total_size));

	if (MDIC(extend_heap_ptr) -> size >= size)
	{
		/* Split if necessary, then return */
		if(size > MDIC(extend_heap_ptr)->size / 2) return extend_heap_ptr;
		return split_block(extend_heap_ptr,size);
	}
	else
	{
		D( printf("new area %zu is smaller than the size %zu needed\n",one_time_alloc,size ) );
		exit(0);
	}
}
Ejemplo n.º 4
0
void
fusb_ephandle::reap_complete_writes ()
{
  // take a look at the completed list and xfer to free list after
  // checking for errors.

  libusb_transfer *lut;

  while ((lut = completed_list_get ()) != 0) {

    // Check for any errors or short writes that were reporetd in the transfer.
    // libusb1 sets status, actual_length.

    if (lut->status != LIBUSB_TRANSFER_COMPLETED) {
      LOG(ERR) << "Invalid LUT status " << lut->status;
      check_health (false);
    }
    else if (lut->actual_length != lut->length){
      LOG(ERR) << "Improper write of " << lut->actual_length;
      check_health (false);
    }
    else check_health (true);

    free_list_add (lut);
  }
}
Ejemplo n.º 5
0
bool
fusb_ephandle::submit_lut (libusb_transfer *lut)
{
  if (!d_devhandle->_submit_lut (lut)) {
    LOG(ERR) << "USB submission failed";
    free_list_add (lut);
    check_health (false);
    return false;
  }
  return true;
}
Ejemplo n.º 6
0
Archivo: page.c Proyecto: softirq/libmm
static int sep_list_from_area(const uint32_t prio, uint32_t order)
{
    struct page *page = NULL;
    free_area_t *queue = NULL;
    struct list_head *head, *item = NULL;

    queue = buddy_list.free_area + order;

    while(queue && order < NR_MEM_LISTS)
    {
        if(queue->nr_free_pages > 0) 
        {
            head = &(queue->lists[prio]);
            if(list_empty_careful(head))
            {
                ++order;
                ++queue;
            }
            else
            {
                /*DD("sep list order = %d. prio = %d", order, prio);*/
                if(free_list_del(head, order, &item) != 0)
                {
                    return -1;
                }

                page = list_entry(item, struct page, list);
                --order;
                --(page->order);
                free_list_add(page, prio, order);
                page += (uint32_t)pow(2,order);
                free_list_add(page, prio,order);

                return order;
            }
        }

        ++order;
        ++queue;
    }
Ejemplo n.º 7
0
bool
fusb_ephandle::reload_read_buffer ()
{
  assert (d_read_buffer >= d_read_buffer_end);

  libusb_transfer *lut;

  if (d_read_work_in_progress) {
    lut = d_read_work_in_progress;
    d_read_work_in_progress = 0;
    d_read_buffer = 0;
    d_read_buffer_end = 0;
    lut->actual_length = 0;
    if (!submit_lut (lut)) {
      LOG(ERR) << "Improper LUT submission";
      return false;
    }
  }

  while (1) {

    while ((lut = completed_list_get ()) == 0 )
      if (!d_devhandle->_reap(true))
        {
 	  LOG(ERR) << "No libusb events";
          check_health (false);
          return false;
        }
    if (lut->status != LIBUSB_TRANSFER_COMPLETED) {
      LOG(ERR) << "Improper read status " << lut->status;
      lut->actual_length = 0;
      free_list_add (lut);
      check_health (false);
      return false;
    }

    d_read_work_in_progress = lut;
    d_read_buffer = (unsigned char *) lut->buffer;
    d_read_buffer_end = d_read_buffer + lut->actual_length;

    check_health (true);
    return true;
  }
}
Ejemplo n.º 8
0
/*
 * delete_pool() - Delete a memory pool. Helper function common to all
 *                         memory pool types.
 *
 * Parameters:
 *    mgr:     INPUT The handle to the pools manager
 *    pool:    INPUT The handle of the  pool to delete
 *
 * Returns:
 *    BCME_OK   Pool deleted ok.
 *    other     Pool not deleted due to indicated error.
 *
 */
static int BCMATTACHFN(delete_pool)(bcm_mpm_mgr_h mgr, bcm_mp_pool_h *poolp)
{
	bcm_mp_pool_h      pool;

	/* Check parameters */
	if ((mgr == NULL) || (poolp == NULL) || (*poolp == NULL)) {
		return (BCME_BADARG);
	}


	/* Verify that all memory objects have been freed back to the pool. */
	pool = *poolp;
	if (pool->num_alloc != 0) {
		MPOOL_ERROR(("ERROR: %s: memory leak - nobj(%d) num_alloc(%d)\n",
		       __FUNCTION__, pool->u.p.nobj, pool->num_alloc));

		return (BCME_BUSY);
	}


	/* For pool manager allocated memory, free the contiguous block of memory objects. */
	if ((BCM_MP_GET_POOL_TYPE(pool) == BCM_MP_TYPE_PREALLOC) &&
	    (pool->u.p.malloc_memstart != NULL)) {
		MFREE(mgr->osh, pool->u.p.malloc_memstart,
		      pool->u.p.nobj * pool->u.p.padded_objsz);
	}


	/* Mark the memory pool as unused. */
	BCM_MP_CLEAR_IN_USE(pool);


	/* Add object memory back to pool. */
	free_list_add(&mgr->free_pools, (bcm_mp_free_list_t *) pool);

	mgr->npools--;


	*poolp = NULL;
	return (BCME_OK);
}
Ejemplo n.º 9
0
/*
 * bcm_mp_free() - Free a memory pool object.
 *
 * Parameters:
 *    pool:  INPUT   The handle to the pool.
 *    objp:  INPUT   A pointer to the object to free.
 *
 * Returns:
 *    BCME_OK   Ok
 *    other     Error during free.
 *
 */
int bcm_mp_free(bcm_mp_pool_h pool, void *objp)
{
	/* Check parameters */
	ASSERT(pool != NULL);

	if (objp == NULL) {
		return (BCME_BADARG);
	}

	if (BCM_MP_GET_POOL_TYPE(pool) == BCM_MP_TYPE_PREALLOC) {
		/* Add object memory back to pool. */
		free_list_add(&pool->u.p.free_objp, (bcm_mp_free_list_t *) objp);
	}
	else {
		/* Heap allocation memory pool. */
		MFREE(pool->u.h.osh, objp, pool->objsz);
	}

	/* Update pool state. */
	pool->num_alloc--;

	return (BCME_OK);
}
Ejemplo n.º 10
0
/*
 * create_pool() - Create a new pool for fixed size objects. Helper function
 *                         common to all memory pool types.
 *
 * Parameters:
 *    mgr:           INPUT  The handle to the pool manager
 *    obj_sz:        INPUT  Size of objects that will be allocated by the new pool.
 *                          This is the size requested by the user. The actual size
 *                          of the memory object may be padded.
 *                          Must be > 0 for heap pools. Must be >= sizeof(void *) for
 *                          Prealloc pools.
 *    padded_obj_sz: INPUT  Size of objects that will be allocated by the new pool.
 *                          This is the actual size of memory objects. It is 'obj_sz'
 *                          plus optional padding required for alignment.
 *                          Must be > 0 for heap pools. Must be >= sizeof(void *) for
 *                          Prealloc pools.
 *    nobj:          INPUT  Maximum number of concurrently existing objects to support.
 *                          Must be specified for Prealloc pool. Ignored for heap pools.
 *    memstart       INPUT  Pointer to the memory to use, or NULL to malloc().
 *                          Ignored for heap pools.
 *    memsize        INPUT  Number of bytes referenced from memstart (for error checking).
 *                          Must be 0 if 'memstart' is NULL. Ignored for heap pools.
 *    poolname       INPUT  For instrumentation, the name of the pool
 *    type           INPUT  Pool type - BCM_MP_TYPE_xxx.
 *    newp:          OUTPUT The handle for the new pool, if creation is successful
 *
 * Returns:
 *    BCME_OK   Pool created ok.
 *    other     Pool not created due to indicated error. newpoolp set to NULL.
 *
 *
 */
static int BCMATTACHFN(create_pool)(bcm_mpm_mgr_h mgr,
                                    unsigned int obj_sz,
                                    unsigned int padded_obj_sz,
                                    int nobj,
                                    void *memstart,
                                    char poolname[BCM_MP_NAMELEN],
                                    uint16 type,
                                    bcm_mp_pool_h *newp)
{
	bcm_mp_pool_t      *mem_pool = NULL;
	void               *malloc_memstart = NULL;

	/* Check parameters */
	if ((mgr == NULL) ||
	    (newp == NULL) ||
	    (obj_sz == 0) ||
	    (padded_obj_sz == 0) ||
	    (poolname == NULL) ||
	    (poolname[0] == '\0')) {
		return (BCME_BADARG);
	}

	/* Allocate memory object from pool. */
	mem_pool = (bcm_mp_pool_t *) free_list_remove(&mgr->free_pools);
	if (mem_pool == NULL) {
		return (BCME_NOMEM);
	}

	/* For pool manager allocated memory, malloc the contiguous memory
	 * block of objects.
	 */
	if ((type == BCM_MP_TYPE_PREALLOC) && (memstart == NULL)) {
		memstart = MALLOC(mgr->osh, padded_obj_sz * nobj);
		if (memstart == NULL) {
			free_list_add(&mgr->free_pools,
			                     (bcm_mp_free_list_t *) mem_pool);
			return (BCME_NOMEM);
		}
		malloc_memstart = memstart;
	}

	/* Init memory pool object (common). */
	memset(mem_pool, 0, sizeof(*mem_pool));
	mem_pool->objsz = obj_sz;
	BCM_MP_SET_POOL_TYPE(mem_pool, type);
	BCM_MP_SET_IN_USE(mem_pool);
	strncpy(mem_pool->name, poolname, sizeof(mem_pool->name));
	mem_pool->name[sizeof(mem_pool->name)-1] = '\0';


	if (type == BCM_MP_TYPE_PREALLOC) {
		/* Init memory pool object (Prealloc specific). */
		mem_pool->u.p.nobj            = (uint16) nobj;
		mem_pool->u.p.malloc_memstart = malloc_memstart;
		mem_pool->u.p.padded_objsz    = padded_obj_sz;

		/* Chain all the memory objects onto the pool's free list. */
		free_list_init(&mem_pool->u.p.free_objp, memstart, padded_obj_sz, nobj);
	}
	else {
		/* Init memory pool object (Heap specific). */
		mem_pool->u.h.osh = mgr->osh;
	}

	mgr->npools++;
	*newp = mem_pool;
	return (BCME_OK);
}