/** * @brief Locate blocks of contiguous free space of a given amount. * @param blocks The number of contiguous blocks to search for. * @return The index of the first block of the contiguous free memory, or -1 if not found. */ static int32_t locate_free(heap_state_t* heap_state, int32_t blocks) { int32_t n; int32_t heap_blocks; int32_t block=block_range(heap_state,&heap_blocks); uint32_t page=0; while(block < heap_blocks) { page = heap_state->heap_free_bitmap[block_offset(block)]; if ( ((page & ALL_BITS) != ALL_BITS) ) /* look at 32 blocks at a time... */ { /* out of the next 32 bits, see if we can start the sequence */ for(n=0; n < HEAP_BLOCKS_PER_PAGE; n++) { /* try each bit */ if (is_free_sequence(heap_state,block+n,blocks)) { return block+n; } } } block += HEAP_BLOCKS_PER_PAGE; /* we've looked at 32 blocks, skip past them */ } return -1; }
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; }
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); }
/** * @brief Lookup a single bit representing a single block, and return the bit state state as a boolean. * @param heap_state Pointer to the heap state related to the heap to use. * @param block The block index to look up. * @param map The bitmap in which to lookup the bit in question. * @return A boolean representative of the state of the bit. */ static bool get_bitmap_bit(heap_state_t* heap_state,int32_t block,uint32_t map[]) { if ( valid(heap_state,block) ) { return (map[block_offset(block)] & (1<<bit_offset(block))) ? true : false; } return false; }
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); }
/** @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); }
static u64_t romdisk_read(struct block_t * blk, u8_t * buf, u64_t blkno, u64_t blkcnt) { struct romdisk_t * romdisk = (struct romdisk_t *)(blk->priv); u64_t offset = block_offset(blk, blkno); u64_t length = block_available_length(blk, blkno, blkcnt); u64_t count = block_available_count(blk, blkno, blkcnt); memcpy((void *)buf, (const void *)((u8_t *)(romdisk->start) + offset), length); return count; }
static u64_t romdisk_read(struct block_t * blk, u8_t * buf, u64_t blkno, u64_t blkcnt) { struct romdisk_pdata_t * pdat = (struct romdisk_pdata_t *)(blk->priv); virtual_addr_t offset = pdat->addr + block_offset(blk, blkno); u64_t count = block_available_count(blk, blkno, blkcnt); u64_t length = block_available_length(blk, blkno, blkcnt); memcpy((void *)buf, (const void *)(offset), length); return count; }
void ringbuffer_resize(struct ringbuffer * rb, struct ringbuffer_block * blk, int size) { if (size == 0) { rb->head = block_offset(rb, blk); return; } int align_length = ALIGN(sizeof(struct ringbuffer_block) + size); int old_length = ALIGN(blk->length); assert(align_length <= old_length); blk->length = size + sizeof(struct ringbuffer_block); if (align_length == old_length) { return; } blk = block_next(rb, blk); blk->length = old_length - align_length; if (blk->length >= sizeof(struct ringbuffer_block)) { blk->id = -1; } rb->head = block_offset(rb, blk); }
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); }
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 }
/** * @brief lookup a bit in the bitmap and set the bit state from a boolean. * @param heap_state Pointer to the heap state related to the heap to use. * @param block The block index to look up. * @param map The bitmap in which to lookup the bit in question. * @param state The boolean state to use to set or reset the bit. */ static void set_bitmap_bit(heap_state_t* heap_state,int32_t block,uint32_t map[],bool state) { if ( valid(heap_state,block) ) { int32_t bitOffset = bit_offset(block); int32_t wordOffset = block_offset(block); if (state) map[wordOffset] |= (1<<bitOffset); else map[wordOffset] &= ~(1<<bitOffset); } }
void Gdal::Band::LoadBlock(int column, int row) const { ASSERT(column >= 0 && column < block_count.cx); ASSERT(row >= 0 && row < block_count.cy); int block_index = column + row * block_count.cx; if(blocks[block_index]) return; Point block_offset(block_size.cx * column, block_size.cy * row); One<Block> new_block = new Block(block_size, type, pixel_bytes); band->ReadBlock(column, row, new_block->bytes); blocks[block_index] = pick(new_block); }
unsigned char *unvectorize(unsigned char *zigzag, int size) { unsigned char *blocks = calloc(size, sizeof(unsigned char)); int block_length = size / (8 * 8 * 3); int i, x, y, color; int index = 0; int d; // Going through every block for(i = 0; i < block_length; i++) { // Zigzagging each block into the zigzag vector // Putting colors in different vectors for(color = 0; color < 3; color++) { for(d = 1, x = 0, y = 0; (x < 8) && (y < 8); index++) { blocks[block_offset(i, x, y, color)] = zigzag[index]; x += d; y -= d; if(y < 0) { // Outside top y = 0; d = -d; continue; } if(x < 0) { d = -d; if(y > 7) { // Outside left bottom y = 7; x += 2; continue; } // Outside left only x = 0; continue; } if(x > 7) { // Outside right x = 7; y += 2; d = -d; continue; } if(y > 7) { // Outside bottom x += 2; y = 7; d = -d; continue; } } } } //printf("len -> %d\n", block_length); //printf("sz -> %d\n", size); //printf("i -> %d\n", index); return blocks; }
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); } }
/** @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); }
/** @fn void ringbuffer_resize(RINGBUFFER * rb, RBUF_BLOCK * blk, int size) * @brief ringbuffer收到数据,调整ringbuffer * @param rb 环形缓冲区指针 * @param blk 接受数据的当前空闲块 * @param size 接受数据的大小 * @return N/A */ void ringbuffer_resize(RINGBUFFER * rb, RBUF_BLOCK * blk, int size) { if (size == 0) { rb->head = block_offset(rb, blk); return; } int align_length = ALIGN(sizeof(RBUF_BLOCK) + size); int old_length = ALIGN(blk->length); assert(align_length < old_length); blk->length = size + sizeof(RBUF_BLOCK); if (align_length == old_length) { return; } blk = block_next(rb, blk); blk->length = old_length - align_length; if (blk->length >= sizeof(RBUF_BLOCK)) { blk->id = -1; } rb->head = block_offset(rb, blk); }
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; }
/** @fn static RBUF_BLOCK *_alloc(RINGBUFFER * rb, int total_size , int size) * @brief 为数据块分配空间 * @param rb 环形缓冲区指针. * @param total_size 可以用来分配的连续的总空间 * @param size 需要分配的空间 * @return 指向先分配数据块的指针 */ static RBUF_BLOCK *_alloc(RINGBUFFER * rb, int total_size , int size) { RBUF_BLOCK * blk = block_ptr(rb, rb->head); int align_length = ALIGN(sizeof(RBUF_BLOCK) + size); /*初始化分配块*/ blk->length = sizeof(RBUF_BLOCK) + size; blk->offset = 0; blk->next = -1; blk->id = -1; RBUF_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(RBUF_BLOCK)) { next->id = -1; } } // printf("rb->head:%d\n",rb->head); return blk; }
unsigned char *vectorize(BMPData *bmp, unsigned char *dctq) { unsigned char *blocks = dctq; unsigned char *zigzag = calloc(bmp->dataSize, sizeof(unsigned char)); int block_length = bmp->block_data_length; int i, x, y, color; int index = 0; int d; // Going through every block for(i = 0; i < block_length; i++) { // Zigzagging each block into the zigzag vector // Putting colors in different vectors for(color = 0; color < 3; color++) { for(d = 1, x = 0, y = 0; (x < 8) && (y < 8); index++) { zigzag[index] = blocks[block_offset(i, x, y, color)]; x += d; y -= d; if(y < 0) { // Outside top y = 0; d = -d; continue; } if(x < 0) { d = -d; if(y > 7) { // Outside left bottom y = 7; x += 2; continue; } // Outside left only x = 0; continue; } if(x > 7) { // Outside right x = 7; y += 2; d = -d; continue; } if(y > 7) { // Outside bottom x += 2; y = 7; d = -d; continue; } } } } /* for(i = 0; i < bmp->dataSize; i++) { if(i % 64 == 0) { printf("\n\n"); } printf("%d ", zigzag[i]); } printf("\n");*/ return zigzag; }