Beispiel #1
0
//todo ? skip is used to jump over given bytes?
int
ringbuffer_data(struct ringbuffer * rb, struct ringbuffer_block * blk, int size, int skip, void **ptr) {

	int length = blk->length - sizeof(struct ringbuffer_block) - blk->offset;
	for (;;) {
		if (length > skip) {    //length > skip
			if (length - skip >= size) {
				char * start = (char *)(blk + 1);
				*ptr = (start + blk->offset + skip);
				return size;
			}
            //set address to read to NULL
			*ptr = NULL;
			int ret = length - skip;    //if ret < size ,and blk has next , shift to next
			while (blk->next >= 0) {
				blk = block_ptr(rb, blk->next);
				ret += blk->length - sizeof(struct ringbuffer_block);
				if (ret >= size)
					return size;
			}
			return ret;
		}
		if (blk->next < 0) {
			assert(length == skip);     //length == skip
			*ptr = NULL;
			return 0;
		}

        //length < skip
		blk = block_ptr(rb, blk->next);
		assert(blk->offset == 0);
		skip -= length;
		length = blk->length - sizeof(struct ringbuffer_block);
	}
}
Beispiel #2
0
int
ringbuffer_data(struct ringbuffer * rb, struct ringbuffer_block * blk, int size, int skip, void **ptr) {
	int length = blk->length - sizeof(struct ringbuffer_block) - blk->offset;
	for (;;) {
		if (length > skip) {
			if (length - skip >= size) {
				char * start = (char *)(blk + 1);
				*ptr = (start + blk->offset + skip);
				return size;
			}
			*ptr = NULL;
			int ret = length - skip;
			while (blk->next >= 0) {
				blk = block_ptr(rb, blk->next);
				ret += blk->length - sizeof(struct ringbuffer_block);
				if (ret >= size)
					return size;
			}
			return ret;
		}
		if (blk->next < 0) {
			assert(length == skip);
			*ptr = NULL;
			return 0;
		}
		blk = block_ptr(rb, blk->next);
		assert(blk->offset == 0);
		skip -= length;
		length = blk->length - sizeof(struct ringbuffer_block);
	}
}
Beispiel #3
0
void *
ringbuffer_copy(struct ringbuffer * rb, struct ringbuffer_block * from, int skip, struct ringbuffer_block * to) {

    int size = to->length - sizeof(struct ringbuffer_block);
	int length = from->length - sizeof(struct ringbuffer_block) - from->offset;
	char * ptr = (char *)(to+1);
	for (;;) {
		if (length > skip) {    //data length bigger than skip ,need to copy
			char * src = (char *)(from + 1);
			src += from->offset + skip;
			length -= skip;         //length of data to copy
			while (length < size) {     //if small than size, pull from its next blk
				memcpy(ptr, src, length);
				assert(from->next >= 0);    //has a next blk
				from = block_ptr(rb , from->next);
				assert(from->offset == 0);  //if offset not 0 ,means this blk has data to be handle
				ptr += length;      //shift dest address
				size -= length;     //re calculate size to copy
				length = from->length - sizeof(struct ringbuffer_block);    //data length of blk
				src =  (char *)(from + 1);
			}
			memcpy(ptr, src , size);    //if data length is enough ,do copy
			to->id = from->id;      //copy id
			return (char *)(to + 1);        //return dest
		}
		assert(from->next >= 0);        //if length is not enough to skip ,shift to next blk ,skip the left num
		from = block_ptr(rb, from->next);
		assert(from->offset == 0);
		skip -= length;     //remaind skip
		length = from->length - sizeof(struct ringbuffer_block);        //get a new length of a new blk ,restart
	}
}
Beispiel #4
0
void *
ringbuffer_copy(struct ringbuffer * rb, struct ringbuffer_block * from, int skip, struct ringbuffer_block * to) {
	int size = to->length - sizeof(struct ringbuffer_block);
	int length = from->length - sizeof(struct ringbuffer_block) - from->offset;
	char * ptr = (char *)(to+1);
	for (;;) {
		if (length > skip) {
			char * src = (char *)(from + 1);
			src += from->offset + skip;
			length -= skip;
			while (length < size) {
				memcpy(ptr, src, length);
				assert(from->next >= 0);
				from = block_ptr(rb , from->next);
				assert(from->offset == 0);
				ptr += length;
				size -= length;
				length = from->length - sizeof(struct ringbuffer_block);
				src =  (char *)(from + 1);
			}
			memcpy(ptr, src , size);
			to->id = from->id;
			return (char *)(to + 1);
		}
		assert(from->next >= 0);
		from = block_ptr(rb, from->next);
		assert(from->offset == 0);
		skip -= length;
		length = from->length - sizeof(struct ringbuffer_block);
	}
}
Beispiel #5
0
static void free_block(struct k_mem_pool *p, int level, size_t *lsizes, int bn)
{
	int i, key, lsz = lsizes[level];
	void *block = block_ptr(p, lsz, bn);

	key = irq_lock();

	set_free_bit(p, level, bn);

	if (level && partner_bits(p, level, bn) == 0xf) {
		for (i = 0; i < 4; i++) {
			int b = (bn & ~3) + i;

			clear_free_bit(p, level, b);
			if (b != bn &&
			    block_fits(p, block_ptr(p, lsz, b), lsz)) {
				sys_dlist_remove(block_ptr(p, lsz, b));
			}
		}

		irq_unlock(key);
		free_block(p, level-1, lsizes, bn / 4); /* tail recursion! */
		return;
	}

	if (block_fits(p, block, lsz)) {
		sys_dlist_append(&p->levels[level].free_list, block);
	}

	irq_unlock(key);
}
Beispiel #6
0
/**	@fn	RBUF_BLOCK *ringbuffer_alloc(RINGBUFFER * rb, int size) 
 *	@brief	在ringbuffer中开辟size大小的数据块 
 *	@param rb	环形缓冲区指针.
 *	@param size	需要开辟的数据块的大小	 
 *	@return	指向该数据块的指针 
 */
RBUF_BLOCK *ringbuffer_alloc(RINGBUFFER * rb, int size) 
{
	/*调整数据块大小4字节对齐*/ 
	int align_length = ALIGN(sizeof(RBUF_BLOCK) + size);
	int i;
	/*循环2次实现一个环形的功能*/
	for (i = 0;i < 2;i++) 
	{
		int free_size = 0;
		RBUF_BLOCK * blk = block_ptr(rb, rb->head);
		do 
		{
		//	printf("blk->length:%d\n",blk->length);
		//	printf("blk->offset:%d\n",blk->offset);
			/*如果当前blk还在使用则返回NULL表示没有剩余的空间可以分配*/ 
			if ((blk->length >= sizeof(RBUF_BLOCK)) && (blk->id >= 0))
			{ 
				return NULL;
			}
			/*回收碎片*/ 
			free_size += ALIGN(blk->length);
			if (free_size >= align_length) 
			{
				return _alloc(rb, free_size , size);
			}
			blk = block_next(rb, blk);
		} while(blk);
		/*如果后面没有足够的空间分配则从头分配*/
		rb->head = 0;
	}
	return NULL;
}
Beispiel #7
0
//ring buffer alloc
struct ringbuffer_block *
ringbuffer_alloc(struct ringbuffer * rb, int size) {

    //get align size needed
	int align_length = ALIGN(sizeof(struct ringbuffer_block) + size);
	int i;
	for (i=0;i<2;i++) {
		int free_size = 0;

        //find start pointer, from rb->head on
		struct ringbuffer_block * blk = block_ptr(rb, rb->head);    //blk is next point of last blk
                                                                    //so blk is next space to use
		do {
            //轮转之前不会执行,只有轮转后后可能执行,轮转后遇到不可分配的,应该强行回收
			if (blk->length >= sizeof(struct ringbuffer_block) && blk->id >= 0)    //id >= 0 means mem in use
				return NULL;
			free_size += ALIGN(blk->length);
			if (free_size >= align_length) {
				return _alloc(rb, free_size , size);
			}
			blk = block_next(rb, blk);              //find space available
		} while(blk);
		rb->head = 0;    //roll back ,do again
	}
	return NULL;
}
Beispiel #8
0
static struct ringbuffer_block *
_alloc(struct ringbuffer * rb, int total_size , int size) {

    //get start point ,from rb->head on
	struct ringbuffer_block * blk = block_ptr(rb, rb->head);
    //get align length
	int align_length = ALIGN(sizeof(struct ringbuffer_block) + size);
    //set real length
	blk->length = sizeof(struct ringbuffer_block) + size;     //blk real size ,no align
	blk->offset = 0;                                          //set length with no align ,cause padding space no need to read
	blk->next = -1;
	blk->id = -1;
    //get next blk
	struct ringbuffer_block * next = block_next(rb, blk);
	if (next) {
		rb->head = block_offset(rb, next);                    //set head to offset(start) of next blk
		if (align_length < total_size) {
			next->length = total_size - align_length;         //next blk is the remain space, set length of rest space
			if (next->length >= sizeof(struct ringbuffer_block)) {
				next->id = -1;  //-1 means blk available
			}
		}
	} else {
		rb->head = 0;                                         //if no next , means roll back ,head set to 0
	}
	return blk;
}
Beispiel #9
0
static void init_mem_pool(struct k_mem_pool *p)
{
	int i;
	size_t buflen = p->n_max * p->max_sz, sz = p->max_sz;
	u32_t *bits = p->buf + buflen;

	sys_dlist_init(&p->wait_q);

	for (i = 0; i < p->n_levels; i++) {
		int nblocks = buflen / sz;

		sys_dlist_init(&p->levels[i].free_list);

		if (nblocks < 32) {
			p->max_inline_level = i;
		} else {
			p->levels[i].bits_p = bits;
			bits += (nblocks + 31)/32;
		}

		sz = _ALIGN4(sz / 4);
	}

	for (i = 0; i < p->n_max; i++) {
		void *block = block_ptr(p, p->max_sz, i);

		sys_dlist_append(&p->levels[0].free_list, block);
		set_free_bit(p, 0, i);
	}
}
Beispiel #10
0
void
ringbuffer_link(struct ringbuffer *rb , struct ringbuffer_block * head, struct ringbuffer_block * next) {
	while (head->next >=0) {
		head = block_ptr(rb, head->next);
	}
	next->id = head->id;
	head->next = block_offset(rb, next);
}
Beispiel #11
0
struct ringbuffer *
ringbuffer_new(int size) {
	struct ringbuffer * rb = malloc(sizeof(*rb) + size);
	rb->size = size;
	rb->head = 0;
	struct ringbuffer_block * blk = block_ptr(rb, 0);
	blk->length = size;
	blk->id = -1;
	return rb;
}
Beispiel #12
0
/**	@fn	void ringbuffer_link(RINGBUFFER *rb , RBUF_BLOCK * head, RBUF_BLOCK * next)
 *	@brief	将同一连接的数据块连接起来 
 *	@param rb 环形缓冲区指针.
 *	@param head 指向同一连接的一块数据块
 *	@param next 指向要连接的数据块 
 *	@return	N/A
 */
void ringbuffer_link(RINGBUFFER *rb , RBUF_BLOCK * head, RBUF_BLOCK * next)
{
	/*指到同一连接的数据块的最尾*/ 
	while (head->next >=0) 
	{
		head = block_ptr(rb, head->next);
	}
	next->id = head->id;
	head->next = block_offset(rb, next);
}
Beispiel #13
0
static inline struct ringbuffer_block *
block_next(struct ringbuffer * rb, struct ringbuffer_block * blk) {
	int align_length = ALIGN(blk->length);
	int head = block_offset(rb, blk);
	if (align_length + head == rb->size) {
		return NULL;
	}
	assert(align_length + head < rb->size);
	return block_ptr(rb, head + align_length);
}
Beispiel #14
0
void
ringbuffer_link(struct ringbuffer *rb , struct ringbuffer_block * head, struct ringbuffer_block * next) {
	//head blk already have a next blk, shift to this "next blk"
    while (head->next >=0) {
		head = block_ptr(rb, head->next);
	}
	//set 2 block of same id
	next->id = head->id;
    //set blk1 -> next offset of blk2
	head->next = block_offset(rb, next);
}
Beispiel #15
0
static inline struct ringbuffer_block *
block_next(struct ringbuffer * rb, struct ringbuffer_block * blk) {

	int align_length = ALIGN(blk->length);
	int head = block_offset(rb, blk);               //head is result of last blk - (start+1),head is relative address of blk
	if (align_length + head == rb->size) {
		return NULL;
	}
	assert(align_length + head < rb->size);     //have space to alloc
	return block_ptr(rb, head + align_length);      //offset of last bulk + length of last bulk
}
Beispiel #16
0
void
ringbuffer_free(struct ringbuffer * rb, struct ringbuffer_block * blk) {
	if (blk == NULL)
		return;
	int id = _block_id(blk);
	blk->id = -1;
	while (blk->next >= 0) {
		blk = block_ptr(rb, blk->next);
		assert(_block_id(blk) == id);
		blk->id = -1;
	}
}
Beispiel #17
0
int
ringbuffer_collect(struct ringbuffer * rb) {
	int id = _last_id(rb);
	struct ringbuffer_block *blk = block_ptr(rb, 0);
	do {
		if (blk->length >= sizeof(struct ringbuffer_block) && blk->id == id) {
			blk->id = -1;
		}
		blk = block_next(rb, blk);
	} while(blk);
	return id;
}
Beispiel #18
0
struct ringbuffer *
ringbuffer_new(int size) {
	struct ringbuffer * rb = malloc(sizeof(*rb) + size);

    printf("size of init rb is %d \n", sizeof(*rb));

	rb->size = size;
	rb->head = 0;
	struct ringbuffer_block * blk = block_ptr(rb, 0);   //get address of memory
	blk->length = size;
	blk->id = -1;
	return rb;
}
Beispiel #19
0
/**	@fn	int ringbuffer_collect(RINGBUFFER * rb) 
 *	@brief 收集最早分配的还在使用的同一id的数据块以便覆盖	 
 *	@param rb	环形缓冲区指针	 
 *	@return	返回该数据块id 
 */
int ringbuffer_collect(RINGBUFFER * rb) 
{
	int id = _last_id(rb);
	RBUF_BLOCK *blk = block_ptr(rb, 0);
	do 
	{
		if (blk->length >= sizeof(RBUF_BLOCK) && blk->id == id) 
		{
			blk->id = -1;
		}
		blk = block_next(rb, blk);
	} while(blk);
	return id;
}
Beispiel #20
0
/**	@fn	static inline RBUF_BLOCK *block_next(RINGBUFFER * rb, RBUF_BLOCK * blk)
 *	@brief	指针指向下一个数据块 
 *	@param rb 环形缓冲区指针.
 *	@param blk 当前数据块指针.
 *	@return	指向下一块数据块的指针 
 */
static inline RBUF_BLOCK *block_next(RINGBUFFER * rb, RBUF_BLOCK * blk)
{
	/*分配的时候是按4字节对齐的。中间会有碎片*/ 
	int align_length = ALIGN(blk->length);
	int head = block_offset(rb, blk);
	/*如果当前的blk已经在buffer的最尾,则表示没有下一块*/ 
	if (align_length + head == rb->size) 
	{
		return NULL;
	}
	/*如果当前分配的空间加上当前的位置大于ringbuffersize则段错误*/ 
	assert(align_length + head < rb->size);
	return block_ptr(rb, head + align_length);
}
Beispiel #21
0
static int
_last_id(struct ringbuffer * rb) {
	int i;
	for (i=0;i<2;i++) {
		struct ringbuffer_block * blk = block_ptr(rb, rb->head);
		do {
			if (blk->length >= sizeof(struct ringbuffer_block) && blk->id >= 0)
				return blk->id;
			blk = block_next(rb, blk);
		} while(blk);
		rb->head = 0;
	}
	return -1;
}
Beispiel #22
0
/**	@fn	RINGBUFFER *ringbuffer_new(int size)
 *	@brief	创建一个ringbuffer 
 *	@param size ringbuffer的大小 
 *	@return	指向ringbuffer的指针rb 
 */
RINGBUFFER *ringbuffer_new(int size)
{
	RINGBUFFER * rb = NULL; 
	if(NULL == (rb = (RINGBUFFER *)malloc(sizeof(*rb) + size)))
	{
		perror("malloc");	
	}
	rb->size = size;
	rb->head = 0;
	RBUF_BLOCK * blk = block_ptr(rb, 0);
	blk->length = size;
	blk->id = -1;
	return rb;
}
Beispiel #23
0
/**	@fn	void ringbuffer_free(RINGBUFFER * rb, RBUF_BLOCK * blk)
 *	@brief 将已经断开连接的数据块id置-1	 
 *	@param rb	指向ringbuffer的指针 
 *	@param blk	指向已断开连接的第一块数据块 
 *	@return	N/A		
 */
void ringbuffer_free(RINGBUFFER * rb, RBUF_BLOCK * blk)
{
	if (blk == NULL)
	{ 
		return;
	} 
	int id = _block_id(blk);
	blk->id = -1;
	while (blk->next >= 0) 
	{
		blk = block_ptr(rb, blk->next);
		assert(_block_id(blk) == id);
		blk->id = -1;
	}
}
Beispiel #24
0
static struct ringbuffer_block *
_alloc(struct ringbuffer * rb, int total_size , int size) {
	struct ringbuffer_block * blk = block_ptr(rb, rb->head);
	int align_length = ALIGN(sizeof(struct ringbuffer_block) + size);
	blk->length = sizeof(struct ringbuffer_block) + size;
	blk->offset = 0;
	blk->next = -1;
	blk->id = -1;
	struct ringbuffer_block * next = block_next(rb, blk);
	rb->head = block_offset(rb, next);
	if (align_length < total_size) {
		next->length = total_size - align_length;
		if (next->length >= sizeof(struct ringbuffer_block)) {
			next->id = -1;
		}
	}
	return blk;
}
Beispiel #25
0
//get a blk needed ,with skip param
struct ringbuffer_block *
ringbuffer_yield(struct ringbuffer * rb, struct ringbuffer_block *blk, int skip) {
	int length = blk->length - sizeof(struct ringbuffer_block) - blk->offset;       //-offset 意思是处理未处理的数据,offset是未处理的数据起始点
	for (;;) {
		if (length > skip) {
			blk->offset += skip;    //shift offset by skip ,skip means no need to process
			return blk;
		}
		blk->id = -1;
		if (blk->next < 0) {
			return NULL;
		}
		blk = block_ptr(rb, blk->next);
		assert(blk->offset == 0);
		skip -= length;     //re calculate skip, skip is consumed partly by last blk
		length = blk->length - sizeof(struct ringbuffer_block);
	}
}
Beispiel #26
0
struct ringbuffer_block *
ringbuffer_yield(struct ringbuffer * rb, struct ringbuffer_block *blk, int skip) {
	int length = blk->length - sizeof(struct ringbuffer_block) - blk->offset;
	for (;;) {
		if (length > skip) {
			blk->offset += skip;
			return blk;
		}
		blk->id = -1;
		if (blk->next < 0) {
			return NULL;
		}
		blk = block_ptr(rb, blk->next);
		assert(blk->offset == 0);
		skip -= length;
		length = blk->length - sizeof(struct ringbuffer_block);
	}
}
Beispiel #27
0
/**	@fn	static int _last_id(RINGBUFFER * rb) 
 *	@brief 寻找最早分配的还在使用的数据块id,以便收集覆盖	 
 *	@param rb	环形缓冲区指针.	 
 *	@return	返回该数据块id 
 */
static int _last_id(RINGBUFFER * rb)
{
	int i;
	/*循环2次实现一个环形的功能*/
	for (i = 0;i < 2;i++) 
	{
		RBUF_BLOCK * blk = block_ptr(rb, rb->head);
		do 
		{
			if ((blk->length >= sizeof(RBUF_BLOCK)) && (blk->id >= 0))
			{
				return blk->id;
			}
			blk = block_next(rb, blk);
		} while(blk);
		rb->head = 0;
	}
	return -1;
}
Beispiel #28
0
struct ringbuffer_block *
ringbuffer_alloc(struct ringbuffer * rb, int size) {
	int align_length = ALIGN(sizeof(struct ringbuffer_block) + size);
	int i;
	for (i=0;i<2;i++) {
		int free_size = 0;
		struct ringbuffer_block * blk = block_ptr(rb, rb->head);
		do {
			if (blk->length >= sizeof(struct ringbuffer_block) && blk->id >= 0)
				return NULL;
			free_size += ALIGN(blk->length);
			if (free_size >= align_length) {
				return _alloc(rb, free_size , size);
			}
			blk = block_next(rb, blk);
		} while(blk);
		rb->head = 0;
	}
	return NULL;
}
Beispiel #29
0
    decompressor::block_ptr_t decompressor::read_block(size_t block_id) const
    {
	block_ptr_t cached_block_ptr = m_cache->get(block_id);
	if (cached_block_ptr) {
	    return cached_block_ptr;
	}
	
	boost::shared_ptr<block_t> block_ptr(new block_t(block_id * block_size(), std::vector<char>())); // non-const ptr
	std::vector<char>& block = block_ptr->second;

        block.resize(m_block_size);
        
        z_stream strm;
        int ret;
        strm.zalloc = Z_NULL;
        strm.zfree = Z_NULL;
        strm.opaque = Z_NULL;
        ret = inflateInit2(&strm, window_size);
        assert(ret == Z_OK);

        size_t offset = m_offsets[block_id];
            
        strm.avail_in = m_compressed_size - offset;
        strm.next_in = (unsigned char*)(m_compressed_data + offset);

        strm.avail_out = m_block_size;
        strm.next_out = (unsigned char*)&block[0];

        ret = inflate(&strm, Z_BLOCK);
        assert(ret == Z_OK);
        block.resize(m_block_size - strm.avail_out);

        inflateEnd(&strm);

#ifdef ZRANDOM_PROFILE
        ++m_reads;
        m_unique_reads.insert(block_id);
#endif
	m_cache->put(block_id, block_ptr);
	return block_ptr;
    }
Beispiel #30
0
void 
ringbuffer_dump(struct ringbuffer * rb) {
	struct ringbuffer_block *blk = block_ptr(rb,0);
	int i=0;
	printf("total size= %d\n",rb->size);
	while (blk) {
		++i;
		if (i>10)
			break;
		if (blk->length >= sizeof(*blk)) {
			printf("[%u : %d]", (unsigned)(blk->length - sizeof(*blk)), block_offset(rb,blk));
			printf(" id=%d",blk->id);
			if (blk->id >=0) {
				printf(" offset=%d next=%d",blk->offset, blk->next);
			}
		} else {
			printf("<%u : %d>", blk->length, block_offset(rb,blk));
		}
		printf("\n");
		blk = block_next(rb, blk);
	}
}