1 Star 3 Fork 0

zengku / cache_manager

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
buf_manage.c 6.38 KB
一键复制 编辑 原始数据 按行查看 历史
zengku 提交于 2020-07-14 23:12 . 修改了nand_get_block()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "buf_manage.h"
/* 宏定义list_entry */
#define get_hash_node(hash_p) list_entry(hash_p, struct nand_block_head_s, hash)
#define get_lru_node(lru_p) list_entry(lru_p, struct nand_block_head_s, lru)
/* 结点大小 */
#define BLK_NODE_SIZE sizeof(struct nand_block_head_s)
static struct list_head blk_head_hashtable[HASH_SIZE]; /* hash表头 */
static LIST_HEAD(blk_head_lru); /* lru表头 */
static unsigned long nand_max_cacher; /* 最大缓冲区数 */
static unsigned long nand_pool_cnt; /* 数据块数量 */
/**
* nand_hash_key — 散列函数
* @dev: 设备号
* @blk_nr: 块号
*
* 将16位的设备号置为新数据的高16位,将16位的块号置为该数据低16位,
* 然后采用除法Hash来获得键值
*
* 返回值:键值
*/
static unsigned long nand_hash_key(int dev, int blk_nr)
{
unsigned long hash_key;
hash_key = ((dev << 16) | blk_nr);
return (hash_key % HASH_SIZE);
}
/**
* nand_init_blk_pool — 初始化空闲缓冲区
* @max_cache: 系统中允许的最大缓冲区数目
*
* 初始化高速缓冲管理所需的数据结构
*
* 返回值:无
*/
void nand_init_blk_pool(unsigned long max_cache)
{
unsigned long i;
nand_max_cacher = max_cache; /* 初始化最大缓冲区数 */
nand_pool_cnt = 0; /* 初始化缓冲区数 */
for (i = 0; i < HASH_SIZE; i++) { /* 初始化hash表元素表头 */
INIT_LIST_HEAD(&blk_head_hashtable[i]);
}
INIT_LIST_HEAD(&blk_head_lru); /* 初始化lru表 */
}
/**
* nand_find_block — 检索缓冲区
* @dev: 设备号
* @blk_nr: 块号
*
* 一个缓冲区总是在某个散列队列上,但是它可以在或不在空闲表中
*
* 返回值:无
*/
struct nand_block_head_s *nand_search_block(int dev, int blk_nr)
{
unsigned long i;
struct list_head *cur_node;
struct nand_block_head_s *tmp_buf;
for (i = 0; i < HASH_SIZE; i++) {
list_for_each(cur_node, &(blk_head_hashtable[i])) {
tmp_buf = get_hash_node(cur_node);
if (tmp_buf->dev == dev && tmp_buf->blk_nr == blk_nr) {
return tmp_buf;
}
}
}
(void)printf("检索失败\n");
return NULL;
}
/**
* nand_get_block — 分配缓冲区
* @dev: 设备号
* @blk_nr: 块号
*
* 当内核申请一个数据块时,它使用对应的设备号和块号的组合去找相应的缓冲区,
* 找不到就申请,最初空闲表中空的,所需要的块是从系统内存中分配的,申请块缓冲时,
* 当整个数据块已经申请的缓冲数量未达到上限以前,从系统中申请新的数据块,
* 否则,从空闲表中分配,如果空闲表也没有数据块,则返回失败。
*
* 返回值:指向能被使用的缓冲区的指针,如果没有的话,返回NULL。
*/
struct nand_block_head_s *nand_get_block(int dev, int blk_nr)
{
unsigned long i, key;
struct list_head *next_node;
struct nand_block_head_s *tmp_buf;
key = nand_hash_key(dev, blk_nr);
tmp_buf = nand_search_block(dev, blk_nr);
if (!tmp_buf) { /* 没找到缓冲区进行分配 */
if (nand_pool_cnt < nand_max_cacher) { /* 小于最大缓冲区数 */
tmp_buf = (struct nand_block_head_s *)malloc(BLK_NODE_SIZE + (BLK_SIZE * sizeof(char)));
if (tmp_buf == NULL) {
(void)printf("malloc memory failed!\n");
return NULL;
}
memset(tmp_buf->blk_data, 0, BLK_SIZE);
tmp_buf->flags = DATA_INVALID;
tmp_buf->dev = dev;
tmp_buf->blk_nr = blk_nr;
list_add_tail(&(tmp_buf->hash), &blk_head_hashtable[key]);
nand_pool_cnt++; /* 块计数加一 */
} else {
if (!(list_empty(&blk_head_lru))) { /* lru表空闲缓冲区 */
next_node = blk_head_lru.next;
tmp_buf = get_hash_node(next_node);
list_del_init(next_node); /* 将第一个结点从lru表摘除 */
list_del_init(&(tmp_buf->hash)); /* 将第一个结点从hash表摘除 */
list_add(&(tmp_buf->hash), &blk_head_hashtable[key]);
tmp_buf->dev = dev;
tmp_buf->blk_nr = blk_nr;
}
}
}
return tmp_buf;
}
/**
* nand_put_block — 释放缓冲区
* @tmp_blk_node: 被释放的缓冲区指针
*
* 将要释放的缓冲区添加到LRU表尾,将一个缓冲区释放回高速缓冲的空闲表中去
*
* 返回值:无
*/
void nand_put_block(struct nand_block_head_s *tmp_blk_node)
{
if (tmp_blk_node) {
if (tmp_blk_node->flags == DATA_VALID) {
list_add_tail(&(tmp_blk_node->lru), &blk_head_lru);
}
} else {
(void)printf("这是个空块\n");
}
}
/**
* nand_write_data — 写入数据
* @tmp_blk_bode: 空闲缓冲区
* @data: 要写入的数据
*
* 向缓冲区写入数据
*
* 返回值:无
*/
void nand_write_data(struct nand_block_head_s *tmp_blk_bode, char *data)
{
struct nand_block_head_s *tmp_node;
if (tmp_blk_bode->flags == DATA_INVALID) {
tmp_blk_bode->flags = DATA_VALID;
(void)printf("write data successfully!\n");
} else {
(void)printf("write data failed!\n");
}
}
/**
* nand_show_hash — 显示hash表
*
* 遍历hash表进行打印
*
* 返回值:无
*/
void nand_show_hash()
{
struct nand_block_head_s *tmp_buf;
struct list_head *head_node, *cur_node;
unsigned long i;
for (i = 0; i < HASH_SIZE; i++) {
head_node = &(blk_head_hashtable[i]);
list_for_each(cur_node, head_node) {
tmp_buf = get_hash_node(cur_node);
if (tmp_buf->flags == DATA_VALID) {
printf("缓存的结点 key = %d, dev = %d, blk_nr = %d, data = %s\n",
i, tmp_buf->dev, tmp_buf->blk_nr, tmp_buf->blk_data);
} else {
printf("缓存的结点 key = %d, dev = %d, blk_nr = %d\n",
i, tmp_buf->dev, tmp_buf->blk_nr);
}
}
}
}
/**
* nand_free_block — 清空缓存区
*
* 遍历每条链表释放缓存区
*
* 返回值:无
*/
void nand_free_block()
{
unsigned long i;
struct list_head *cur_node, *next_node;
struct nand_block_head_s *tmp_buf;
for (i = 0; i < HASH_SIZE; i++) {
list_for_each_safe(cur_node, next_node, &blk_head_hashtable[i]) {
tmp_buf = get_hash_node(cur_node);
list_del_init(cur_node);
free(tmp_buf);
tmp_buf = NULL;
nand_pool_cnt--; /* 清除块计数 */
}
}
INIT_LIST_HEAD(&blk_head_lru);
(void)printf("free done!\n");
}
C
1
https://gitee.com/zengsmallbear/cache_manager.git
git@gitee.com:zengsmallbear/cache_manager.git
zengsmallbear
cache_manager
cache_manager
master

搜索帮助