kernel/fs: Refactor EntryCache to not use constant array sizes.

Instead set them in the Init functions. For now, the same
hard-coded sizes are used, so aside from slightly increased storage
on two classes (or not even due to padding), this has no functional change.
This commit is contained in:
Augustin Cavalier 2022-08-03 17:43:12 -04:00
parent d02c0bade7
commit 25866ebeeb
2 changed files with 28 additions and 20 deletions

View File

@ -9,8 +9,6 @@
#include <new>
static const int32 kEntriesPerGeneration = 1024;
static const int32 kEntryNotInArray = -1;
static const int32 kEntryRemoved = -2;
@ -33,14 +31,14 @@ EntryCacheGeneration::~EntryCacheGeneration()
status_t
EntryCacheGeneration::Init()
EntryCacheGeneration::Init(int32 entriesSize)
{
entries = new(std::nothrow) EntryCacheEntry*[kEntriesPerGeneration];
entries_size = entriesSize;
entries = new(std::nothrow) EntryCacheEntry*[entries_size];
if (entries == NULL)
return B_NO_MEMORY;
memset(entries, 0, sizeof(EntryCacheEntry*) * kEntriesPerGeneration);
memset(entries, 0, sizeof(EntryCacheEntry*) * entries_size);
return B_OK;
}
@ -67,6 +65,7 @@ EntryCache::~EntryCache()
free(entry);
entry = next;
}
delete[] fGenerations;
rw_lock_destroy(&fLock);
}
@ -79,8 +78,12 @@ EntryCache::Init()
if (error != B_OK)
return error;
for (int32 i = 0; i < kGenerationCount; i++) {
error = fGenerations[i].Init();
fGenerationCount = 8;
int32 entriesSize = 1024;
fGenerations = new(std::nothrow) EntryCacheGeneration[fGenerationCount];
for (int32 i = 0; i < fGenerationCount; i++) {
error = fGenerations[i].Init(entriesSize);
if (error != B_OK)
return error;
}
@ -96,6 +99,9 @@ EntryCache::Add(ino_t dirID, const char* name, ino_t nodeID, bool missing)
WriteLocker _(fLock);
if (fGenerationCount == 0)
return B_NO_MEMORY;
EntryCacheEntry* entry = fEntries.Lookup(key);
if (entry != NULL) {
entry->node_id = nodeID;
@ -168,8 +174,8 @@ EntryCache::Lookup(ino_t dirID, const char* name, ino_t& _nodeID,
if (entry == NULL)
return false;
int32 oldGeneration = atomic_get_and_set(&entry->generation,
fCurrentGeneration);
const int32 oldGeneration = atomic_get_and_set(&entry->generation,
fCurrentGeneration);
if (oldGeneration == fCurrentGeneration || entry->index < 0) {
// The entry is already in the current generation or is being moved to
// it by another thread.
@ -183,8 +189,8 @@ EntryCache::Lookup(ino_t dirID, const char* name, ino_t& _nodeID,
entry->index = kEntryNotInArray;
// add to the current generation
int32 index = atomic_add(&fGenerations[oldGeneration].next_index, 1);
if (index < kEntriesPerGeneration) {
const int32 index = atomic_add(&fGenerations[oldGeneration].next_index, 1);
if (index < fGenerations[fCurrentGeneration].entries_size) {
fGenerations[fCurrentGeneration].entries[index] = entry;
entry->index = index;
_nodeID = entry->node_id;
@ -230,9 +236,11 @@ EntryCache::DebugReverseLookup(ino_t nodeID, ino_t& _dirID)
void
EntryCache::_AddEntryToCurrentGeneration(EntryCacheEntry* entry)
{
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
// the generation might not be full yet
int32 index = fGenerations[fCurrentGeneration].next_index++;
if (index < kEntriesPerGeneration) {
if (index < fGenerations[fCurrentGeneration].entries_size) {
fGenerations[fCurrentGeneration].entries[index] = entry;
entry->generation = fCurrentGeneration;
entry->index = index;
@ -240,8 +248,8 @@ EntryCache::_AddEntryToCurrentGeneration(EntryCacheEntry* entry)
}
// we have to clear the oldest generation
int32 newGeneration = (fCurrentGeneration + 1) % kGenerationCount;
for (int32 i = 0; i < kEntriesPerGeneration; i++) {
const int32 newGeneration = (fCurrentGeneration + 1) % fGenerationCount;
for (int32 i = 0; i < fGenerations[newGeneration].entries_size; i++) {
EntryCacheEntry* otherEntry = fGenerations[newGeneration].entries[i];
if (otherEntry == NULL)
continue;
@ -253,8 +261,8 @@ EntryCache::_AddEntryToCurrentGeneration(EntryCacheEntry* entry)
// set the new generation and add the entry
fCurrentGeneration = newGeneration;
fGenerations[newGeneration].next_index = 1;
fGenerations[newGeneration].entries[0] = entry;
fGenerations[newGeneration].next_index = 1;
entry->generation = newGeneration;
entry->index = 0;
}

View File

@ -44,12 +44,13 @@ struct EntryCacheEntry {
struct EntryCacheGeneration {
int32 next_index;
int32 entries_size;
EntryCacheEntry** entries;
EntryCacheGeneration();
~EntryCacheGeneration();
status_t Init();
status_t Init(int32 entriesSize);
};
@ -99,8 +100,6 @@ public:
const char* DebugReverseLookup(ino_t nodeID, ino_t& _dirID);
private:
static const int32 kGenerationCount = 8;
typedef BOpenHashTable<EntryCacheHashDefinition> EntryTable;
typedef DoublyLinkedList<EntryCacheEntry> EntryList;
@ -111,7 +110,8 @@ private:
private:
rw_lock fLock;
EntryTable fEntries;
EntryCacheGeneration fGenerations[kGenerationCount];
int32 fGenerationCount;
EntryCacheGeneration* fGenerations;
int32 fCurrentGeneration;
};