Skip to content

Commit

Permalink
class
Browse files Browse the repository at this point in the history
  • Loading branch information
YourBroDuke committed Jan 7, 2019
1 parent ed4c9aa commit ac90493
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 6 deletions.
2 changes: 1 addition & 1 deletion include/zjunix/mfs/fat32.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ struct mem_page {

u8 *p_data;
u8 state;
u32 p_block_number;
u32 abs_sector_num;
struct list_head p_hashlist;
struct list_head p_LRU;
};
Expand Down
6 changes: 6 additions & 0 deletions include/zjunix/mfs/fat32cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ struct P_cache {
};

u32 init_cache();
struct mem_dentry * dcache_lookup(struct D_cache *dcache, u32 sector_num, u32 offset);
struct mem_page * pcache_lookup(struct P_cache *pcache, struct mem_page *data);
void dcache_add(struct D_cache *dcache, struct mem_dentry *data);
void pcache_add(struct P_cache *pcache, struct mem_page* data);
void dcache_drop(struct D_cache *dcache);
void pcache_drop(struct P_cache *pcache);

u32 __intHash(u32 key, u32 size);

#endif
108 changes: 103 additions & 5 deletions kernel/mfs/fat32cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,118 @@ u32 init_cache() {
}
}

void dcache_add(struct D_cache *dcache, struct mem_dentry *data)
{
u32 hash = __intHash(data->abs_sector_num * 16 + data->sector_dentry_offset, C_TABLESIZE);
struct mem_dentry * dcache_lookup(struct D_cache *dcache, u32 sector_num, u32 offset) {
struct list_head *table_head;
struct list_head *crt_node;
struct mem_dentry *crt_entry;

u32 hash = __intHash(sector_num * DENTRY_PER_SEC + offset, C_TABLESIZE);

table_head = &(dcache->c_hashtable[hash]);

list_for_each(crt_node, table_head) {
crt_entry = list_entry(crt_node, struct mem_dentry, d_hashlist);
if (crt_entry->abs_sector_num == sector_num && crt_entry->sector_dentry_offset == offset) {
break;
}
}

// Update LRU list
if (crt_node != table_head) {
list_del(&(crt_entry->d_LRU));
list_add(&(crt_entry->d_LRU), &(dcache->c_LRU));
return crt_entry;
} else {
return 0;
}
}

struct mem_page * pcache_lookup(struct P_cache *pcache, u32 sector_num) {
struct list_head *table_head;
struct list_head *crt_node;
struct mem_page *crt_page;

u32 hash = __intHash(sector_num, C_TABLESIZE);

table_head = &(pcache->c_hashtable[hash]);

list_for_each(crt_node, table_head) {
crt_page = list_entry(crt_node, struct mem_page, p_hashlist);
if (crt_page->abs_sector_num == sector_num) {
break;
}
}

// Update LRU list
if (crt_node != table_head) {
list_del(&(crt_page->p_LRU));
list_add(&(crt_page->p_LRU), &(pcache->c_LRU));
return crt_page;
} else {
return 0;
}
}

void dcache_add(struct D_cache *dcache, struct mem_dentry *data) {
u32 hash = __intHash(data->abs_sector_num * DENTRY_PER_SEC + data->sector_dentry_offset, C_TABLESIZE);

if (dcache->crt_size == dcache->max_capacity) {
// dcache_drop_LRU(dcache);
dcache_drop(dcache);
}

list_add(&(data->d_hashlist), dcache->c_hashtable+hash);
list_add(&(data->d_LRU), &(dcache->c_LRU))
list_add(&(data->d_LRU), &(dcache->c_LRU));

dcache->crt_size++;
}

void pcache_add(sruct P_cache *pcache, struct mem_page *data) {
u32 hash = __intHash(data->abs_sector_num, C_TABLESIZE);

if (pcache->crt_size == pcache->max_capacity) {
pcache_drop(pcache)
}

list_add(&(data->p_hashlist), pcache->c_hashtable+hash);
list_add(&(data->p_LRU), &(pcache->p_LRU));

pcache->crt_size++;
}

void dcache_drop(struct D_cache *dcache) {
struct list_head *LRU_head = &(dcache->c_LRU);
struct list_head *victim = LRU_head->prev;
struct mem_dentry *crt_entry;

if (dcache->crt_size == 0 || dcache->crt_size == 1) return;
else {
crt_entry = list_entry(victim, struct mem_dentry, d_LRU);
if (crt_entry->is_root == 1) {
victim = victim->prev;
crt_entry = list_entry(victim, struct mem_dentry, d_LRU);
}
list_del(victim);
list_del(&(crt_entry->d_hashlist));
kfree(crt_entry);
dcache->crt_size--;
}
}

void pcache_drop(struct P_cache *pcache) {
struct list_head *LRU_head = &(pcache->c_LRU);
struct list_head *victim = LRU_head->prev;
struct mem_page *crt_page;

if (pcache->crt_size == 0) return;
else {
crt_page = list_entry(victim, struct mem_page, p_LRU);
list_del(victim);
list_del(&(crt_page->p_hashlist));
kfree(crt_page->p_data);
pcache->crt_size--;
}
}

u32 __intHash(u32 key, u32 size) {
u32 mask = size - 1;
return key & mask;
Expand Down

0 comments on commit ac90493

Please sign in to comment.