upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp58
1 files changed, 52 insertions, 6 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 2581578..9ee056f 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -10,6 +10,7 @@
10#undef snprintf 10#undef snprintf
11#endif 11#endif
12#include "headers.h" 12#include "headers.h"
13#include <thread> // hardware_concurrency, for the miner thread count
13#ifdef _WIN32 14#ifdef _WIN32
14#include <winsock2.h> 15#include <winsock2.h>
15#endif 16#endif
@@ -1224,18 +1225,63 @@ void ThreadMessageHandler2(void* parg)
1224 1225
1225 1226
1226 1227
1227//// todo: start one thread per processor, use getenv("NUMBER_OF_PROCESSORS") 1228// Satoshi's "todo: start one thread per processor" stood here since 2009 and is
1229// what MinerThreadCount() and StartMinerThreads() below finally do -- by way of
1230// std::thread::hardware_concurrency rather than NUMBER_OF_PROCESSORS, which only
1231// ever existed on Windows.
1232//
1233// Miners share slot 3 of vfThreadRunning, and StopNode waits for every slot to
1234// go false before the node tears the database down. With one miner that was the
1235// same thing as "the miner finished"; with several, the first one out would
1236// announce that everybody had finished while the rest were still hashing and
1237// still calling ProcessBlock. So count them, and let only the last one leaving
1238// clear the flag.
1239static CCriticalSection cs_nMinersRunning;
1240static int nMinersRunning = 0;
1241
1228void ThreadBitcoinMiner(void* parg) 1242void ThreadBitcoinMiner(void* parg)
1229{ 1243{
1230 vfThreadRunning[3] = true; 1244 int nThreadId = (int)(intptr_t)parg;
1231 CheckForShutdown(3); 1245 CRITICAL_BLOCK(cs_nMinersRunning)
1246 {
1247 nMinersRunning++;
1248 vfThreadRunning[3] = true;
1249 }
1232 try 1250 try
1233 { 1251 {
1234 bool fRet = BitcoinMiner(); 1252 bool fRet = BitcoinMiner(nThreadId);
1235 printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); 1253 printf("BitcoinMiner thread %d returned %s\n", nThreadId, fRet ? "true" : "false");
1236 } 1254 }
1237 CATCH_PRINT_EXCEPTION("BitcoinMiner()") 1255 CATCH_PRINT_EXCEPTION("BitcoinMiner()")
1238 vfThreadRunning[3] = false; 1256 CRITICAL_BLOCK(cs_nMinersRunning)
1257 {
1258 if (--nMinersRunning <= 0)
1259 {
1260 nMinersRunning = 0;
1261 vfThreadRunning[3] = false;
1262 }
1263 }
1264}
1265
1266// Start the miners. Returns how many actually got off the ground.
1267int StartMinerThreads()
1268{
1269 int nThreads = MinerThreadCount();
1270 int nStarted = 0;
1271 for (int i = 0; i < nThreads; i++)
1272 {
1273 if (_beginthread(ThreadBitcoinMiner, 0, (void*)(intptr_t)(i + 1)) == (uintptr_t)-1)
1274 printf("Error: _beginthread(ThreadBitcoinMiner) failed on thread %d\n", i + 1);
1275 else
1276 nStarted++;
1277 }
1278 // The dataset is one allocation shared by all of them; only the 2 MB
1279 // scratchpads multiply. Printed because "why is it using 2 GB" is the first
1280 // question anyone asks.
1281 printf("Mining with %d thread(s) of %u core(s) -- about %d MB "
1282 "(~2080 MB shared RandomX dataset + ~2 MB per thread)\n",
1283 nStarted, std::thread::hardware_concurrency(), 2080 + 2 * nStarted);
1284 return nStarted;
1239} 1285}
1240 1286
1241 1287