PIMutex as std::mutex

This commit is contained in:
2020-07-17 11:14:11 +03:00
parent ea624a5111
commit 6f5c864e9f
7 changed files with 130 additions and 432 deletions

View File

@@ -26,9 +26,12 @@
#ifdef PIP_STD_IOSTREAM #ifdef PIP_STD_IOSTREAM
# include <iostream> # include <iostream>
#endif #endif
#include <atomic>
#include <mutex>
typedef std::mutex PIMutex;
class PIObject; class PIObject;
class PIMutex; //class PIMutex;
class PIString; class PIString;
class PIByteArray; class PIByteArray;
class PIInit; class PIInit;

View File

@@ -23,7 +23,7 @@
#include "pibase.h" #include "pibase.h"
class PIString; class PIString;
class PIMutex; //class PIMutex;
class PIThread; class PIThread;
class PITimer; class PITimer;
class PIPeer; class PIPeer;

View File

@@ -120,11 +120,11 @@ public:
EVENT1(peerConnectedEvent, const PIString &, name) EVENT1(peerConnectedEvent, const PIString &, name)
EVENT1(peerDisconnectedEvent, const PIString &, name) EVENT1(peerDisconnectedEvent, const PIString &, name)
bool lockedEth() const {return eth_mutex.isLocked();} // bool lockedEth() const {return eth_mutex.isLocked();}
bool lockedPeers() const {return peers_mutex.isLocked();} // bool lockedPeers() const {return peers_mutex.isLocked();}
bool lockedMBcasts() const {return mc_mutex.isLocked();} // bool lockedMBcasts() const {return mc_mutex.isLocked();}
bool lockedSends() const {return send_mutex.isLocked();} // bool lockedSends() const {return send_mutex.isLocked();}
bool lockedMCSends() const {return send_mc_mutex.isLocked();} // bool lockedMCSends() const {return send_mc_mutex.isLocked();}
protected: protected:
virtual void dataReceived(const PIString & from, const PIByteArray & data) {;} virtual void dataReceived(const PIString & from, const PIByteArray & data) {;}

View File

@@ -34,110 +34,100 @@
* *
* */ * */
#include "pimutex.h" //#include "pimutex.h"
#include "piincludes_p.h" //#include "piincludes_p.h"
#ifdef BLACKBERRY //#ifdef BLACKBERRY
# include <pthread.h> //# include <pthread.h>
#endif //#endif
PRIVATE_DEFINITION_START(PIMutex) //PRIVATE_DEFINITION_START(PIMutex)
#ifdef WINDOWS //#ifdef WINDOWS
HANDLE // HANDLE
#else //#else
pthread_mutex_t // pthread_mutex_t
#endif //#endif
mutex; // mutex;
PRIVATE_DEFINITION_END(PIMutex) //PRIVATE_DEFINITION_END(PIMutex)
PIMutex::PIMutex(): inited_(false) { //PIMutex::PIMutex(): inited_(false) {
//printf("new Mutex %p\n", this); // //printf("new Mutex %p\n", this);
#ifdef WINDOWS //#ifdef WINDOWS
PRIVATE->mutex = 0; // PRIVATE->mutex = 0;
#endif //#endif
init(); // init();
} //}
PIMutex::~PIMutex() { //PIMutex::~PIMutex() {
//printf("del Mutex %p\n", this); // //printf("del Mutex %p\n", this);
destroy(); // destroy();
} //}
void PIMutex::lock() { //void PIMutex::lock() {
#ifdef WINDOWS //#ifdef WINDOWS
// std::cout << (ullong)PRIVATE->mutex << "locking..." << std::endl; //// std::cout << (ullong)PRIVATE->mutex << "locking..." << std::endl;
// DWORD wr = //// DWORD wr =
WaitForSingleObject(PRIVATE->mutex, INFINITE); // WaitForSingleObject(PRIVATE->mutex, INFINITE);
// std::cout << (ullong)PRIVATE->mutex << " lock wr=" << wr << std::endl; //// std::cout << (ullong)PRIVATE->mutex << " lock wr=" << wr << std::endl;
#else //#else
pthread_mutex_lock(&(PRIVATE->mutex)); // pthread_mutex_lock(&(PRIVATE->mutex));
#endif //#endif
locked = true; //}
}
void PIMutex::unlock() { //void PIMutex::unlock() {
#ifdef WINDOWS //#ifdef WINDOWS
// BOOL wr = //// BOOL wr =
// ReleaseMutex(PRIVATE->mutex); //// ReleaseMutex(PRIVATE->mutex);
SetEvent(PRIVATE->mutex); // SetEvent(PRIVATE->mutex);
// std::cout << (ullong)PRIVATE->mutex << " unlock wr=" << wr << std::endl; //// std::cout << (ullong)PRIVATE->mutex << " unlock wr=" << wr << std::endl;
#else //#else
pthread_mutex_unlock(&(PRIVATE->mutex)); // pthread_mutex_unlock(&(PRIVATE->mutex));
#endif //#endif
locked = false; //}
}
bool PIMutex::tryLock() { //bool PIMutex::tryLock() {
bool ret = // bool ret =
#ifdef WINDOWS //#ifdef WINDOWS
(WaitForSingleObject(PRIVATE->mutex, 0) == WAIT_OBJECT_0); // (WaitForSingleObject(PRIVATE->mutex, 0) == WAIT_OBJECT_0);
#else //#else
(pthread_mutex_trylock(&(PRIVATE->mutex)) == 0); // (pthread_mutex_trylock(&(PRIVATE->mutex)) == 0);
#endif //#endif
locked = true; // return ret;
return ret; //}
}
bool PIMutex::isLocked() const { //void PIMutex::init() {
// std::cout << "test " << (ullong)PRIVATE->mutex << std::endl; // if (inited_) destroy();
return locked; //#ifdef WINDOWS
} // PRIVATE->mutex = CreateEvent(NULL, FALSE, TRUE, NULL);
//// std::cout << "create " << (ullong)PRIVATE->mutex << std::endl;
//#else
// pthread_mutexattr_t attr;
// memset(&attr, 0, sizeof(attr));
// pthread_mutexattr_init(&attr);
// pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
// memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex));
// pthread_mutex_init(&(PRIVATE->mutex), &attr);
// pthread_mutexattr_destroy(&attr);
//#endif
// inited_ = true;
//}
void PIMutex::init() { //void PIMutex::destroy() {
if (inited_) destroy(); // if (inited_) {
#ifdef WINDOWS //#ifdef WINDOWS
PRIVATE->mutex = CreateEvent(NULL, FALSE, TRUE, NULL); //// std::cout << "destroy " << (ullong)PRIVATE->mutex << std::endl;
// std::cout << "create " << (ullong)PRIVATE->mutex << std::endl; // if (PRIVATE->mutex) CloseHandle(PRIVATE->mutex);
#else // PRIVATE->mutex = 0;
pthread_mutexattr_t attr; //#else
memset(&attr, 0, sizeof(attr)); // pthread_mutex_destroy(&(PRIVATE->mutex));
pthread_mutexattr_init(&attr); //#endif
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); // }
memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex)); // inited_ = false;
pthread_mutex_init(&(PRIVATE->mutex), &attr); //}
pthread_mutexattr_destroy(&attr);
#endif
locked = false;
inited_ = true;
}
void PIMutex::destroy() {
if (inited_) {
#ifdef WINDOWS
// std::cout << "destroy " << (ullong)PRIVATE->mutex << std::endl;
if (PRIVATE->mutex) CloseHandle(PRIVATE->mutex);
PRIVATE->mutex = 0;
#else
pthread_mutex_destroy(&(PRIVATE->mutex));
#endif
}
locked = inited_ = false;
}

View File

@@ -25,42 +25,42 @@
#include "piinit.h" #include "piinit.h"
class PIP_EXPORT PIMutex
{ //class PIP_EXPORT PIMutex
public: //{
//! Constructs unlocked mutex //public:
explicit PIMutex(); // //! Constructs unlocked mutex
// explicit PIMutex();
//! Destroy mutex // //! Destroy mutex
~PIMutex(); // ~PIMutex();
//! \brief Lock mutex // //! \brief Lock mutex
//! \details If mutex is unlocked it set to locked state and returns immediate. // //! \details If mutex is unlocked it set to locked state and returns immediate.
//! If mutex is already locked function blocks until mutex will be unlocked // //! If mutex is already locked function blocks until mutex will be unlocked
void lock(); // void lock();
//! \brief Unlock mutex // //! \brief Unlock mutex
//! \details In any case this function returns immediate // //! \details In any case this function returns immediate
void unlock(); // void unlock();
//! \brief Try to lock mutex // //! \brief Try to lock mutex
//! \details If mutex is unlocked it set to locked state and returns "true" immediate. // //! \details If mutex is unlocked it set to locked state and returns "true" immediate.
//! If mutex is already locked function returns immediate an returns "false" // //! If mutex is already locked function returns immediate an returns "false"
bool tryLock(); // bool tryLock();
//! Returns if mutex is locked // //! Returns if mutex is locked
bool isLocked() const; // bool isLocked() const;
private: //private:
NO_COPY_CLASS(PIMutex) // NO_COPY_CLASS(PIMutex)
void init(); // void init();
void destroy(); // void destroy();
bool inited_; // bool inited_;
bool locked; // PRIVATE_DECLARATION
PRIVATE_DECLARATION //};
};
class PIP_EXPORT PIMutexLocker class PIP_EXPORT PIMutexLocker
@@ -71,7 +71,7 @@ public:
~PIMutexLocker() {if (cond) mutex->unlock();} ~PIMutexLocker() {if (cond) mutex->unlock();}
private: private:
PIMutex * mutex; PIMutex * mutex;
volatile bool cond; std::atomic_bool cond;
}; };
#endif // PIMUTEX_H #endif // PIMUTEX_H

300
main.cpp
View File

@@ -2,308 +2,12 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
/*#include <sys/ioctl.h>
#include <sys/select.h>
void print(PIConfig::Entry*e, PIString indent = "") { class A : public PIObject {
piCout << indent << e->name() << "=" << e->value();
indent += " ";
e->children().forEach([=](PIConfig::Entry*e)->PIConfig::Entry*{print(e, indent); return e;});
}
class AsyncIOWatcher: public PIThread {
PIOBJECT_SUBCLASS(AsyncIOWatcher, PIThread)
public: public:
AsyncIOWatcher() { void test() {piCout << "test";}
pipe_fd[0] = pipe_fd[1] = 0;
if (pipe(pipe_fd) != 0) {
piCoutObj << "Warning: can`t create pipe," << errorString();
} else {
fd_list << pipe_fd[0];
}
piCout << pipe_fd[0] << pipe_fd[1];
fd_list_changed = false;
start();
}
~AsyncIOWatcher() {
stop();
breakSelect();
if (!waitForFinish(2000))
terminate();
if (pipe_fd[0]) ::close(pipe_fd[0]);
if (pipe_fd[1]) ::close(pipe_fd[1]);
}
void add(int fd) {
que_mutex.lock();
fd_list_changed = true;
if (!add_que.contains(fd))
add_que.enqueue(fd);
que_mutex.unlock();
breakSelect();
}
void remove(int fd) {
que_mutex.lock();
fd_list_changed = true;
if (!remove_que.contains(fd))
remove_que.enqueue(fd);
que_mutex.unlock();
breakSelect();
}
private:
virtual void run() {
que_mutex.lock();
if (fd_list_changed) {
for (int i = 0; i < add_que.size_s(); ++i) {
if (!fd_list.contains(add_que[i]))
fd_list << add_que[i];
}
for (int i = 0; i < remove_que.size_s(); ++i) {
fd_list.removeAll(remove_que[i]);
}
add_que.clear();
remove_que.clear();
}
fd_list_changed = false;
que_mutex.unlock();
s_tv.tv_sec = 1;
s_tv.tv_usec = 0;
FD_ZERO(&s_set);
int max_fd = 0;
piForeachC (int fd, fd_list) {
FD_SET(fd, &s_set);
if (max_fd < fd)
max_fd = fd;
}
int ret = select(max_fd + 1, &s_set, 0, 0, 0);
piCout << "select" << ret;
if (ret <= 0) return;
read_buff.resize(1024);
uint ibuff = 0;
piForeachC (int fd, fd_list) {
if (!FD_ISSET(fd, &s_set)) continue;
if (fd == pipe_fd[0]) {
read(fd, &ibuff, sizeof(ibuff));
piCoutObj << "breaked";
continue;
}
int readed = read(fd, read_buff.data(), read_buff.size_s());
piCout << "readed" << fd << readed;
}
}
void breakSelect() {
if (pipe_fd[1])
::write(pipe_fd[1], "\0", 1);
}
PIQueue<int> add_que, remove_que;
PIDeque<int> fd_list;
PIByteArray read_buff;
PIMutex que_mutex;
bool fd_list_changed;
int pipe_fd[2];
fd_set s_set;
struct timeval s_tv;
}; };
*/
struct A {
double arr[1000];
};
//PIKbdListener kbd(0, 0, false);
// void swap(int & x, int & y) {int t = x; x = y; y = t;}
// void swap2(int & x, int & y) {int t(std::move(x)); x = y; y = t;}
// void swap(uint & x, uint & y) {uint t = x; x = y; y = t;}
// void swap2(uint & x, uint & y) {uint t(std::move(x)); x = y; y = t;}
// void swap(ullong & x, ullong & y) {ullong t = x; x = y; y = t;}
// void swap2(ullong & x, ullong & y) {ullong t{std::move(x)}; x = y; y = t;}
// void swap(llong & x, llong & y) {llong t = x; x = y; y = t;}
// void swap2(llong & x, llong & y) {llong t{std::move(x)}; x = y; y = t;}
// void swap(double & x, double & y) {double t = x; x = y; y = t;}
// void swap2(double & x, double & y) {double t(std::move(x)); x = std::move(y); y = std::move(t);}
// void swap(float & x, float & y) {float t = x; x = y; y = t;}
// void swap2(float & x, float & y) {float t(std::move(x)); x = std::move(y); y = std::move(t);}
// void swap(PIString & x, PIString & y) {PIString t = x; x = y; y = t;}
// void swap2(PIString & x, PIString & y) {PIString t(std::move(x)); x = std::move(y); y = std::move(t);}
// void swap(std::string & x, std::string & y) {std::string t = x; x = y; y = t;}
// void swap2(std::string & x, std::string & y) {std::string t{std::move(x)}; x = std::move(y); y = std::move(t);}
// void swap(A & x, A & y) {A t = x; x = y; y = t;}
// void swap2(A & x, A & y) {A t{std::move(x)}; x = std::move(y); y = std::move(t);}
//void swap(PIObject & x, PIObject & y) {A t = x; x = y; y = t;}
//void swap2(PIObject & x, PIObject & y) {A t(std::move(x)); x = std::move(y); y = std::move(t);}
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
// PITimeMeasurer tm;
// int m = 100000;
// int a = 99, b = 77;
// piCout << "int";
// tm.reset();
// for (int i = 0; i < m; ++i) {
// swap(a,b);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// swap2(a,b);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwapBinary(a,b);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwap(a,b);
// }
// piCout << tm.elapsed_s();
// piCout << "size_t";
// size_t ta = 99, tb = 77;
// tm.reset();
// for (int i = 0; i < m; ++i) {
// swap(ta,tb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// swap2(ta,tb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwapBinary(ta,tb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwap(ta,tb);
// }
// piCout << tm.elapsed_s();
// piCout << "ullong";
// ullong lla = 99, llb = 77;
// tm.reset();
// for (int i = 0; i < m; ++i) {
// swap(lla,llb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// swap2(lla,llb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwapBinary(lla,llb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwap(lla,llb);
// }
// piCout << tm.elapsed_s();
// piCout << "double";
// double da = 0.99,db = 77.77;
// tm.reset();
// for (int i = 0; i < m; ++i) {
// swap(da,db);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// swap2(da,db);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwapBinary(da,db);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwap(da,db);
// }
// piCout << tm.elapsed_s();
// piCout << "float";
// float fa = 0.99,fb = 77.77;
// tm.reset();
// for (int i = 0; i < m; ++i) {
// swap(fa,fb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// swap2(fa,fb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwapBinary(fa,fb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwap(fa,fb);
// }
// piCout << tm.elapsed_s();
// piCout << "A";
// A aa,ab;
// tm.reset();
// for (int i = 0; i < m; ++i) {
// swap(aa,ab);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// swap2(aa,ab);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwapBinary(aa,ab);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwap(aa,ab);
// }
// piCout << tm.elapsed_s();
// piCout << "std::string";
// std::string ia = "123456789012345678901vfsdvsd2345678",ib = "qwertyvsdfvvsdvfsuiopqwertyuikolsdfghjklsdfghjk";
// tm.reset();
// for (int i = 0; i < m; ++i) {
// swap(ia,ib);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// swap2(ia,ib);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// ia.swap(ib);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwap(ia,ib);
// }
// piCout << tm.elapsed_s();
// PIString sa = "123456789012345678901vfsdvsd2345678",sb = "qwertyvsdfvvsdvfsuiopqwertyuikolsdfghjklsdfghjk";
// piCout << "PIString";
// tm.reset();
// for (int i = 0; i < m; ++i) {
// swap(sa,sb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// swap2(sa, sb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// sa.swap(sb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwapBinary(sa, sb);
// }
// piCout << tm.elapsed_s(); tm.reset();
// for (int i = 0; i < m; ++i) {
// piSwap(sa, sb);
// }
// piCout << tm.elapsed_s();
return 0; return 0;
} }

View File

@@ -164,19 +164,20 @@ public:
tl->content << TileSimple::Row("Quality: " + PIString::fromNumber((int)ds.quality), CellFormat()); tl->content << TileSimple::Row("Quality: " + PIString::fromNumber((int)ds.quality), CellFormat());
} }
void updatePeerInfo() { void updatePeerInfo() {
bool pm = daemon_.lockedPeers(); // bool pm = daemon_.lockedPeers();
screen->lock(); screen->lock();
daemon_.lock(); daemon_.lock();
peers_tl->content.clear(); peers_tl->content.clear();
addrs_tl->content.clear(); addrs_tl->content.clear();
peerinfo_tl->content.clear(); peerinfo_tl->content.clear();
peermap_tl->content.clear(); peermap_tl->content.clear();
peers_tl->content << TileList::Row("this | 0 | 0 | " + PIString::fromNumber(daemon_.allPeers().size_s()) + peers_tl->content << TileList::Row("this | 0 | 0 | " + PIString::fromNumber(daemon_.allPeers().size_s())
" [em = " + PIString::fromBool(daemon_.lockedEth()) + ", " // + " [em = " + PIString::fromBool(daemon_.lockedEth()) + ", "
"mm = " + PIString::fromBool(daemon_.lockedMBcasts()) + ", " // "mm = " + PIString::fromBool(daemon_.lockedMBcasts()) + ", "
"sm = " + PIString::fromBool(daemon_.lockedSends()) + ", " // "sm = " + PIString::fromBool(daemon_.lockedSends()) + ", "
"ms = " + PIString::fromBool(daemon_.lockedMCSends()) + ", " // "ms = " + PIString::fromBool(daemon_.lockedMCSends()) + ", "
"pm = " + PIString::fromBool(pm) + "]", CellFormat()); // "pm = " + PIString::fromBool(pm) + "]"
, CellFormat());
piForeachC(PIPeer::PeerInfo &p , daemon_.allPeers()) piForeachC(PIPeer::PeerInfo &p , daemon_.allPeers())
peers_tl->content << TileList::Row(p.name + " | d = " + PIString::fromNumber(p.dist) + peers_tl->content << TileList::Row(p.name + " | d = " + PIString::fromNumber(p.dist) +
" | p = " + PIString::fromNumber(p.ping()) + " | p = " + PIString::fromNumber(p.ping()) +