📄 cache.c
字号:
/***********************************************************************/
/* */
/* Module: cache.c */
/* Release: 2004.5 */
/* Version: 2004.2 */
/* Purpose: Cache interface for the file systems */
/* */
/*---------------------------------------------------------------------*/
/* */
/* Copyright 2004, Blunk Microsystems */
/* ALL RIGHTS RESERVED */
/* */
/* Licensees have the non-exclusive right to use, modify, or extract */
/* this computer program for software development at a single site. */
/* This program may be resold or disseminated in executable format */
/* only. The source code may not be redistributed or resold. */
/* */
/***********************************************************************/
#include "posixfsp.h"
#include "../include/cache.h"
/***********************************************************************/
/* Local Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* remove_from_replacer: Remove specified entry from cache LRU list */
/* */
/* Inputs: entry = pointer to cache entry */
/* C = cache to which LRU list belongs */
/* */
/***********************************************************************/
static void remove_from_replacer(CacheEntry *entry, Cache *C)
{
/*-------------------------------------------------------------------*/
/* Adjust the double linked list (LRU) by taking the entry out. */
/*-------------------------------------------------------------------*/
if (entry->prev_lru)
entry->prev_lru->next_lru = entry->next_lru;
else
C->lru_head = entry->next_lru;
if (entry->next_lru)
entry->next_lru->prev_lru = entry->prev_lru;
else
C->lru_tail = entry->prev_lru;
/*-------------------------------------------------------------------*/
/* Null out the pointers for the taken out entry. */
/*-------------------------------------------------------------------*/
entry->prev_lru = entry->next_lru = NULL;
}
/***********************************************************************/
/* put_into_tail: Add an entry to the end of the linked list */
/* */
/* Inputs: entry = pointer to cache entry to be added */
/* C = cache to which the list belongs */
/* */
/***********************************************************************/
static void put_into_tail(CacheEntry *entry, Cache *C)
{
/*-------------------------------------------------------------------*/
/* Set next to NULL since entry will be last entry, and prev to what */
/* tail of list was before. */
/*-------------------------------------------------------------------*/
entry->next_lru = NULL;
entry->prev_lru = C->lru_tail;
/*-------------------------------------------------------------------*/
/* If the list was not empty, set the next of tail to new entry, */
/* else, because list was empty, set also head of list to new entry. */
/*-------------------------------------------------------------------*/
if (C->lru_tail)
C->lru_tail->next_lru = entry;
else
C->lru_head = entry;
/*-------------------------------------------------------------------*/
/* Set tail of list to new entry. */
/*-------------------------------------------------------------------*/
C->lru_tail = entry;
}
/***********************************************************************/
/* hash: Hash based on the sector number */
/* */
/* Inputs: sector_number = value on which hash is done */
/* size = size of the table */
/* */
/* Returns: Index into the hash table where value gets hashed */
/* */
/***********************************************************************/
static int hash(int sector_number, int size)
{
return (19823 * sector_number + 321043) % size;
}
/***********************************************************************/
/* Global Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* InitCache: Initialize and allocate memory for the specified cache */
/* */
/* Inputs: C = cache to be initialized */
/* pool_size = number of sectors in the cache */
/* writef = write sector function */
/* readf = read sector function */
/* sect_sz = sector size for file system */
/* temp_sects = number of temporary sectors */
/* alignment = memory alignment */
/* */
/* Returns: Beginning of pool on success, 0 on failure */
/* */
/***********************************************************************/
ui32 InitCache(Cache *C, int pool_size, MedWFunc writef, MedRFunc readf,
int sect_sz, int temp_sects, int alignment)
{
ui32 *sectors;
/*-------------------------------------------------------------------*/
/* Set the write and read functions for the cache. */
/*-------------------------------------------------------------------*/
C->write = writef;
C->read = readf;
/*-------------------------------------------------------------------*/
/* Set the number of sectors in cache. */
/*-------------------------------------------------------------------*/
C->pool_size = pool_size;
/*-------------------------------------------------------------------*/
/* Allocate memory for the pool and hash table. */
/*-------------------------------------------------------------------*/
C->pool = calloc((size_t)C->pool_size * sizeof(CacheEntry), (size_t)1);
if (C->pool == NULL)
return 0;
C->hash_tbl = calloc((size_t)C->pool_size * sizeof(CacheEntry *),
(size_t)1);
if (C->hash_tbl == NULL)
{
free(C->pool);
return 0;
}
/*-------------------------------------------------------------------*/
/* Allocate memory for all the sectors. This is where data goes. */
/* Also, allocate extra sectors for use by file sys. internals. */
/* Pointers to extra sectors will be set in file system init routine.*/
/*-------------------------------------------------------------------*/
sectors = calloc((size_t)(sect_sz * (C->pool_size + temp_sects) /
alignment), (size_t)alignment);
if (sectors == NULL)
{
free(C->pool);
free(C->hash_tbl);
return 0;
}
/*-------------------------------------------------------------------*/
/* Initialize the pool for the cache. */
/*-------------------------------------------------------------------*/
C->pool[0].sector = (ui8 *)sectors;
ReinitCache(C, sect_sz);
return (ui32)sectors;
}
/***********************************************************************/
/* ReinitCache: Re-initialize the cache */
/* */
/* Inputs: C = cache to be reinitialized */
/* sect_sz = sector size for file system */
/* */
/***********************************************************************/
void ReinitCache(Cache *C, int sect_sz)
{
int i;
ui8 *mem = C->pool[0].sector;
/*-------------------------------------------------------------------*/
/* Loop to initialize each entry in the cache. */
/*-------------------------------------------------------------------*/
for (i = 0; i < C->pool_size; ++i)
{
/*-----------------------------------------------------------------*/
/* Assign a sector chunk of the preallocated memory. */
/*-----------------------------------------------------------------*/
C->pool[i].sector = mem;
mem += sect_sz;
/*-----------------------------------------------------------------*/
/* Set the entry in the pool to have an invalid sector number, -1, */
/* not dirty, 0 pin count, no hash location and file_ptr. */
/*-----------------------------------------------------------------*/
C->pool[i].sect_num = -1;
C->pool[i].dirty = CLEAN;
C->pool[i].pin_cnt = 0;
C->pool[i].hash_loc = NULL;
C->pool[i].file_ptr = NULL;
/*-----------------------------------------------------------------*/
/* If the first entry in pool, set its prev_lru to NULL. */
/*-----------------------------------------------------------------*/
if (!i)
{
C->pool[i].prev_lru = NULL;
if (C->pool_size == 1)
C->pool[i].next_lru = NULL;
else
C->pool[i].next_lru = &C->pool[i + 1];
}
/*-----------------------------------------------------------------*/
/* Else if last entry in pool, set its next_lru to NULL. */
/*-----------------------------------------------------------------*/
else if (i == (C->pool_size - 1))
{
C->pool[i].prev_lru = &C->pool[i - 1];
C->pool[i].next_lru = NULL;
}
/*-----------------------------------------------------------------*/
/* Else set prev_lru to previous and next_lru to next entry. */
/*-----------------------------------------------------------------*/
else
{
C->pool[i].prev_lru = &C->pool[i - 1];
C->pool[i].next_lru = &C->pool[i + 1];
}
/*-----------------------------------------------------------------*/
/* Initialize also the hash table entry. */
/*-----------------------------------------------------------------*/
C->pool[i].next_hash = C->pool[i].prev_hash = NULL;
C->pool[i].hash_loc = NULL;
C->hash_tbl[i] = NULL;
}
/*-------------------------------------------------------------------*/
/* Set the dirty flags. */
/*-------------------------------------------------------------------*/
C->dirty_old = C->dirty_new = FALSE;
/*-------------------------------------------------------------------*/
/* Initialize the current sector being worked on. */
/*-------------------------------------------------------------------*/
C->sector_number = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -