#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include "buf_interface.h"
#define POOL_SIZE 100 /* limit of block quantity in the pool */
static list_head_t blk_head_hashtable[HASH_SIZE]; /* hash table */
static list_head_t lru;
/**
* get_key - get hashtable key
*@dev:device number
*@blk_nr:block number
*/
int get_key(unsigned int dev, unsigned int blk_nr)
{
int key ;
key = ((dev << 3) + blk_nr) % (HASH_SIZE); /* simple hash function */
return key;
}
/**
* init_blk_pool - initialize the cache pool
*/
void init_blk_pool()
{
int i;
/* initialize the hash table */
for (i = 0; i < HASH_SIZE; i++){
INIT_LIST_HEAD(&blk_head_hashtable[i]);
}
/* initialize the free list */
INIT_LIST_HEAD(&lru);
}
/**
* search_hash_table - search the given block in the hashtable
* @dev:device number
* @blk_nr:block number
* return the pointer of the specific block
*/
nand_block_head_t * search_hash_table(unsigned int dev, unsigned int blk_nr)
{
int key;
nand_block_head_t *block;
list_head_t *p;
key = get_key(dev,blk_nr);
printf("hash key = %d\n",key);
/* go through the list */
_list_for_each(p,&blk_head_hashtable[key]){
/* get struct for the block */
block= list_entry(p, nand_block_head_t, hash);
if((block->dev == dev) && (block->blk_nr == blk_nr)){
return block;
}
}
printf("there is no block(device = %d, block = %d) in the pool right now.\n",dev,blk_nr);
return NULL;
}
/**
* init_block - initialize the block
* @p: to block to be initialzed
* dev:device number
* blk_nr:block number
*/
int init_block(nand_block_head_t *p,unsigned int dev,unsigned int blk_nr)
{
int key;
/* parameter check */
if (p == NULL){
printf("error!block is NULL.\n");
return 0;
}
p->dev = dev;
p->blk_nr = blk_nr;
p->flags = DATA_VALID;
memset(p->blk_data,0,BLK_SIZE);
INIT_LIST_HEAD(&p->lru);
key = get_key(dev, blk_nr);
list_add_tail(&(p->hash),&blk_head_hashtable[key]);
return 1;
}
/**
* get_block - get a block given device number and block number
* @dev: device number
* @blk_nr:block number
* @head : head of the free list
*/
nand_block_head_t * get_block(unsigned int dev, unsigned int blk_nr)
{
nand_block_head_t *block;
int key,count;
key = get_key(dev, blk_nr);
block = search_hash_table(dev, blk_nr);
if (block){
if (!(block->flags)){
list_del_init(&block->lru); /* take it off the free list */
block->flags = DATA_VALID;
return block;
} else {
printf("\nblock(device = %d, block = %d) is being used!\n\n",
block->dev,block->blk_nr);
return NULL;
}
} else { /* test if the current block use get the limit of the pool */
count = count_pool();
if (count >= POOL_SIZE){
printf("pool is full running!\n");
if (!list_empty(&lru)){
/* get strcut for block */
block = list_entry(lru.next, nand_block_head_t, lru);
list_del_init(lru.next);
list_del_init(&(block->hash));
if(init_block(block, dev, blk_nr)){
printf("system assign a block in the freelist for you.\n");
return block;
}
}
printf("the free list is empty!\n");
return NULL;
}
/* dynamic allot memory */
block = (nand_block_head_t *)malloc(
sizeof(nand_block_head_t)+ BLK_SIZE * sizeof(char));
if (block == NULL){
printf("apply memory failed!\n");
return NULL;
} else {
printf("creating a block.\n");
}
(void)init_block(block, dev, blk_nr);
/* check if the new block joined the hashtable */
if (blk_head_hashtable[key].prev == &(block->hash)){
printf("block has added to the hashtable\n\ndevice = %d\nblock = %d\n",
block->dev,block->blk_nr);
} else {
printf("the block(dev=%d,blk=%d) has not added to the hashtable\n",
block->dev,block->blk_nr);
}
return block;
}
} /* get_block */
/**
* count_pool - count the total of block already used in the pool
*/
int count_pool()
{
int i,count;
list_head_t *p;
count = 0;
/* go though each queue of the hash table and count the total */
for (i = 0; i < HASH_SIZE; i++) {
if (list_empty(&blk_head_hashtable[i])){
continue;
}
_list_for_each(p,&blk_head_hashtable[i]){
count++;
}
}
return count;
}
/**
* put_block - put a block back to the list
* @p:pointer point to a block
*/
void put_block(nand_block_head_t *p)
{
/* parameter check */
if (p == NULL){
printf("block is inexistence\n");
return ;
}
if (p->flags != DATA_VALID){
printf("it is in the free list already!\n");
return;
}
/* put the block back and add to the free block list */
p->flags = !(DATA_VALID);
memset(p->blk_data,0,BLK_SIZE);
list_add_tail(&(p->lru),&lru);
/* check whether the block added to the list but now */
/* if added successfully,the prev of head point to it */
if(lru.prev == &(p->lru)){
printf("block has added to the free list\n\ndevice = %d\nblock = %d\n",
p->dev,p->blk_nr);
}
}
/**
* clear_pool - free the pool
*/
void clear_pool()
{
int i,count;
list_head_t *p,*tmp;
nand_block_head_t *block;
count = 0;
for (i = 0; i < HASH_SIZE; i++){
_list_for_each_safe(p, tmp, &blk_head_hashtable[i]){
list_del_init(p);
block = list_entry(p, nand_block_head_t, hash);
free(block);
count++;
}
}
lru.next = &lru;/* list is empty too now */
lru.prev = &lru;
printf("free %d blocks\n",count);
}
/**
* see_pool - see the state of the pool
*/
void see_pool()
{
int i,count;
list_head_t *p;
nand_block_head_t *block;
count = count_pool();/* get the total use of the pool */
if (count > 0){
printf("now there are %d in the pool\n",count);
for (i = 0; i < HASH_SIZE; i++){
_list_for_each(p,&blk_head_hashtable[i]){
block = list_entry(p, nand_block_head_t, hash);/* get the struct for block */
printf("\ndev: %d\nblk :%d\nflags:%d\n",
block->dev,block->blk_nr,block->flags);
}
}
} else {
printf("pool is empty!\n");
}
}
串行FLASH数据缓冲区的管理
5星 · 超过95%的资源 需积分: 14 108 浏览量
2010-09-14
11:11:25
上传
评论 1
收藏 4KB RAR 举报
newguworld
- 粉丝: 0
- 资源: 1
最新资源
- AT32与Sxx32/Gx32替换对照表
- STM32VET6单片机+XC3S250E(FPGA)+AD9708 DDS信号发生器MCU+FPGA源码+PDF硬件设计原理图
- SCIPOptSuite-9.0.0-win64-VS15.exe
- GIS10.4补丁文件
- fdgsfdgfdsgsf
- 基于CodeMirror5实现的mybatis+sql提示扩展功能,主要是用于在线设计开发场景中的动态sql部分.zip
- 计算机毕业设计-aSP.NET某中学学生成绩管理系统的设计(源代码+)-毕设源码实例.zip
- springboot集成mybatis动态sql.zip
- mybatis中的动态sql, 涉及 where trim set if foreach等
- 简单- 快递运输(Java & JS & Python & C).html
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈