Limit extfs device cache to 10% of system memory.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-09-27 16:50:12 +02:00
parent 4839a97d91
commit ec990882b0
4 changed files with 63 additions and 16 deletions

View File

@ -31,7 +31,17 @@
#include "device.h"
#include "ioleast.h"
Block::Block()
{
this->block_data = NULL;
}
Block::Block(Device* device, uint32_t block_id)
{
Construct(device, block_id);
}
void Block::Construct(Device* device, uint32_t block_id)
{
this->modify_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
this->transit_done_cond = PTHREAD_COND_INITIALIZER;
@ -46,14 +56,18 @@ Block::Block(Device* device, uint32_t block_id)
this->block_id = block_id;
this->dirty = false;
this->is_in_transit = false;
this->block_data = NULL;
}
Block::~Block()
{
Destruct();
delete[] block_data;
}
void Block::Destruct()
{
Sync();
Unlink();
delete[] block_data;
}
void Block::Refer()
@ -64,11 +78,12 @@ void Block::Refer()
void Block::Unref()
{
if ( !--reference_count )
{
#if 0
device->block_count--;
delete this;
#else
{};
#endif
}
}
void Block::Sync()

View File

@ -28,8 +28,11 @@ class Device;
class Block
{
public:
Block();
Block(Device* device, uint32_t block_id);
~Block();
void Construct(Device* device, uint32_t block_id);
void Destruct();
public:
pthread_mutex_t modify_lock;

View File

@ -61,6 +61,15 @@ Device::Device(int fd, const char* path, uint32_t block_size, bool write)
this->has_sync_thread = false;
this->sync_thread_should_exit = false;
this->sync_in_transit = false;
this->block_count = 0;
#ifdef __sortix__
// TODO: This isn't scaleable if there's multiple filesystems mounted.
size_t memory;
memstat(NULL, &memory);
this->block_limit = (memory / 10) / block_size;
#else
this->block_limit = 32768;
#endif
}
Device::~Device()
@ -88,17 +97,37 @@ void Device::SpawnSyncThread()
pthread_create(&this->sync_thread, NULL, Device__SyncThread, this) == 0;
}
Block* Device::AllocateBlock()
{
if ( block_limit <= block_count )
{
for ( Block* block = lru_block; block; block = block->prev_block )
{
if ( block->reference_count )
continue;
block->Destruct(); // Syncs.
return block;
}
}
uint8_t* data = new uint8_t[block_size];
if ( !data ) // TODO: Use operator new nothrow!
return NULL;
Block* block = new Block();
if ( !block ) // TODO: Use operator new nothrow!
return delete[] data, (Block*) NULL;
block->block_data = data;
block_count++;
return block;
}
Block* Device::GetBlock(uint32_t block_id)
{
if ( Block* block = GetCachedBlock(block_id) )
return block;
uint8_t* data = new uint8_t[block_size];
if ( !data ) // TODO: Use operator new nothrow!
Block* block = AllocateBlock();
if ( !block )
return NULL;
Block* block = new Block(this, block_id);
if ( !block ) // TODO: Use operator new nothrow!
return delete[] data, (Block*) NULL;
block->block_data = data;
block->Construct(this, block_id);
off_t file_offset = (off_t) block_size * (off_t) block_id;
preadall(fd, block->block_data, block_size, file_offset);
block->Prelink();
@ -115,13 +144,10 @@ Block* Device::GetBlockZeroed(uint32_t block_id)
block->FinishWrite();
return block;
}
uint8_t* data = new uint8_t[block_size];
if ( !data ) // TODO: Use operator new nothrow!
Block* block = AllocateBlock();
if ( !block )
return NULL;
Block* block = new Block(this, block_id);
if ( !block ) // TODO: Use operator new nothrow!
return delete[] data, (Block*) NULL;
block->block_data = data;
block->Construct(this, block_id);
memset(block->block_data, 0, block_size);
block->Prelink();
block->BeginWrite();

View File

@ -50,9 +50,12 @@ public:
bool has_sync_thread;
bool sync_thread_should_exit;
bool sync_in_transit;
size_t block_count;
size_t block_limit;
public:
void SpawnSyncThread();
Block* AllocateBlock();
Block* GetBlock(uint32_t block_id);
Block* GetBlockZeroed(uint32_t block_id);
Block* GetCachedBlock(uint32_t block_id);