下午没事,写着玩~
明天加上LRU链,用定时器检查资源是否超时,超时就删除。
#include "priv.h"
#include "kt_resource.h"
#define RESOURCE_HASHSIZE (1 << 5)
static struct kmem_cache *Resource_mempool;
static resource_hashtable_t resource_hashtable[RESOURCE_HASHSIZE];
resource_hash_t resource_get_hash(resource_node_t *node)
{
resource_hash_t hash;
hash.hash_pos = node->hash.hash_pos & (RESOURCE_HASHSIZE - 1);
return hash;
}
resource_node_t * resource_alloc(void)
{
resource_node_t *node = NULL;
node = (resource_node_t *)kmem_cache_alloc(Resource_mempool, GFP_ATOMIC);
if(unlikely(!node)){
printk("kmem_cache_alloc failed\n");
}
nos_atomic_set(&node->refcnt, 1);
return node;
}
void resource_free(resource_node_t *node)
{
kmem_cache_free(Resource_mempool, node);
}
void resource_hold(resource_node_t *node)
{
nos_atomic_inc(&(node->refcnt));
}
void resource_put(resource_node_t *node)
{
if(nos_atomic_dec_and_test(&(node->refcnt))){
resource_free(node);
}
}
void resource_insert(resource_node_t *node)
{
ne_u32 hash_pos;
hash_pos = resource_get_hash(node).hash_pos;
nos_spin_lock_bh(&(resource_hashtable + hash_pos)->lock);
ne_list_add_tail(&node->list, &(resource_hashtable + hash_pos)->list);
resource_hold(node);
nos_spin_unlock_bh(&(resource_hashtable + hash_pos)->lock);
}
void resource_remove(resource_node_t *node)
{
ne_u32 hash_pos;
hash_pos = resource_get_hash(node).hash_pos;
nos_spin_lock_bh(&(resource_hashtable + hash_pos)->lock);
ne_list_del(&node->list);
nos_spin_unlock_bh(&(resource_hashtable + hash_pos)->lock);
}
resource_node_t * resource_create(resource_hash_t hash)
{
resource_node_t *node = NULL;
node = resource_alloc();
if(!node)
return NULL;
node->hash.hash_pos = hash.hash_pos;
resource_insert(node);
return node;
}
void resource_destroy(resource_node_t *node)
{
resource_remove(node);
resource_put(node);
}
resource_node_t * resource_lookup(resource_hash_t hash)
{
int i = 0;
resource_node_t *pos = NULL;
ne_u32 hash_pos = hash.hash_pos;
nos_spin_lock_bh(&(resource_hashtable + hash_pos)->lock);
list_for_each_entry(pos, &(resource_hashtable + hash_pos)->list, list){
if(hash_pos != pos->hash.hash_pos)
continue;
resource_hold(pos);
nos_spin_unlock_bh(&(resource_hashtable + hash_pos)->lock);
return pos;
}
nos_spin_unlock_bh(&(resource_hashtable + hash_pos)->lock);
return NULL;
}
int kt_resource_cache_init(void){
int i = 0;
Resource_mempool = kmem_cache_create("RESOURCE_MEMPOOL", sizeof(resource_node_t), 0, SLAB_HWCACHE_ALIGN, NULL);
if(unlikely(!Resource_mempool)){
printk("kmem_cache_create failed\n");
return -1;
}
for(i = 0; i < RESOURCE_HASHSIZE; i++){
nos_spinlock_init(&(resource_hashtable + i)->lock);
NE_INIT_LIST_HEAD(&(resource_hashtable + i)->list);
}
return 0;
}
void kt_resource_cache_fini(void){
int i = 0;
resource_node_t *pos = NULL;
resource_node_t *next = NULL;
for(i = 0; i < RESOURCE_HASHSIZE; i++){
nos_spin_lock_bh(&(resource_hashtable + i)->lock);
list_for_each_entry_safe(pos, next, &(resource_hashtable + i)->list, list){
ne_list_del(&pos->list);
resource_put(pos);
}
nos_spin_unlock_bh(&(resource_hashtable + i)->lock);
}
kmem_cache_destroy(Resource_mempool);
}
#include "priv.h"
int kt_resource_init(void){
int ret;
resource_hash_t hash;
resource_node_t *node = NULL;
ret = kt_resource_cache_init();
if(ret != 0)
return -1;
test:
hash.hash_pos = 1;
node = resource_create(hash);
if(!node)
return -1;
else{
printk("node->hash.hash_pos %d\n", node->hash.hash_pos);
resource_put(node);
}
hash.hash_pos = 2;
node = resource_create(hash);
if(!node)
return -1;
else{
printk("node->hash.hash_pos %d\n", node->hash.hash_pos);
resource_put(node);
}
node = resource_lookup(hash);
if(!node){
printk("not find\n");
return 0;
}else{
printk("node->hash.hash_pos %d\n", node->hash.hash_pos);
resource_put(node);
}
resource_destroy(node);
node = resource_lookup(hash);
if(!node){
printk("not find\n");
return 0;
}else{
printk("node->hash.hash_pos %d\n", node->hash.hash_pos);
}
return 0;
}
void kt_resource_fini(void){
kt_resource_cache_fini();
}
module_init(kt_resource_init);
module_exit(kt_resource_fini);
MODULE_LICENSE("GPL");