Browse Source

rwlocks

pull/1/head
Pieter Wuille 13 years ago
parent
commit
d0d24282b3
  1. 4
      db.h
  2. 16
      main.cpp
  3. 21
      util.h

4
db.h

@ -85,7 +85,7 @@ public:
IMPLEMENT_SERIALIZE (({ IMPLEMENT_SERIALIZE (({
int nVersion = 0; int nVersion = 0;
READWRITE(nVersion); READWRITE(nVersion);
CRITICAL_BLOCK(cs) { SHARED_CRITICAL_BLOCK(cs) {
if (fWrite) { if (fWrite) {
CAddrDb *db = const_cast<CAddrDb*>(this); CAddrDb *db = const_cast<CAddrDb*>(this);
int nOur = ourId.size(); int nOur = ourId.size();
@ -158,7 +158,7 @@ public:
return Get_(ip, wait); return Get_(ip, wait);
} }
void GetIPs(std::set<CIP>& ips, int max, bool fOnlyIPv4 = true) { void GetIPs(std::set<CIP>& ips, int max, bool fOnlyIPv4 = true) {
CRITICAL_BLOCK(cs) SHARED_CRITICAL_BLOCK(cs)
GetIPs_(ips, max, fOnlyIPv4); GetIPs_(ips, max, fOnlyIPv4);
} }
}; };

16
main.cpp

@ -3,6 +3,8 @@
#include "bitcoin.h" #include "bitcoin.h"
#include "db.h" #include "db.h"
#define NTHREADS 100
using namespace std; using namespace std;
extern "C" { extern "C" {
@ -17,7 +19,9 @@ extern "C" void* ThreadCrawler(void* data) {
CIPPort ip; CIPPort ip;
int wait = 5; int wait = 5;
if (!db.Get(ip, wait)) { if (!db.Get(ip, wait)) {
Sleep(wait*1000); wait *= 1000;
wait += rand() % (500 * NTHREADS);
Sleep(wait);
continue; continue;
} }
int ban = 0; int ban = 0;
@ -75,13 +79,13 @@ int main(void) {
for (vector<CIP>::iterator it = ips.begin(); it != ips.end(); it++) { for (vector<CIP>::iterator it = ips.begin(); it != ips.end(); it++) {
db.Add(CIPPort(*it, 8333)); db.Add(CIPPort(*it, 8333));
} }
pthread_t thread[NTHREADS]; pthread_t thread[NTHREADS+2];
for (int i=0; i<NTHREADS-2; i++) { for (int i=0; i<NTHREADS; i++) {
pthread_create(&thread[i], NULL, ThreadCrawler, NULL); pthread_create(&thread[i], NULL, ThreadCrawler, NULL);
} }
pthread_create(&thread[NTHREADS-2], NULL, ThreadDumper, NULL); pthread_create(&thread[NTHREADS], NULL, ThreadDumper, NULL);
pthread_create(&thread[NTHREADS-1], NULL, ThreadDNS, NULL); pthread_create(&thread[NTHREADS+1], NULL, ThreadDNS, NULL);
for (int i=0; i<NTHREADS; i++) { for (int i=0; i<NTHREADS+2; i++) {
void* res; void* res;
pthread_join(thread[i], &res); pthread_join(thread[i], &res);
} }

21
util.h

@ -45,12 +45,18 @@ inline int myclosesocket(SOCKET& hSocket)
class CCriticalSection class CCriticalSection
{ {
protected: protected:
pthread_mutex_t mutex; pthread_rwlock_t mutex;
public: public:
explicit CCriticalSection() { pthread_mutex_init(&mutex, NULL); } explicit CCriticalSection() { pthread_rwlock_init(&mutex, NULL); }
~CCriticalSection() { pthread_mutex_destroy(&mutex); } ~CCriticalSection() { pthread_rwlock_destroy(&mutex); }
void Enter() { pthread_mutex_lock(&mutex); } void Enter(bool fShared = false) {
void Leave() { pthread_mutex_unlock(&mutex); } if (fShared) {
pthread_rwlock_rdlock(&mutex);
} else {
pthread_rwlock_wrlock(&mutex);
}
}
void Leave() { pthread_rwlock_unlock(&mutex); }
}; };
// Automatically leave critical section when leaving block, needed for exception safety // Automatically leave critical section when leaving block, needed for exception safety
@ -59,7 +65,7 @@ class CCriticalBlock
protected: protected:
CCriticalSection* pcs; CCriticalSection* pcs;
public: public:
CCriticalBlock(CCriticalSection& cs) : pcs(&cs) { pcs->Enter(); } CCriticalBlock(CCriticalSection& cs, bool fShared = false) : pcs(&cs) { pcs->Enter(fShared); }
operator bool() const { return true; } operator bool() const { return true; }
~CCriticalBlock() { pcs->Leave(); } ~CCriticalBlock() { pcs->Leave(); }
}; };
@ -67,6 +73,9 @@ public:
#define CRITICAL_BLOCK(cs) \ #define CRITICAL_BLOCK(cs) \
if (CCriticalBlock criticalblock = CCriticalBlock(cs)) if (CCriticalBlock criticalblock = CCriticalBlock(cs))
#define SHARED_CRITICAL_BLOCK(cs) \
if (CCriticalBlock criticalblock = CCriticalBlock(cs, true))
template<typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend) template<typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend)
{ {
static unsigned char pblank[1]; static unsigned char pblank[1];

Loading…
Cancel
Save