]> granicus.if.org Git - transmission/commitdiff
(trunk libT) use jch's suggestion of having a per-session page-aligned memory buffer...
authorCharles Kerr <charles@transmissionbt.com>
Tue, 23 Feb 2010 07:20:57 +0000 (07:20 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Tue, 23 Feb 2010 07:20:57 +0000 (07:20 +0000)
libtransmission/inout.c
libtransmission/peer-io.c
libtransmission/peer-msgs.c
libtransmission/platform.h
libtransmission/session.c
libtransmission/session.h

index 6a6c1188680ed24522893af668a62b725e0283a8..3317b4195521552ecf70dfb3b16512e2c729894c 100644 (file)
@@ -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;
 }
 
index 4d1ac7333243586b23ab16c614166df804f2cbef..c5e3c951ce737143766db9651965a092d4bc8769 100644 (file)
@@ -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 );
 }
 
 /***
index 7867a1050eaf2d6ded1b517dcf2e7c3ea6f736d6..5b5f48173e4d2e6bf3340b7ffa7a8cad20efa8f2 100644 (file)
@@ -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",
index e9c687bd6502ef6077487c353e0ccbf5f1585a1f..3f946288ed5a17628e6a82ffa994b373518ddc8e 100644 (file)
@@ -32,8 +32,6 @@
  #define MAX_PATH_LENGTH  2048
 #endif
 
-#define MAX_STACK_ARRAY_SIZE 7168
-
 /**
  * @addtogroup tr_session Session
  * @{
index 2c7218d6e63ba083d25a7a916a7bf4404cc21c8b..0880be051a223b9cec39e4a4de35a3cd8a3df460 100644 (file)
@@ -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 );
index f3ff1c57f3ef814363b494ffc37fd0f246b11461..cb3d2c61a7b1559e65a799bd23359238486ef505 100644 (file)
@@ -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 );