From fad8f285a8a2309dfe0132e4f958ca21485882fd Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 23 Feb 2010 07:20:57 +0000 Subject: [PATCH] (trunk libT) use jch's suggestion of having a per-session page-aligned memory buffer for general reuse. (http://trac.transmissionbt.com/ticket/2551#comment:5) --- libtransmission/inout.c | 5 +++-- libtransmission/peer-io.c | 16 ++++++++++------ libtransmission/peer-msgs.c | 9 ++++++--- libtransmission/platform.h | 2 -- libtransmission/session.c | 23 +++++++++++++++++++++++ libtransmission/session.h | 15 ++++++++++++++- 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/libtransmission/inout.c b/libtransmission/inout.c index 6a6c11886..3317b4195 100644 --- a/libtransmission/inout.c +++ b/libtransmission/inout.c @@ -295,8 +295,8 @@ recalculateHash( tr_torrent * tor, size_t bytesLeft; uint32_t offset = 0; tr_bool success = TRUE; - uint8_t buffer[MAX_STACK_ARRAY_SIZE]; - const size_t buflen = MAX_STACK_ARRAY_SIZE; + uint8_t * buffer = tr_sessionGetBuffer( tor->session ); + const size_t buflen = SESSION_BUFFER_SIZE; SHA_CTX sha; assert( tor != NULL ); @@ -322,6 +322,7 @@ recalculateHash( tr_torrent * tor, if( success ) SHA1_Final( setme, &sha ); + tr_sessionReleaseBuffer( tor->session ); return success; } diff --git a/libtransmission/peer-io.c b/libtransmission/peer-io.c index 4d1ac7333..c5e3c951c 100644 --- a/libtransmission/peer-io.c +++ b/libtransmission/peer-io.c @@ -32,7 +32,6 @@ #include "list.h" #include "net.h" #include "peer-io.h" -#include "platform.h" /* MAX_STACK_ARRAY_SIZE */ #include "trevent.h" /* tr_runInEventThread() */ #include "utils.h" @@ -810,17 +809,19 @@ tr_peerIoWrite( tr_peerIo * io, case PEER_ENCRYPTION_RC4: { /* FIXME(libevent2): use evbuffer_reserve_space() and evbuffer_commit_space() instead of tmp */ - uint8_t tmp[MAX_STACK_ARRAY_SIZE]; + void * tmp = tr_sessionGetBuffer( io->session ); + const size_t tmplen = SESSION_BUFFER_SIZE; const uint8_t * walk = bytes; evbuffer_expand( io->outbuf, byteCount ); while( byteCount > 0 ) { - const size_t thisPass = MIN( byteCount, sizeof( tmp ) ); + const size_t thisPass = MIN( byteCount, tmplen ); tr_cryptoEncrypt( io->crypto, thisPass, walk, tmp ); evbuffer_add( io->outbuf, tmp, thisPass ); walk += thisPass; byteCount -= thisPass; } + tr_sessionReleaseBuffer( io->session ); break; } @@ -881,14 +882,17 @@ tr_peerIoDrain( tr_peerIo * io, struct evbuffer * inbuf, size_t byteCount ) { - uint8_t tmp[MAX_STACK_ARRAY_SIZE]; + void * buf = tr_sessionGetBuffer( io->session ); + const size_t buflen = SESSION_BUFFER_SIZE; while( byteCount > 0 ) { - const size_t thisPass = MIN( byteCount, sizeof( tmp ) ); - tr_peerIoReadBytes( io, inbuf, tmp, thisPass ); + const size_t thisPass = MIN( byteCount, buflen ); + tr_peerIoReadBytes( io, inbuf, buf, thisPass ); byteCount -= thisPass; } + + tr_sessionReleaseBuffer( io->session ); } /*** diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c index 7867a1050..5b5f48173 100644 --- a/libtransmission/peer-msgs.c +++ b/libtransmission/peer-msgs.c @@ -31,7 +31,6 @@ #include "peer-io.h" #include "peer-mgr.h" #include "peer-msgs.h" -#include "platform.h" /* MAX_STACK_ARRAY_SIZE */ #include "session.h" #include "stats.h" #include "torrent.h" @@ -1340,16 +1339,20 @@ readBtPiece( tr_peermsgs * msgs, const size_t nLeft = req->length - EVBUFFER_LENGTH( msgs->incoming.block ); size_t n = MIN( nLeft, inlen ); size_t i = n; + void * buf = tr_sessionGetBuffer( getSession( msgs ) ); + const size_t buflen = SESSION_BUFFER_SIZE; while( i > 0 ) { - uint8_t buf[MAX_STACK_ARRAY_SIZE]; - const size_t thisPass = MIN( i, sizeof( buf ) ); + const size_t thisPass = MIN( i, buflen ); tr_peerIoReadBytes( msgs->peer->io, inbuf, buf, thisPass ); evbuffer_add( msgs->incoming.block, buf, thisPass ); i -= thisPass; } + tr_sessionReleaseBuffer( getSession( msgs ) ); + buf = NULL; + fireClientGotData( msgs, n, TRUE ); *setme_piece_bytes_read += n; dbgmsg( msgs, "got %zu bytes for block %u:%u->%u ... %d remain", diff --git a/libtransmission/platform.h b/libtransmission/platform.h index e9c687bd6..3f946288e 100644 --- a/libtransmission/platform.h +++ b/libtransmission/platform.h @@ -32,8 +32,6 @@ #define MAX_PATH_LENGTH 2048 #endif -#define MAX_STACK_ARRAY_SIZE 7168 - /** * @addtogroup tr_session Session * @{ diff --git a/libtransmission/session.c b/libtransmission/session.c index 2c7218d6e..0880be051 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -499,6 +499,7 @@ tr_sessionInit( const char * tag, session->lock = tr_lockNew( ); session->tag = tr_strdup( tag ); session->magicNumber = SESSION_MAGIC_NUMBER; + session->buffer = tr_valloc( SESSION_BUFFER_SIZE ); tr_bencInitList( &session->removedTorrents, 0 ); /* nice to start logging at the very beginning */ @@ -891,6 +892,27 @@ tr_sessionIsIncompleteDirEnabled( const tr_session * session ) **** ***/ +void* +tr_sessionGetBuffer( tr_session * session ) +{ + assert( tr_isSession( session ) ); + assert( !session->bufferInUse ); + assert( tr_amInEventThread( session ) ); + + session->bufferInUse = TRUE; + return session->buffer; +} + +void +tr_sessionReleaseBuffer( tr_session * session ) +{ + assert( tr_isSession( session ) ); + assert( session->bufferInUse ); + assert( tr_amInEventThread( session ) ); + + session->bufferInUse = FALSE; +} + void tr_sessionLock( tr_session * session ) { @@ -1573,6 +1595,7 @@ tr_sessionClose( tr_session * session ) tr_bencFree( session->metainfoLookup ); tr_free( session->metainfoLookup ); } + tr_free( session->buffer ); tr_free( session->tag ); tr_free( session->configDir ); tr_free( session->resumeDir ); diff --git a/libtransmission/session.h b/libtransmission/session.h index f3ff1c57f..cb3d2c61a 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -185,6 +185,12 @@ struct tr_session struct tr_bindinfo * public_ipv4; struct tr_bindinfo * public_ipv6; + + /* a page-aligned buffer for use by the libtransmission thread. + * @see SESSION_BUFFER_SIZE */ + void * buffer; + + tr_bool bufferInUse; }; tr_bool tr_sessionAllowsDHT( const tr_session * session ); @@ -211,9 +217,16 @@ struct tr_bindsockets * tr_sessionGetBindSockets( tr_session * ); enum { - SESSION_MAGIC_NUMBER = 3845 + SESSION_MAGIC_NUMBER = 3845, + + /* @see tr_session.buffer */ + SESSION_BUFFER_SIZE = (16*1024) }; +void* tr_sessionGetBuffer( tr_session * session ); + +void tr_sessionReleaseBuffer( tr_session * session ); + static inline tr_bool tr_isSession( const tr_session * session ) { return ( session != NULL ) && ( session->magicNumber == SESSION_MAGIC_NUMBER );