From: Charles Kerr Date: Mon, 29 Dec 2008 09:51:54 +0000 (+0000) Subject: (trunk libT) avoid some unnecessary memory fragmentation... for composited objects... X-Git-Tag: 1.60~651 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7a4002dd3a672a83a860f7bc3752f1b6776a25a1;p=transmission (trunk libT) avoid some unnecessary memory fragmentation... for composited objects that have a tr_bitfield, contain it directly rather than a pointer to one allocated elsewhere on the heap. --- diff --git a/libtransmission/completion.c b/libtransmission/completion.c index eafaef80e..bccb0c426 100644 --- a/libtransmission/completion.c +++ b/libtransmission/completion.c @@ -38,10 +38,10 @@ struct tr_completion tr_torrent * tor; /* do we have this block? */ - tr_bitfield * blockBitfield; + tr_bitfield blockBitfield; /* do we have this piece? */ - tr_bitfield * pieceBitfield; + tr_bitfield pieceBitfield; /* a block is complete if and only if we have it */ uint16_t * completeBlocks; @@ -63,8 +63,8 @@ struct tr_completion static void tr_cpReset( tr_completion * cp ) { - tr_bitfieldClear( cp->pieceBitfield ); - tr_bitfieldClear( cp->blockBitfield ); + tr_bitfieldClear( &cp->pieceBitfield ); + tr_bitfieldClear( &cp->blockBitfield ); memset( cp->completeBlocks, 0, sizeof( uint16_t ) * cp->tor->info.pieceCount ); cp->sizeNow = 0; @@ -78,9 +78,9 @@ tr_cpInit( tr_torrent * tor ) tr_completion * cp = tr_new( tr_completion, 1 ); cp->tor = tor; - cp->blockBitfield = tr_bitfieldNew( tor->blockCount ); - cp->pieceBitfield = tr_bitfieldNew( tor->info.pieceCount ); cp->completeBlocks = tr_new( uint16_t, tor->info.pieceCount ); + tr_bitfieldConstruct( &cp->blockBitfield, tor->blockCount ); + tr_bitfieldConstruct( &cp->pieceBitfield, tor->info.pieceCount ); tr_cpReset( cp ); return cp; } @@ -88,9 +88,9 @@ tr_cpInit( tr_torrent * tor ) void tr_cpClose( tr_completion * cp ) { - tr_free ( cp->completeBlocks ); - tr_bitfieldFree( cp->pieceBitfield ); - tr_bitfieldFree( cp->blockBitfield ); + tr_free( cp->completeBlocks ); + tr_bitfieldDestruct( &cp->pieceBitfield ); + tr_bitfieldDestruct( &cp->blockBitfield ); tr_free ( cp ); } @@ -155,7 +155,7 @@ tr_cpPieceIsComplete( const tr_completion * cp, const tr_bitfield * tr_cpPieceBitfield( const tr_completion * cp ) { - return cp->pieceBitfield; + return &cp->pieceBitfield; } void @@ -193,15 +193,15 @@ tr_cpPieceRem( tr_completion * cp, cp->sizeWhenDoneIsDirty = 1; cp->haveValidIsDirty = 1; cp->completeBlocks[piece] = 0; - tr_bitfieldRemRange ( cp->blockBitfield, start, end ); - tr_bitfieldRem( cp->pieceBitfield, piece ); + tr_bitfieldRemRange ( &cp->blockBitfield, start, end ); + tr_bitfieldRem( &cp->pieceBitfield, piece ); } int tr_cpBlockIsComplete( const tr_completion * cp, tr_block_index_t block ) { - return tr_bitfieldHas( cp->blockBitfield, block ); + return tr_bitfieldHas( &cp->blockBitfield, block ); } void @@ -219,9 +219,9 @@ tr_cpBlockAdd( tr_completion * cp, ++cp->completeBlocks[piece]; if( tr_cpPieceIsComplete( cp, piece ) ) - tr_bitfieldAdd( cp->pieceBitfield, piece ); + tr_bitfieldAdd( &cp->pieceBitfield, piece ); - tr_bitfieldAdd( cp->blockBitfield, block ); + tr_bitfieldAdd( &cp->blockBitfield, block ); cp->sizeNow += blockSize; @@ -234,11 +234,10 @@ const tr_bitfield * tr_cpBlockBitfield( const tr_completion * cp ) { assert( cp ); - assert( cp->blockBitfield ); - assert( cp->blockBitfield->bits ); - assert( cp->blockBitfield->bitCount ); + assert( cp->blockBitfield.bits ); + assert( cp->blockBitfield.bitCount ); - return cp->blockBitfield; + return &cp->blockBitfield; } int @@ -249,7 +248,6 @@ tr_cpBlockBitfieldSet( tr_completion * cp, assert( cp ); assert( bitfield ); - assert( cp->blockBitfield ); if( tr_bitfieldTestFast( bitfield, cp->tor->blockCount - 1 ) ) { diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 1a65d13b0..0759c39f2 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -537,7 +537,7 @@ torrentRealInit( tr_session * session, tor->error = 0; - tor->checkedPieces = tr_bitfieldNew( tor->info.pieceCount ); + tr_bitfieldConstruct( &tor->checkedPieces, tor->info.pieceCount ); tr_torrentUncheck( tor ); tor->addedDate = time( NULL ); /* this is a default value to be @@ -1063,7 +1063,7 @@ freeTorrent( tr_torrent * tor ) tr_trackerFree( tor->tracker ); tor->tracker = NULL; - tr_bitfieldFree( tor->checkedPieces ); + tr_bitfieldDestruct( &tor->checkedPieces ); tr_free( tor->downloadDir ); tr_free( tor->peer_id ); @@ -1601,7 +1601,7 @@ tr_bool tr_torrentIsPieceChecked( const tr_torrent * tor, tr_piece_index_t piece ) { - return tr_bitfieldHas( tor->checkedPieces, piece ); + return tr_bitfieldHas( &tor->checkedPieces, piece ); } void @@ -1610,9 +1610,9 @@ tr_torrentSetPieceChecked( tr_torrent * tor, tr_bool isChecked ) { if( isChecked ) - tr_bitfieldAdd( tor->checkedPieces, piece ); + tr_bitfieldAdd( &tor->checkedPieces, piece ); else - tr_bitfieldRem( tor->checkedPieces, piece ); + tr_bitfieldRem( &tor->checkedPieces, piece ); } void @@ -1625,9 +1625,9 @@ tr_torrentSetFileChecked( tr_torrent * tor, const tr_piece_index_t end = file->lastPiece + 1; if( isChecked ) - tr_bitfieldAddRange ( tor->checkedPieces, begin, end ); + tr_bitfieldAddRange ( &tor->checkedPieces, begin, end ); else - tr_bitfieldRemRange ( tor->checkedPieces, begin, end ); + tr_bitfieldRemRange ( &tor->checkedPieces, begin, end ); } tr_bool @@ -1650,14 +1650,13 @@ tr_torrentIsFileChecked( const tr_torrent * tor, void tr_torrentUncheck( tr_torrent * tor ) { - tr_bitfieldRemRange ( tor->checkedPieces, 0, tor->info.pieceCount ); + tr_bitfieldRemRange ( &tor->checkedPieces, 0, tor->info.pieceCount ); } int tr_torrentCountUncheckedPieces( const tr_torrent * tor ) { - return tor->info.pieceCount - tr_bitfieldCountTrueBits( - tor->checkedPieces ); + return tor->info.pieceCount - tr_bitfieldCountTrueBits( &tor->checkedPieces ); } time_t* diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index c34ff9351..fb6173b1d 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -26,6 +26,8 @@ #error only libtransmission should #include this header. #endif +#include "utils.h" /* tr_bitfield */ + #ifndef TR_TORRENT_H #define TR_TORRENT_H 1 @@ -205,7 +207,7 @@ struct tr_torrent struct tr_completion * completion; - struct tr_bitfield * checkedPieces; + struct tr_bitfield checkedPieces; tr_completeness completeness; struct tr_tracker * tracker; diff --git a/libtransmission/utils.c b/libtransmission/utils.c index f8cca430a..af05c8c5b 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -746,14 +746,24 @@ tr_strstrip( char * str ) ****/ tr_bitfield* -tr_bitfieldNew( size_t bitCount ) +tr_bitfieldConstruct( tr_bitfield * b, size_t bitCount ) { - tr_bitfield * ret = tr_new0( tr_bitfield, 1 ); + b->bitCount = bitCount; + b->byteCount = ( bitCount + 7u ) / 8u; + b->bits = tr_new0( uint8_t, b->byteCount ); + return b; +} - ret->bitCount = bitCount; - ret->byteCount = ( bitCount + 7u ) / 8u; - ret->bits = tr_new0( uint8_t, ret->byteCount ); - return ret; +void +tr_bitfieldDestruct( tr_bitfield * b ) +{ + tr_free( b->bits ); +} + +tr_bitfield* +tr_bitfieldNew( size_t bitCount ) +{ + return tr_bitfieldConstruct( tr_new0( tr_bitfield, 1 ), bitCount ); } tr_bitfield* @@ -772,7 +782,7 @@ tr_bitfieldFree( tr_bitfield * bitfield ) { if( bitfield ) { - tr_free( bitfield->bits ); + tr_bitfieldDestruct( bitfield ); tr_free( bitfield ); } } diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 84cb57467..d1d310f75 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -299,14 +299,17 @@ int tr_httpParseURL( const char * url, **** ***/ -struct tr_bitfield +typedef struct tr_bitfield { uint8_t * bits; size_t bitCount; size_t byteCount; -}; +} +tr_bitfield; + +tr_bitfield* tr_bitfieldConstruct( tr_bitfield*, size_t bitcount ); -typedef struct tr_bitfield tr_bitfield; +void tr_bitfieldDestruct( tr_bitfield* ); tr_bitfield* tr_bitfieldNew( size_t bitcount ) TR_GNUC_MALLOC; @@ -346,7 +349,7 @@ tr_bitfield* tr_bitfieldOr( tr_bitfield*, need to call tr_bitfieldTestFast() first before you start looping. */ #define tr_bitfieldHasFast( bitfield, nth ) \ - ( ( bitfield->bits[( nth ) >> 3u] << ( ( nth ) & 7u ) & 0x80 ) != 0 ) + ( ( (bitfield)->bits[( nth ) >> 3u] << ( ( nth ) & 7u ) & 0x80 ) != 0 ) /** @param high the highest nth bit you're going to access */ #define tr_bitfieldTestFast( bitfield, high ) \