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