mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Limit extfs device cache to 10% of system memory.
This commit is contained in:
parent
4839a97d91
commit
ec990882b0
4 changed files with 63 additions and 16 deletions
|
@ -31,7 +31,17 @@
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "ioleast.h"
|
#include "ioleast.h"
|
||||||
|
|
||||||
|
Block::Block()
|
||||||
|
{
|
||||||
|
this->block_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Block::Block(Device* device, uint32_t block_id)
|
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->modify_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||||
this->transit_done_cond = PTHREAD_COND_INITIALIZER;
|
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->block_id = block_id;
|
||||||
this->dirty = false;
|
this->dirty = false;
|
||||||
this->is_in_transit = false;
|
this->is_in_transit = false;
|
||||||
this->block_data = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Block::~Block()
|
Block::~Block()
|
||||||
|
{
|
||||||
|
Destruct();
|
||||||
|
delete[] block_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::Destruct()
|
||||||
{
|
{
|
||||||
Sync();
|
Sync();
|
||||||
Unlink();
|
Unlink();
|
||||||
delete[] block_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Block::Refer()
|
void Block::Refer()
|
||||||
|
@ -64,12 +78,13 @@ void Block::Refer()
|
||||||
void Block::Unref()
|
void Block::Unref()
|
||||||
{
|
{
|
||||||
if ( !--reference_count )
|
if ( !--reference_count )
|
||||||
|
{
|
||||||
#if 0
|
#if 0
|
||||||
|
device->block_count--;
|
||||||
delete this;
|
delete this;
|
||||||
#else
|
|
||||||
{};
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Block::Sync()
|
void Block::Sync()
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,8 +28,11 @@ class Device;
|
||||||
class Block
|
class Block
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Block();
|
||||||
Block(Device* device, uint32_t block_id);
|
Block(Device* device, uint32_t block_id);
|
||||||
~Block();
|
~Block();
|
||||||
|
void Construct(Device* device, uint32_t block_id);
|
||||||
|
void Destruct();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pthread_mutex_t modify_lock;
|
pthread_mutex_t modify_lock;
|
||||||
|
|
|
@ -61,6 +61,15 @@ Device::Device(int fd, const char* path, uint32_t block_size, bool write)
|
||||||
this->has_sync_thread = false;
|
this->has_sync_thread = false;
|
||||||
this->sync_thread_should_exit = false;
|
this->sync_thread_should_exit = false;
|
||||||
this->sync_in_transit = 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()
|
Device::~Device()
|
||||||
|
@ -88,17 +97,37 @@ void Device::SpawnSyncThread()
|
||||||
pthread_create(&this->sync_thread, NULL, Device__SyncThread, this) == 0;
|
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)
|
Block* Device::GetBlock(uint32_t block_id)
|
||||||
{
|
{
|
||||||
if ( Block* block = GetCachedBlock(block_id) )
|
if ( Block* block = GetCachedBlock(block_id) )
|
||||||
return block;
|
return block;
|
||||||
uint8_t* data = new uint8_t[block_size];
|
Block* block = AllocateBlock();
|
||||||
if ( !data ) // TODO: Use operator new nothrow!
|
if ( !block )
|
||||||
return NULL;
|
return NULL;
|
||||||
Block* block = new Block(this, block_id);
|
block->Construct(this, block_id);
|
||||||
if ( !block ) // TODO: Use operator new nothrow!
|
|
||||||
return delete[] data, (Block*) NULL;
|
|
||||||
block->block_data = data;
|
|
||||||
off_t file_offset = (off_t) block_size * (off_t) block_id;
|
off_t file_offset = (off_t) block_size * (off_t) block_id;
|
||||||
preadall(fd, block->block_data, block_size, file_offset);
|
preadall(fd, block->block_data, block_size, file_offset);
|
||||||
block->Prelink();
|
block->Prelink();
|
||||||
|
@ -115,13 +144,10 @@ Block* Device::GetBlockZeroed(uint32_t block_id)
|
||||||
block->FinishWrite();
|
block->FinishWrite();
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
uint8_t* data = new uint8_t[block_size];
|
Block* block = AllocateBlock();
|
||||||
if ( !data ) // TODO: Use operator new nothrow!
|
if ( !block )
|
||||||
return NULL;
|
return NULL;
|
||||||
Block* block = new Block(this, block_id);
|
block->Construct(this, block_id);
|
||||||
if ( !block ) // TODO: Use operator new nothrow!
|
|
||||||
return delete[] data, (Block*) NULL;
|
|
||||||
block->block_data = data;
|
|
||||||
memset(block->block_data, 0, block_size);
|
memset(block->block_data, 0, block_size);
|
||||||
block->Prelink();
|
block->Prelink();
|
||||||
block->BeginWrite();
|
block->BeginWrite();
|
||||||
|
|
|
@ -50,9 +50,12 @@ public:
|
||||||
bool has_sync_thread;
|
bool has_sync_thread;
|
||||||
bool sync_thread_should_exit;
|
bool sync_thread_should_exit;
|
||||||
bool sync_in_transit;
|
bool sync_in_transit;
|
||||||
|
size_t block_count;
|
||||||
|
size_t block_limit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void SpawnSyncThread();
|
void SpawnSyncThread();
|
||||||
|
Block* AllocateBlock();
|
||||||
Block* GetBlock(uint32_t block_id);
|
Block* GetBlock(uint32_t block_id);
|
||||||
Block* GetBlockZeroed(uint32_t block_id);
|
Block* GetBlockZeroed(uint32_t block_id);
|
||||||
Block* GetCachedBlock(uint32_t block_id);
|
Block* GetCachedBlock(uint32_t block_id);
|
||||||
|
|
Loading…
Reference in a new issue