diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/stable/client.cpp | 11 | ||||
| -rw-r--r-- | src/stable/client.h | 10 | ||||
| -rw-r--r-- | src/stable/server.cpp | 22 | ||||
| -rw-r--r-- | src/stable/server.h | 8 | ||||
| -rw-r--r-- | src/unstable/profiler.cpp | 184 | ||||
| -rw-r--r-- | src/unstable/profiler.h | 54 |
6 files changed, 288 insertions, 1 deletions
diff --git a/src/stable/client.cpp b/src/stable/client.cpp index f6feb7c..56c5094 100644 --- a/src/stable/client.cpp +++ b/src/stable/client.cpp | |||
| @@ -16,6 +16,13 @@ | |||
| 16 | 16 | ||
| 17 | /** Read buffer size. */ | 17 | /** Read buffer size. */ |
| 18 | #define RBS (2000) // 1500 is the nominal MTU for ethernet, it's a good guess | 18 | #define RBS (2000) // 1500 is the nominal MTU for ethernet, it's a good guess |
| 19 | #ifdef PROFILE_BU_SERVER | ||
| 20 | #define BU_PROFILE_START( x ) Bu::Profiler::getInstance().startEvent( x ) | ||
| 21 | #define BU_PROFILE_END( x ) Bu::Profiler::getInstance().endEvent( x ) | ||
| 22 | #else | ||
| 23 | #define BU_PROFILE_START( x ) (void)0 | ||
| 24 | #define BU_PROFILE_END( x ) (void)0 | ||
| 25 | #endif | ||
| 19 | 26 | ||
| 20 | Bu::Client::Client( Bu::TcpSocket *pSocket, | 27 | Bu::Client::Client( Bu::TcpSocket *pSocket, |
| 21 | class Bu::ClientLinkFactory *pfLink ) : | 28 | class Bu::ClientLinkFactory *pfLink ) : |
| @@ -47,6 +54,7 @@ void Bu::Client::processInput() | |||
| 47 | char buf[RBS]; | 54 | char buf[RBS]; |
| 48 | Bu::size nRead, nTotal=0; | 55 | Bu::size nRead, nTotal=0; |
| 49 | 56 | ||
| 57 | BU_PROFILE_START("client.read"); | ||
| 50 | for(;;) | 58 | for(;;) |
| 51 | { | 59 | { |
| 52 | try | 60 | try |
| @@ -72,6 +80,7 @@ void Bu::Client::processInput() | |||
| 72 | break; | 80 | break; |
| 73 | } | 81 | } |
| 74 | } | 82 | } |
| 83 | BU_PROFILE_END("client.read"); | ||
| 75 | mRead.unlock(); | 84 | mRead.unlock(); |
| 76 | 85 | ||
| 77 | if( nTotal == 0 ) | 86 | if( nTotal == 0 ) |
| @@ -82,7 +91,9 @@ void Bu::Client::processInput() | |||
| 82 | 91 | ||
| 83 | if( pProto && nTotal ) | 92 | if( pProto && nTotal ) |
| 84 | { | 93 | { |
| 94 | BU_PROFILE_START("client.process"); | ||
| 85 | pProto->onNewData( this ); | 95 | pProto->onNewData( this ); |
| 96 | BU_PROFILE_END("client.process"); | ||
| 86 | } | 97 | } |
| 87 | } | 98 | } |
| 88 | 99 | ||
diff --git a/src/stable/client.h b/src/stable/client.h index 119e2f7..abde682 100644 --- a/src/stable/client.h +++ b/src/stable/client.h | |||
| @@ -16,6 +16,14 @@ | |||
| 16 | #include "bu/mutex.h" | 16 | #include "bu/mutex.h" |
| 17 | #include "bu/readwritemutex.h" | 17 | #include "bu/readwritemutex.h" |
| 18 | 18 | ||
| 19 | #ifndef PROFILE_BU_SERVER | ||
| 20 | // #define PROFILE_BU_SERVER 1 | ||
| 21 | #endif | ||
| 22 | |||
| 23 | #ifdef PROFILE_BU_SERVER | ||
| 24 | #include "bu/profiler.h" | ||
| 25 | #endif | ||
| 26 | |||
| 19 | namespace Bu | 27 | namespace Bu |
| 20 | { | 28 | { |
| 21 | class Protocol; | 29 | class Protocol; |
| @@ -29,7 +37,7 @@ namespace Bu | |||
| 29 | class Client : public Bu::Stream | 37 | class Client : public Bu::Stream |
| 30 | { | 38 | { |
| 31 | public: | 39 | public: |
| 32 | Client( Bu::TcpSocket *pSocket, Bu::ClientLinkFactory *pfLink ); | 40 | Client( Bu::TcpSocket *pSocket, Bu::ClientLinkFactory *pfLink); |
| 33 | virtual ~Client(); | 41 | virtual ~Client(); |
| 34 | 42 | ||
| 35 | void processInput(); | 43 | void processInput(); |
diff --git a/src/stable/server.cpp b/src/stable/server.cpp index 3c42bf4..0552510 100644 --- a/src/stable/server.cpp +++ b/src/stable/server.cpp | |||
| @@ -13,17 +13,27 @@ | |||
| 13 | #include "bu/tcpsocket.h" | 13 | #include "bu/tcpsocket.h" |
| 14 | #include "bu/config.h" | 14 | #include "bu/config.h" |
| 15 | 15 | ||
| 16 | #ifdef PROFILE_BU_SERVER | ||
| 17 | #define BU_PROFILE_START( x ) Bu::Profiler::getInstance().startEvent( x ) | ||
| 18 | #define BU_PROFILE_END( x ) Bu::Profiler::getInstance().endEvent( x ) | ||
| 19 | #else | ||
| 20 | #define BU_PROFILE_START( x ) (void)0 | ||
| 21 | #define BU_PROFILE_END( x ) (void)0 | ||
| 22 | #endif | ||
| 23 | |||
| 16 | Bu::Server::Server() : | 24 | Bu::Server::Server() : |
| 17 | nTimeoutSec( 0 ), | 25 | nTimeoutSec( 0 ), |
| 18 | nTimeoutUSec( 0 ), | 26 | nTimeoutUSec( 0 ), |
| 19 | bAutoTick( false ) | 27 | bAutoTick( false ) |
| 20 | { | 28 | { |
| 29 | BU_PROFILE_START("server"); | ||
| 21 | FD_ZERO( &fdActive ); | 30 | FD_ZERO( &fdActive ); |
| 22 | } | 31 | } |
| 23 | 32 | ||
| 24 | Bu::Server::~Server() | 33 | Bu::Server::~Server() |
| 25 | { | 34 | { |
| 26 | shutdown(); | 35 | shutdown(); |
| 36 | BU_PROFILE_START("server"); | ||
| 27 | } | 37 | } |
| 28 | 38 | ||
| 29 | void Bu::Server::addPort( int nPort, int nPoolSize ) | 39 | void Bu::Server::addPort( int nPort, int nPoolSize ) |
| @@ -50,6 +60,7 @@ void Bu::Server::setTimeout( int nTimeoutSec, int nTimeoutUSec ) | |||
| 50 | 60 | ||
| 51 | void Bu::Server::scan() | 61 | void Bu::Server::scan() |
| 52 | { | 62 | { |
| 63 | BU_PROFILE_START("scan"); | ||
| 53 | struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec }; | 64 | struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec }; |
| 54 | 65 | ||
| 55 | fd_set fdRead = fdActive; | 66 | fd_set fdRead = fdActive; |
| @@ -68,6 +79,7 @@ void Bu::Server::scan() | |||
| 68 | { | 79 | { |
| 69 | char buf[1024]; | 80 | char buf[1024]; |
| 70 | strerror_r( errno, buf, 1024 ); | 81 | strerror_r( errno, buf, 1024 ); |
| 82 | BU_PROFILE_END("scan"); | ||
| 71 | throw ExceptionBase( | 83 | throw ExceptionBase( |
| 72 | Bu::String("Error attempting to scan open connections: %1: %2").arg( errno ).arg( buf ).end().getStr() | 84 | Bu::String("Error attempting to scan open connections: %1: %2").arg( errno ).arg( buf ).end().getStr() |
| 73 | ); | 85 | ); |
| @@ -85,7 +97,9 @@ void Bu::Server::scan() | |||
| 85 | else | 97 | else |
| 86 | { | 98 | { |
| 87 | Client *pClient = hClients.get( j ); | 99 | Client *pClient = hClients.get( j ); |
| 100 | BU_PROFILE_START("processInput"); | ||
| 88 | pClient->processInput(); | 101 | pClient->processInput(); |
| 102 | BU_PROFILE_END("processInput"); | ||
| 89 | if( !pClient->isOpen() ) | 103 | if( !pClient->isOpen() ) |
| 90 | { | 104 | { |
| 91 | closeClient( j ); | 105 | closeClient( j ); |
| @@ -99,7 +113,9 @@ void Bu::Server::scan() | |||
| 99 | Client *pClient = hClients.get( j ); | 113 | Client *pClient = hClients.get( j ); |
| 100 | try | 114 | try |
| 101 | { | 115 | { |
| 116 | BU_PROFILE_START("processOutput"); | ||
| 102 | pClient->processOutput(); | 117 | pClient->processOutput(); |
| 118 | BU_PROFILE_END("processOutput"); | ||
| 103 | } | 119 | } |
| 104 | catch( Bu::TcpSocketException &e ) | 120 | catch( Bu::TcpSocketException &e ) |
| 105 | { | 121 | { |
| @@ -133,10 +149,13 @@ void Bu::Server::scan() | |||
| 133 | 149 | ||
| 134 | if( bAutoTick ) | 150 | if( bAutoTick ) |
| 135 | tick(); | 151 | tick(); |
| 152 | |||
| 153 | BU_PROFILE_END("scan"); | ||
| 136 | } | 154 | } |
| 137 | 155 | ||
| 138 | void Bu::Server::addClient( socket_t nSocket, int nPort ) | 156 | void Bu::Server::addClient( socket_t nSocket, int nPort ) |
| 139 | { | 157 | { |
| 158 | BU_PROFILE_START("addClient"); | ||
| 140 | FD_SET( nSocket, &fdActive ); | 159 | FD_SET( nSocket, &fdActive ); |
| 141 | 160 | ||
| 142 | Client *c = new Client( | 161 | Client *c = new Client( |
| @@ -146,6 +165,7 @@ void Bu::Server::addClient( socket_t nSocket, int nPort ) | |||
| 146 | hClients.insert( nSocket, c ); | 165 | hClients.insert( nSocket, c ); |
| 147 | 166 | ||
| 148 | onNewConnection( c, nPort ); | 167 | onNewConnection( c, nPort ); |
| 168 | BU_PROFILE_END("addClient"); | ||
| 149 | } | 169 | } |
| 150 | 170 | ||
| 151 | Bu::Server::SrvClientLink::SrvClientLink( Bu::Client *pClient ) : | 171 | Bu::Server::SrvClientLink::SrvClientLink( Bu::Client *pClient ) : |
| @@ -208,11 +228,13 @@ void Bu::Server::shutdown() | |||
| 208 | 228 | ||
| 209 | void Bu::Server::closeClient( socket_t iSocket ) | 229 | void Bu::Server::closeClient( socket_t iSocket ) |
| 210 | { | 230 | { |
| 231 | BU_PROFILE_START("closeClient"); | ||
| 211 | Bu::Client *pClient = hClients.get( iSocket ); | 232 | Bu::Client *pClient = hClients.get( iSocket ); |
| 212 | onClosedConnection( pClient ); | 233 | onClosedConnection( pClient ); |
| 213 | pClient->close(); | 234 | pClient->close(); |
| 214 | hClients.erase( iSocket ); | 235 | hClients.erase( iSocket ); |
| 215 | FD_CLR( iSocket, &fdActive ); | 236 | FD_CLR( iSocket, &fdActive ); |
| 216 | delete pClient; | 237 | delete pClient; |
| 238 | BU_PROFILE_END("closeClient"); | ||
| 217 | } | 239 | } |
| 218 | 240 | ||
diff --git a/src/stable/server.h b/src/stable/server.h index ee76fd2..d3f0903 100644 --- a/src/stable/server.h +++ b/src/stable/server.h | |||
| @@ -23,6 +23,14 @@ | |||
| 23 | 23 | ||
| 24 | #include "bu/config.h" | 24 | #include "bu/config.h" |
| 25 | 25 | ||
| 26 | #ifndef PROFILE_BU_SERVER | ||
| 27 | // #define PROFILE_BU_SERVER 1 | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #ifdef PROFILE_BU_SERVER | ||
| 31 | #include "bu/profiler.h" | ||
| 32 | #endif | ||
| 33 | |||
| 26 | namespace Bu | 34 | namespace Bu |
| 27 | { | 35 | { |
| 28 | class TcpServerSocket; | 36 | class TcpServerSocket; |
diff --git a/src/unstable/profiler.cpp b/src/unstable/profiler.cpp new file mode 100644 index 0000000..1b176b9 --- /dev/null +++ b/src/unstable/profiler.cpp | |||
| @@ -0,0 +1,184 @@ | |||
| 1 | #include "bu/profiler.h" | ||
| 2 | #include "bu/mutexlocker.h" | ||
| 3 | #include "bu/sio.h" | ||
| 4 | |||
| 5 | #include <sys/time.h> | ||
| 6 | |||
| 7 | Bu::Profiler::Profiler() | ||
| 8 | { | ||
| 9 | } | ||
| 10 | |||
| 11 | Bu::Profiler::~Profiler() | ||
| 12 | { | ||
| 13 | printReport(); | ||
| 14 | } | ||
| 15 | |||
| 16 | uint64_t Bu::Profiler::getMicroTime() | ||
| 17 | { | ||
| 18 | struct timeval tv; | ||
| 19 | gettimeofday( &tv, NULL ); | ||
| 20 | return ((uint64_t)tv.tv_sec)*1000000 + ((uint64_t)tv.tv_usec); | ||
| 21 | } | ||
| 22 | |||
| 23 | void Bu::Profiler::startEvent( const Bu::Blob &bName ) | ||
| 24 | { | ||
| 25 | Bu::MutexLocker l( mLock ); | ||
| 26 | if( hEvent.has( bName ) ) | ||
| 27 | { | ||
| 28 | hEvent.get( bName ).append( Event() ); | ||
| 29 | } | ||
| 30 | else | ||
| 31 | { | ||
| 32 | hEvent.insert( bName, EventList( Event() ) ); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | void Bu::Profiler::endEvent( const Bu::Blob &bName ) | ||
| 37 | { | ||
| 38 | Bu::MutexLocker l( mLock ); | ||
| 39 | if( !hEvent.has( bName ) ) | ||
| 40 | return; | ||
| 41 | |||
| 42 | if( hEvent.get( bName ).isEmpty() ) | ||
| 43 | return; | ||
| 44 | |||
| 45 | hEvent.get( bName ).last().end(); | ||
| 46 | } | ||
| 47 | |||
| 48 | void Bu::Profiler::printReport() const | ||
| 49 | { | ||
| 50 | class Breakdown | ||
| 51 | { | ||
| 52 | public: | ||
| 53 | Breakdown( const Bu::Blob &bName ) : | ||
| 54 | bName( bName ), uCount( 0 ), uTotal( 0 ), uMin( 0 ), uMax( 0 ) { } | ||
| 55 | Breakdown( const Breakdown &rSrc ) : | ||
| 56 | bName( rSrc.bName ), uCount( rSrc.uCount ), uTotal( rSrc.uTotal ), | ||
| 57 | uMin( rSrc.uMin ), uMax( rSrc.uMax ) { } | ||
| 58 | ~Breakdown() { } | ||
| 59 | |||
| 60 | bool operator<( const Breakdown &rhs ) const | ||
| 61 | { | ||
| 62 | return uTotal > rhs.uTotal; | ||
| 63 | } | ||
| 64 | Breakdown &operator=( const Breakdown &rhs ) | ||
| 65 | { | ||
| 66 | bName = rhs.bName; | ||
| 67 | uCount = rhs.uCount; | ||
| 68 | uTotal = rhs.uTotal; | ||
| 69 | uMin = rhs.uMin; | ||
| 70 | uMax = rhs.uMax; | ||
| 71 | return *this; | ||
| 72 | } | ||
| 73 | |||
| 74 | void add( uint64_t uSpan ) | ||
| 75 | { | ||
| 76 | if( uCount == 0 ) | ||
| 77 | { | ||
| 78 | uMin = uMax = uSpan; | ||
| 79 | } | ||
| 80 | else | ||
| 81 | { | ||
| 82 | if( uMin > uSpan ) | ||
| 83 | uMin = uSpan; | ||
| 84 | if( uMax < uSpan ) | ||
| 85 | uMax = uSpan; | ||
| 86 | |||
| 87 | } | ||
| 88 | uCount++; | ||
| 89 | uTotal += uSpan; | ||
| 90 | } | ||
| 91 | |||
| 92 | Bu::Blob bName; | ||
| 93 | uint64_t uCount; | ||
| 94 | uint64_t uTotal; | ||
| 95 | uint64_t uMin; | ||
| 96 | uint64_t uMax; | ||
| 97 | }; | ||
| 98 | Bu::MutexLocker l( mLock ); | ||
| 99 | |||
| 100 | int iTitleLen = 0; | ||
| 101 | Bu::List<Breakdown> lBreakdown; | ||
| 102 | for( EventListHash::const_iterator iType = hEvent.begin(); iType; iType++ ) | ||
| 103 | { | ||
| 104 | Breakdown b( iType.getKey() ); | ||
| 105 | if( iTitleLen < b.bName.getSize() ) | ||
| 106 | iTitleLen = b.bName.getSize(); | ||
| 107 | for( EventList::const_iterator iEv = iType.getValue().begin(); | ||
| 108 | iEv; iEv++ ) | ||
| 109 | { | ||
| 110 | b.add( (*iEv).getSpan() ); | ||
| 111 | } | ||
| 112 | lBreakdown.append( b ); | ||
| 113 | } | ||
| 114 | |||
| 115 | lBreakdown.sort(); | ||
| 116 | |||
| 117 | Bu::println("%1 %2 %3 %4 %5 %6") | ||
| 118 | .arg("Title", Bu::Fmt(iTitleLen) ) | ||
| 119 | .arg("Cnt", Bu::Fmt(5) ) | ||
| 120 | .arg("Total", Bu::Fmt(9) ) | ||
| 121 | .arg("Avg", Bu::Fmt(9) ) | ||
| 122 | .arg("Max", Bu::Fmt(9) ) | ||
| 123 | .arg("Min", Bu::Fmt(9) ); | ||
| 124 | for( Bu::List<Breakdown>::iterator i = lBreakdown.begin(); i; i++ ) | ||
| 125 | { | ||
| 126 | Bu::println("%1 %2 %3.%4 %5.%6 %7.%8 %9.%10") | ||
| 127 | .arg( (*i).bName.getData(), Bu::Fmt(iTitleLen) ) | ||
| 128 | .arg( (*i).uCount, Bu::Fmt(5) ) | ||
| 129 | .arg( ((*i).uTotal/1000000), Bu::Fmt(5).right() ) | ||
| 130 | .arg( ((*i).uTotal/1000)%1000, Bu::Fmt(3).fill('0').right() ) | ||
| 131 | .arg( ((*i).uTotal/(*i).uCount)/1000000, Bu::Fmt(5).right() ) | ||
| 132 | .arg( (((*i).uTotal/(*i).uCount)/1000)%1000, Bu::Fmt(3).right().fill('0') ) | ||
| 133 | .arg( (*i).uMax/1000000, Bu::Fmt(5).right() ) | ||
| 134 | .arg( ((*i).uMax/1000)%1000, Bu::Fmt(3).right().fill('0') ) | ||
| 135 | .arg( (*i).uMin/1000000, Bu::Fmt(5).right() ) | ||
| 136 | .arg( ((*i).uMin/1000)%1000, Bu::Fmt(3).right().fill('0') ) | ||
| 137 | ; | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | Bu::Profiler::Event::Event() : | ||
| 142 | iStart( Bu::Profiler::getMicroTime() ), | ||
| 143 | iStop( 0 ) | ||
| 144 | { | ||
| 145 | } | ||
| 146 | |||
| 147 | Bu::Profiler::Event::Event( const Event &rSrc ) : | ||
| 148 | iStart( rSrc.iStart ), | ||
| 149 | iStop( rSrc.iStop ) | ||
| 150 | { | ||
| 151 | } | ||
| 152 | |||
| 153 | Bu::Profiler::Event::~Event() | ||
| 154 | { | ||
| 155 | } | ||
| 156 | |||
| 157 | void Bu::Profiler::Event::end() | ||
| 158 | { | ||
| 159 | if( iStop == 0 ) | ||
| 160 | iStop = Bu::Profiler::getMicroTime(); | ||
| 161 | } | ||
| 162 | |||
| 163 | bool Bu::Profiler::Event::hasEnded() const | ||
| 164 | { | ||
| 165 | return iStop != 0; | ||
| 166 | } | ||
| 167 | |||
| 168 | uint64_t Bu::Profiler::Event::getStart() const | ||
| 169 | { | ||
| 170 | return iStart; | ||
| 171 | } | ||
| 172 | |||
| 173 | uint64_t Bu::Profiler::Event::getEnd() const | ||
| 174 | { | ||
| 175 | return iStop; | ||
| 176 | } | ||
| 177 | |||
| 178 | uint64_t Bu::Profiler::Event::getSpan() const | ||
| 179 | { | ||
| 180 | if( iStop < iStart ) | ||
| 181 | return 0; | ||
| 182 | return iStop-iStart; | ||
| 183 | } | ||
| 184 | |||
diff --git a/src/unstable/profiler.h b/src/unstable/profiler.h new file mode 100644 index 0000000..df05023 --- /dev/null +++ b/src/unstable/profiler.h | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | #ifndef BU_PROFILER_H | ||
| 2 | #define BU_PROFILER_H | ||
| 3 | |||
| 4 | #include "bu/blob.h" | ||
| 5 | #include "bu/hash.h" | ||
| 6 | #include "bu/list.h" | ||
| 7 | #include "bu/mutex.h" | ||
| 8 | #include "bu/singleton.h" | ||
| 9 | |||
| 10 | namespace Bu | ||
| 11 | { | ||
| 12 | class Profiler : public Bu::Singleton<Profiler> | ||
| 13 | { | ||
| 14 | friend class Bu::Singleton<Profiler>; | ||
| 15 | private: | ||
| 16 | Profiler(); | ||
| 17 | virtual ~Profiler(); | ||
| 18 | |||
| 19 | public: | ||
| 20 | static uint64_t getMicroTime(); | ||
| 21 | |||
| 22 | void startEvent( const Bu::Blob &bName ); | ||
| 23 | void endEvent( const Bu::Blob &bName ); | ||
| 24 | |||
| 25 | void printReport() const; | ||
| 26 | |||
| 27 | private: | ||
| 28 | class Event | ||
| 29 | { | ||
| 30 | public: | ||
| 31 | Event(); | ||
| 32 | Event( const Event &rSrc ); | ||
| 33 | ~Event(); | ||
| 34 | |||
| 35 | void end(); | ||
| 36 | bool hasEnded() const; | ||
| 37 | |||
| 38 | uint64_t getStart() const; | ||
| 39 | uint64_t getEnd() const; | ||
| 40 | uint64_t getSpan() const; | ||
| 41 | |||
| 42 | private: | ||
| 43 | uint64_t iStart; | ||
| 44 | uint64_t iStop; | ||
| 45 | }; | ||
| 46 | |||
| 47 | typedef Bu::List<Event> EventList; | ||
| 48 | typedef Bu::Hash<Bu::Blob, EventList> EventListHash; | ||
| 49 | EventListHash hEvent; | ||
| 50 | mutable Bu::Mutex mLock; | ||
| 51 | }; | ||
| 52 | }; | ||
| 53 | |||
| 54 | #endif | ||
