Changeset 7441 for trunk/libtransmission/bandwidth.c
- Timestamp:
- Dec 20, 2008, 10:19:34 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/bandwidth.c
r7433 r7441 295 295 int period_msec ) 296 296 { 297 int n;297 int i, n, peerCount; 298 298 tr_ptrArray * tmp; 299 299 struct tr_peerIo ** peers; 300 300 301 /* allocateBandwidth() is a helper function with two purposes: 302 * 1. allocate bandwidth to b and its subtree 303 * 2. accumulate an array of all the peerIos from b and its subtree. */ 301 304 tmp = tr_ptrArrayNew( ); 302 305 allocateBandwidth( b, dir, period_msec, tmp ); 303 peers = (struct tr_peerIo**) tr_ptrArrayPeek( tmp, &n ); 304 305 /* loop through all the peers, reading and writing in small chunks, 306 * until we run out of bandwidth or peers. we do it this way to 307 * prevent one peer from using up all the bandwidth */ 308 #if 0 309 fprintf( stderr, "%s - %d peers\n", (dir==TR_UP)?"up":"down", n ); 310 #endif 311 while( n > 0 ) 312 { 313 int i; 314 for( i=0; i<n; ) 315 { 316 const int increment = n==1 ? 4096 : 1024; 317 const int byteCount = tr_peerIoFlush( peers[i], dir, increment); 318 319 #if 0 320 if( byteCount ) 321 fprintf( stderr, "peer %p: %d bytes\n", peers[i], byteCount ); 322 #endif 323 324 if( byteCount == increment ) 325 ++i; 326 else 327 peers[i] = peers[--n]; 306 peers = (struct tr_peerIo**) tr_ptrArrayPeek( tmp, &peerCount ); 307 308 /* Stop all peers from listening for the socket to be ready for IO. 309 * See "Second phase of IO" lower in this function for more info. */ 310 for( i=0; i<peerCount; ++i ) 311 tr_peerIoSetEnabled( peers[i], dir, FALSE ); 312 313 /* First phase of IO. Tries to distribute bandwidth in a fair/even manner 314 * to avoid "greedy peers" from starving out the other peers: loop through 315 * peers in a round-robin fashion, giving each one of them them small chunks 316 * of bandwidth to use. (It's small to conserve some of the bandwidth 317 * until the end of the loop). Keep looping until we run out of bandwidth 318 * or peers that are ready to use it. */ 319 n = peerCount; 320 i = n ? tr_cryptoWeakRandInt( n ) : 0; /* pick a random starting point */ 321 for( ; n>0; ) 322 { 323 const int increment = n==1 ? 4096 : 1024; 324 const int byteCount = tr_peerIoFlush( peers[i], dir, increment); 325 326 if( byteCount == increment ) 327 ++i; 328 else { 329 /* peer is done writing for now; move it to the end of the list */ 330 tr_peerIo * tmp = peers[i]; 331 peers[i] = peers[n-1]; 332 peers[n-1] = tmp; 333 --n; 328 334 } 329 } 335 336 assert( i <= n ); 337 if( i == n ) 338 i = 0; 339 } 340 341 /* Second phase of IO. To help us scale well in high bandiwdth situations 342 * such as LANs, enable on-demand IO for peers with bandwidth left to burn. 343 * This on-demand IO for a peer is enabled until either (1) the peer runs 344 * out of bandwidth, or (2) the next tr_bandwidthAllocate() call, when we 345 * start all over again. */ 346 for( i=0; i<peerCount; ++i ) 347 if( tr_peerIoHasBandwidthLeft( peers[i], dir ) ) 348 tr_peerIoSetEnabled( peers[i], dir, TRUE ); 330 349 331 350 /* cleanup */
Note: See TracChangeset
for help on using the changeset viewer.