Ejemplo n.º 1
0
//Coalesce free blocks if possible
static void *coalesce(void *bp) {
    size_t prev_alloc = block_free(block_prev(get_header(bp)));
    size_t next_alloc = block_free(block_next(get_header(bp)));
    size_t size = block_size(get_header(bp));

    if(prev_alloc && next_alloc)
	return bp;
    else if(prev_alloc && !next_alloc) {
	size += block_size(block_next(get_header(bp)));
	PUT(get_header(bp), PACK(size, 0));
	PUT(get_footer(bp), PACK(size, 0));
    }
    else if(!prev_alloc && next_alloc) {
	size += block_size(block_prev(get_header(bp)));
	PUT(get_header(prev_bp(bp)), PACK(size, 0));
	PUT(get_footer(bp), PACK(size, 0));
	bp = prev_bp(bp);
    }
    else if(!prev_alloc && !next_alloc) {
	size += block_size(block_next(get_header(bp))) + block_size(block_prev(get_header(bp)));
	PUT(get_header(prev_bp(bp)), PACK(size, 0));
	PUT(get_footer(next_bp(bp)), PACK(size, 0));
	bp = prev_bp(bp);
    }
    checkheap(1);
    return bp;
}
Ejemplo n.º 2
0
Archivo: heap.c Proyecto: MrXedac/riku
void expand_right(block_header_t* block)
{
	/* Get next block */
	block_footer_t* ftr = get_footer(block);
	block_header_t* next_hdr = (block_header_t*)((uintptr_t)ftr + sizeof(block_footer_t));
	
	if((uintptr_t)next_hdr >= (uintptr_t)(HEAP_END))
		return;
	
	if(next_hdr->magic != HEAP_HEADER_MAGIC)
		panic("Kernel heap corrupted", 0);
	
	/* If block is free, expand it */
	if(next_hdr->flags == 0)
	{
		block_footer_t* next_ftr = get_footer(next_hdr);
		next_ftr->header = block;
		block->size += next_hdr->size;
		
		block_footer_t* oui = get_footer(block);
		/* Routine checks. */
		if(oui->magic != HEAP_FOOTER_MAGIC)
			panic("Kernel heap corrupted during expand", 0);
		
		if(oui->header->magic != HEAP_HEADER_MAGIC)
			panic("Kernel heap corrupted during expand (2)", 0);
		
	}
}
Ejemplo n.º 3
0
Archivo: heap.c Proyecto: MrXedac/riku
uintptr_t* kalloc(uint32_t asize)
{
	uint32_t size;
	if(!kernel_heap)
		return 0;
	
	// Align allocation size on uint32_t
	uint8_t mod = asize % 4;
	if(mod > 0)
		size = asize + 4 - (uint32_t)mod;
	else
		size = asize;
	
	uint32_t required_size = size + 2*(sizeof(block_footer_t) + sizeof(block_header_t));
	
	block_header_t* blk = kernel_heap->heap_begin;
	
	// Iterate in our heap, and stops when we found a block, or there is no remaining blocks
	while((blk->size < required_size ||blk->flags == 1) && next_block(blk))
		blk = next_block(blk);

	// We found a block !
	if(blk->size >= required_size && blk->flags == 0 && blk->magic == HEAP_HEADER_MAGIC)
	{
		if(blk->size == required_size) {
			blk->flags = 1;
			return block_data_space(blk);
		} else {
			// Update block data
			block_footer_t* footer = get_footer(blk);
			uint32_t old_size = blk->size;
			blk->size = size + sizeof(block_header_t) + sizeof(block_footer_t);
			blk->flags = 1;
			
			// Create footer for block
			block_footer_t* new_footer = (block_footer_t*)((uintptr_t)blk + blk->size - sizeof(block_footer_t));
			new_footer->header = blk;
			new_footer->magic = HEAP_FOOTER_MAGIC;

			// Create new block next to it
			block_header_t* new_block = (block_header_t*)((uintptr_t)new_footer + sizeof(block_footer_t));
			new_block->magic = HEAP_HEADER_MAGIC;
			new_block->flags = 0;
			new_block->size = old_size - blk->size;
			
			// Update footer data to link to the newly created block
			footer->header = new_block;
			
			block_footer_t* check = get_footer(new_block);
			block_footer_t* check2 = get_footer(blk);
			return block_data_space(blk);
		}
	} else {
		panic("Kernel heap out of memory\n", 0);
		return 0;
	}
}
Ejemplo n.º 4
0
//Placing the allocated block in the free block
static void place(void *bp, size_t size) {
    size_t bsize = block_size(get_header(bp));
    if((bsize-size) >= (2*DSIZE)) {
	PUT(get_header(bp), PACK(size, 1));
	PUT(get_footer(bp), PACK(size, 1));
	bp = next_bp(bp);
	PUT(get_header(bp), PACK(bsize-size, 0));
	PUT(get_footer(bp), PACK(bsize-size, 0));
    }
    else {
	PUT(get_header(bp), PACK(bsize, 1));
	PUT(get_footer(bp), PACK(bsize, 1));
    }
}
Ejemplo n.º 5
0
//Extend the heap
static void *extend_heap(size_t words) {
    //Even number of words to maintain alignment
    size_t size = (words % 2) ? ((words + 1) * WSIZE) : (words * WSIZE);
    uint32_t *bp = mem_sbrk(size);
    if((long)bp == -1)
        return NULL;

    PUT(get_header(bp), PACK(size, 0));
    PUT(get_footer(bp), PACK(size, 0));
    PUT(block_next(get_header(bp)), PACK(0,1));

    return coalesce(bp);

}
Ejemplo n.º 6
0
Archivo: mm.c Proyecto: adel-qod/malloc
/// <summary> 
/// Does what you'd expect the malloc C standard library to do, check 
/// the requirements document for more details.
/// <summary>
/// <param name='size'> How many bytes the user needs to allocate </param>
/// <return> 
/// A properely aligned pointer to a block of memory whose size at
/// is at least equal to the size requested by the caller. 
/// </return>
void *my_malloc(size_t size)
{
    uint8_t *user_data; /* The pointer we will return to the user */
    uint8_t *new_block; /* Used to point to the block added by grow_heap */
    uint8_t *sliced_block; /* Used to point to the left-over of a block */
    struct block_header *header, *footer, *slice_header;
    int slice_list;/* Which list the slice belongs to */
    if(size <= 0)
        return NULL;
    size += sizeof(struct block_header) * 2; /* The header+footer */
    size = (size+7) & ~7;/* Align the size to 8-byte boundary */
    /* Identify which list to pick from */
    int list_num = pick_list(size);
    DEBUG_PRINT("size requested: %zd\n", size);
    DEBUG_PRINT("List picked: %d\n", list_num);
    user_data = extract_free_block(list_num, size);
    /* If no list had enough space */
    if(user_data == NULL) {
        if((new_block = grow_heap(size)) == NULL) {
            DEBUG_PRINT("%s\n", "-------------------------------------");
            errno = ENOMEM;
            return NULL;
        }
        add_free_block_to_list(list_num, new_block);
        user_data = extract_free_block(list_num, size);
    }
    assert(user_data != NULL);
    DEBUG_PRINT("%s\n", "Found a block!");
    /* If we can slice, add the left-over back to our lists */
    sliced_block = slice_block(user_data, size);
    if(sliced_block != NULL) {
        slice_header = (struct block_header *) sliced_block;
        slice_list = pick_list(slice_header->block_size);
        add_free_block_to_list(slice_list, sliced_block);
    }
    /* Mark the block as allocated */
    header = (struct block_header *) user_data;
    SET_ALLOC(header);
    footer = get_footer(user_data);
    SET_ALLOC(footer);
    user_data = user_data + 8;/* Now points past the header */
    DEBUG_PRINT("%s\n", "-------------------------------------");
    return user_data;
}
Ejemplo n.º 7
0
bool CMessage::validate() {
  if (m_header->canary != HEADER_CANARY) {
    log_error("Header Canary : expected 0x%08X, found 0x%08X", HEADER_CANARY, m_header->canary);
    return false;
  }
  message_footer* footer = get_footer();
  if (footer->canary != FOOTER_CANARY) {
    log_error("Footer Canary : expected 0x%08X, found 0x%08X", FOOTER_CANARY, footer->canary);
    return false;
  }
  if (m_header->size != footer->size) {
    log_error("Size : header 0x%08X, footer 0x%08X", m_header->size, footer->size);
    return false;
  }
  if (m_header->session != footer->session) {
    log_error("Session : header 0x%08X, footer 0x%08X", m_header->session, footer->session);
    return false;
  }
  return true;
}
Ejemplo n.º 8
0
Archivo: heap.c Proyecto: MrXedac/riku
void expand_left(block_header_t* block)
{
	/* Get previous block */
	block_footer_t* prev_ftr = (block_footer_t*)((uintptr_t)block - sizeof(block_footer_t));
	
	if((uintptr_t)prev_ftr <= (uintptr_t)(HEAP_BEGIN + sizeof(heap_t)))
		return;
	
	block_header_t* prev_hdr = prev_ftr->header;
	if(prev_hdr->magic != HEAP_HEADER_MAGIC)
		panic("Kernel heap corrupted", 0);
	
	/* If block is free, expand it */
	if(prev_hdr->flags == 0)
	{
		block_footer_t* ftr = get_footer(block);
		ftr->header = prev_hdr;
		prev_hdr->size += block->size;
		
	}
}
Ejemplo n.º 9
0
static int process_data(server *srv, connection *con, plugin_data *p,
			buffer *filename, chunkqueue *cq, off_t range_start)
{
	int err;
	size_t len;
	//off_t *abs_off;
	vhd_state_t *state;
	vhd_context_t *vhd;

	err = 0;
	state = &p->state;
	vhd = &state->vhd;
	//abs_off = range_start + con->range_offset;
	//abs_off = state->abs_off;
	DEBUGLOG("so", "Absolute Offset", state->abs_off);
	DEBUGLOG("sd", "Current Virtual Block = ", state->curr_virt_blk);
	if (state->curr_virt_blk != -1) {
		DEBUGLOG("s", "Process Block");
		err = process_block(srv, cq, state, &(state->abs_off));
		goto done;
	}

	if (state->abs_off < 0 + sizeof(vhd_footer_t)) {
		err = get_footer(srv, cq, state, &(state->abs_off));
		goto done;
	}

	if (((off_t)state->abs_off) < vhd->footer.data_offset + sizeof(vhd_header_t)) {
		err = get_header(srv, cq, state, &(state->abs_off));
		goto done;
	}

	if (((off_t)state->abs_off) < vhd->header.table_offset + state->bat_buf_size) {
		err = get_bat(srv, cq, state, &(state->abs_off));
		if (err)
			goto done;
		if (state->vhd_ready)
			err = prepare_for_write(srv, state, filename, state->abs_off);
		goto done;
	}

	if (state->blocks_written < state->blocks_allocated) {
		LOG("sdd", "BUG!", state->blocks_written,
				state->blocks_allocated);
		err = -EINVAL;
		goto done;
	}

	// TODO: we could actually validate the primary footer at the end
	len = chunkqueue_avail(cq);
	DEBUGLOG("sd", "Discarding the remainder", len);
	discard_bytes(srv, cq, len);
	state->abs_off += len;

	if (state->zero_unalloc) {
		err = zero_unallocated(srv, state);
		state->zero_unalloc = 0;
	}

done:
	con->range_offset = state->abs_off - range_start;
	return err;
}