Skip to content

Commit

Permalink
limit max thread count to 126
Browse files Browse the repository at this point in the history
When the number of threads is higher than 126 the number of LMDB locks
is exhausted and `ArmoryDB` dies with the error:

```
MDB_READERS_FULL: Environment maxreaders limit reached
```

See:
lmdbjava/lmdbjava#65 (comment)

Replace the uses of `std::thread::hardware_concurrency()` with a new
function `MAX_THREADS()` which limits the number of threads to `126`.

This is a temporary fix, the real fix would be making sure the number of
LMDB locks is sufficient.

However, a configured value for the maximum number of threads would also
be useful.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
  • Loading branch information
rkitover committed Aug 24, 2019
1 parent 4f1d7f1 commit e3d97d5
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 6 deletions.
2 changes: 1 addition & 1 deletion cppForSwig/BDM_Server.cpp
Expand Up @@ -1848,7 +1848,7 @@ void Clients::init(BlockDataManagerThread* bdmT,
unsigned innerThreadCount = 2;
if (BlockDataManagerConfig::getDbType() == ARMORY_DB_SUPER &&
BlockDataManagerConfig::getOperationMode() != OPERATION_UNITTEST)
innerThreadCount = thread::hardware_concurrency();
innerThreadCount = MAX_THREADS();
for (unsigned i = 0; i < innerThreadCount; i++)
{
controlThreads_.push_back(thread(innerthread));
Expand Down
14 changes: 14 additions & 0 deletions cppForSwig/BlockDataManagerConfig.cpp
Expand Up @@ -20,6 +20,20 @@

using namespace std;

size_t MAX_THREADS()
{
size_t cpu_threads = std::thread::hardware_concurrency();

if (!cpu_threads)
return 1;
// there are only 126 LMDB locks by default
// FIXME: need to increase number of LMDB locks
else if (cpu_threads > 126)
return 126;

return cpu_threads;
}

////////////////////////////////////////////////////////////////////////////////
//
// NodeStatusStruct
Expand Down
4 changes: 3 additions & 1 deletion cppForSwig/BlockDataManagerConfig.h
Expand Up @@ -28,6 +28,8 @@
#define DEFAULT_ZCTHREAD_COUNT 100
#define WEBSOCKET_PORT 7681

size_t MAX_THREADS();

class BitcoinP2P;

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -66,7 +68,7 @@ struct BlockDataManagerConfig
bool customBtcPort_ = false;

unsigned ramUsage_ = 4;
unsigned threadCount_ = std::thread::hardware_concurrency();
unsigned threadCount_ = MAX_THREADS();
unsigned zcThreadCount_ = DEFAULT_ZCTHREAD_COUNT;

std::exception_ptr exceptionPtr_ = nullptr;
Expand Down
4 changes: 2 additions & 2 deletions cppForSwig/Server.cpp
Expand Up @@ -234,7 +234,7 @@ void WebSocketServer::start(BlockDataManagerThread* bdmT,
instance->clientInterruptThread();
};

unsigned parserThreads = thread::hardware_concurrency() / 4;
unsigned parserThreads = MAX_THREADS() / 4;
if (parserThreads == 0)
parserThreads = 1;
for (unsigned i = 0; i < parserThreads; i++)
Expand Down Expand Up @@ -1038,4 +1038,4 @@ void ClientConnection::processAEADHandshake(BinaryData msg)
void ClientConnection::closeConnection()
{
run_->store(-1, memory_order_relaxed);
}
}
4 changes: 2 additions & 2 deletions cppForSwig/ZeroConf.cpp
Expand Up @@ -290,7 +290,7 @@ void ZeroConfContainer::preprocessZcMap(
};

vector<thread> parserThreads;
for (unsigned i = 1; i < thread::hardware_concurrency(); i++)
for (unsigned i = 1; i < MAX_THREADS(); i++)
parserThreads.push_back(thread(parserLdb));
parserLdb();

Expand Down Expand Up @@ -2111,4 +2111,4 @@ bool ZcUpdateBatch::hasData() const
return true;

return false;
}
}

0 comments on commit e3d97d5

Please sign in to comment.