Beispiel #1
0
void *kmalloc(u32 size)
{
	int i;
	int j;
	struct header *fit = NULL;
	struct alloc_list *l;
	for_each_alloc_list_entry(l, j) {
		struct header *t = l->first;
		for_each_block(t, i) {
			if (t->used)
				continue;
			if (fit == NULL) {
				fit = t;
				continue;
			}
			if (t->size >= size && t->size < fit->size) {
				fit = t;
				continue;
			}
		}
	}
	if (fit == NULL) {
		add_block(GROW_BUFFER_SIZE);
		return kmalloc(size);
		return NULL;
	}
	/* Check if we can break the block down */
	int left = fit->size - size - sizeof(struct header) - sizeof(struct footer);
	if (left > 4)
		break_block(fit, size);
	fit->used = 1;
	print_blocks();
	return fit->mem;
}
Beispiel #2
0
static int pool_alloc(struct k_mem_pool *p, struct k_mem_block *block,
		      size_t size)
{
	size_t lsizes[p->n_levels];
	int i, alloc_l = -1, free_l = -1, from_l;
	void *blk = NULL;

	/* Walk down through levels, finding the one from which we
	 * want to allocate and the smallest one with a free entry
	 * from which we can split an allocation if needed.  Along the
	 * way, we populate an array of sizes for each level so we
	 * don't need to waste RAM storing it.
	 */
	lsizes[0] = _ALIGN4(p->max_sz);
	for (i = 0; i < p->n_levels; i++) {
		if (i > 0) {
			lsizes[i] = _ALIGN4(lsizes[i-1] / 4);
		}

		if (lsizes[i] < size) {
			break;
		}

		alloc_l = i;
		if (!level_empty(p, i)) {
			free_l = i;
		}
	}

	if (alloc_l < 0 || free_l < 0) {
		block->data = NULL;
		return -ENOMEM;
	}

	/* Iteratively break the smallest enclosing block... */
	blk = alloc_block(p, free_l, lsizes[free_l]);

	if (!blk) {
		/* This can happen if we race with another allocator.
		 * It's OK, just back out and the timeout code will
		 * retry.  Note mild overloading: -EAGAIN isn't for
		 * propagation to the caller, it's to tell the loop in
		 * k_mem_pool_alloc() to try again synchronously.  But
		 * it means exactly what it says.
		 */
		return -EAGAIN;
	}

	for (from_l = free_l;
	     level_empty(p, alloc_l) && from_l < alloc_l;
	     from_l++) {
		blk = break_block(p, blk, from_l, lsizes);
	}

	/* ... until we have something to return */
	block->data = blk;
	block->id.pool = pool_id(p);
	block->id.level = alloc_l;
	block->id.block = block_num(p, block->data, lsizes[alloc_l]);
	return 0;
}