source: branches/1.5x/libtransmission/bandwidth.h @ 8204

Last change on this file since 8204 was 8204, checked in by charles, 13 years ago

(1.5x libT) various backports for 1.52:
(1) recognize Aria2 as a client
(2) remove jhujhiti's tr_suspectAddress(), since he removed it from trunka
(3) on Mac, better detection of where the Web UI files are located
(4) reintroduce the web task queue
(5) various minor formatting changes to reduce the diffs between 1.52 and trunk

  • Property svn:keywords set to Date Rev Author Id
File size: 8.5 KB
Line 
1/*
2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: bandwidth.h 8204 2009-04-10 17:34:25Z charles $
11 */
12
13#ifndef __TRANSMISSION__
14#error only libtransmission should #include this header.
15#endif
16
17#ifndef TR_BANDWIDTH_H
18#define TR_BANDWIDTH_H
19
20#include "transmission.h"
21#include "ptrarray.h"
22#include "utils.h" /* tr_new(), tr_free() */
23
24struct tr_peerIo;
25
26/* these are PRIVATE IMPLEMENTATION details that should not be touched.
27 * it's included in the header for inlining and composition. */
28enum
29{
30    HISTORY_MSEC = 2000,
31    INTERVAL_MSEC = HISTORY_MSEC,
32    GRANULARITY_MSEC = 50,
33    HISTORY_SIZE = ( INTERVAL_MSEC / GRANULARITY_MSEC ),
34    MAGIC_NUMBER = 43143
35};
36
37/* these are PRIVATE IMPLEMENTATION details that should not be touched.
38 * it's included in the header for inlining and composition. */
39struct bratecontrol
40{
41    int newest;
42    struct { uint64_t date, size; } transfers[HISTORY_SIZE];
43};
44
45/* these are PRIVATE IMPLEMENTATION details that should not be touched.
46 * it's included in the header for inlining and composition. */
47struct tr_band
48{
49    tr_bool isLimited;
50    tr_bool honorParentLimits;
51    size_t bytesLeft;
52    double desiredSpeed;
53    struct bratecontrol raw;
54    struct bratecontrol piece;
55};
56
57/**
58 * Bandwidth is an object for measuring and constraining bandwidth speeds.
59 *
60 * Bandwidth objects can be "stacked" so that a peer can be made to obey
61 * multiple constraints (for example, obeying the global speed limit and a
62 * per-torrent speed limit).
63 *
64 * HIERARCHY
65 *
66 *   Transmission's bandwidth hierarchy is a tree.
67 *   At the top is the global bandwidth object owned by tr_session.
68 *   Its children are per-torrent bandwidth objects owned by tr_torrent.
69 *   Underneath those are per-peer bandwidth objects owned by tr_peer.
70 *
71 *   tr_session also owns a tr_handshake's bandwidths, so that the handshake
72 *   I/O can be counted in the global raw totals.  When the handshake is done,
73 *   the bandwidth's ownership passes to a tr_peer.
74 *
75 * MEASURING
76 *
77 *   When you ask a bandwidth object for its speed, it gives the speed of the
78 *   subtree underneath it as well.  So you can get Transmission's overall
79 *   speed by quering tr_session's bandwidth, per-torrent speeds by asking
80 *   tr_torrent's bandwidth, and per-peer speeds by asking tr_peer's bandwidth.
81 *
82 * CONSTRAINING
83 *
84 *   Call tr_bandwidthAllocate() periodically.  tr_bandwidth knows its current
85 *   speed and will decide how many bytes to make available over the
86 *   user-specified period to reach the user-specified desired speed.
87 *   If appropriate, it notifies its peer-ios that new bandwidth is available.
88 *
89 *   tr_bandwidthAllocate() operates on the tr_bandwidth subtree, so usually
90 *   you'll only need to invoke it for the top-level tr_session bandwidth.
91 *
92 *   The peer-ios all have a pointer to their associated tr_bandwidth object,
93 *   and call tr_bandwidthClamp() before performing I/O to see how much
94 *   bandwidth they can safely use.
95 */
96typedef struct tr_bandwidth
97{
98    /* these are PRIVATE IMPLEMENTATION details that should not be touched.
99     * it's included in the header for inlining and composition. */
100
101    struct tr_band band[2];
102    struct tr_bandwidth * parent;
103    int magicNumber;
104    tr_session * session;
105    tr_ptrArray children; /* struct tr_bandwidth */
106    struct tr_peerIo * peer;
107}
108tr_bandwidth;
109
110
111/**
112***
113**/
114
115tr_bandwidth* tr_bandwidthConstruct( tr_bandwidth * bandwidth,
116                                     tr_session   * session,
117                                     tr_bandwidth * parent );
118
119/** @brief create a new tr_bandwidth object */
120static TR_INLINE tr_bandwidth* tr_bandwidthNew( tr_session * session, tr_bandwidth * parent )
121{
122    return tr_bandwidthConstruct( tr_new0( tr_bandwidth, 1 ), session, parent );
123}
124
125tr_bandwidth* tr_bandwidthDestruct( tr_bandwidth * bandwidth );
126
127/** @brief free a tr_bandwidth object */
128static TR_INLINE void tr_bandwidthFree( tr_bandwidth * bandwidth )
129{
130    tr_free( tr_bandwidthDestruct( bandwidth ) );
131}
132
133/** @brief test to see if the pointer refers to a live bandwidth object */
134static TR_INLINE tr_bool tr_isBandwidth( const tr_bandwidth  * b )
135{
136    return ( b != NULL ) && ( b->magicNumber == MAGIC_NUMBER );
137}
138
139/******
140*******
141******/
142
143/**
144 * @brief Set the desired speed (in KiB/s) for this bandwidth subtree.
145 * @see tr_bandwidthAllocate
146 * @see tr_bandwidthGetDesiredSpeed
147 */
148static TR_INLINE void tr_bandwidthSetDesiredSpeed( tr_bandwidth        * bandwidth,
149                                                tr_direction          dir,
150                                                double                desiredSpeed )
151{
152    bandwidth->band[dir].desiredSpeed = desiredSpeed;
153}
154
155/**
156 * @brief Get the desired speed (in KiB/s) for ths bandwidth subtree.
157 * @see tr_bandwidthSetDesiredSpeed
158 */
159static TR_INLINE double
160tr_bandwidthGetDesiredSpeed( const tr_bandwidth  * bandwidth,
161                             tr_direction          dir )
162{
163    return bandwidth->band[dir].desiredSpeed;
164}
165
166/**
167 * @brief Set whether or not this bandwidth should throttle its peer-io's speeds
168 */
169static TR_INLINE void tr_bandwidthSetLimited( tr_bandwidth        * bandwidth,
170                                              tr_direction          dir,
171                                              tr_bool               isLimited )
172{
173    bandwidth->band[dir].isLimited = isLimited;
174}
175
176/**
177 * @return nonzero if this bandwidth throttles its peer-ios speeds
178 */
179static TR_INLINE tr_bool tr_bandwidthIsLimited( const tr_bandwidth  * bandwidth,
180                                                tr_direction          dir )
181{
182    return bandwidth->band[dir].isLimited;
183}
184
185/**
186 * @brief allocate the next period_msec's worth of bandwidth for the peer-ios to consume
187 */
188void    tr_bandwidthAllocate          ( tr_bandwidth        * bandwidth,
189                                        tr_direction          direction,
190                                        int                   period_msec );
191
192/**
193 * @brief clamps byteCount down to a number that this bandwidth will allow to be consumed
194 */
195size_t  tr_bandwidthClamp             ( const tr_bandwidth  * bandwidth,
196                                        tr_direction          direction,
197                                        size_t                byteCount );
198
199/******
200*******
201******/
202
203/** @brief Get the raw total of bytes read or sent by this bandwidth subtree. */
204double tr_bandwidthGetRawSpeed( const tr_bandwidth  * bandwidth,
205                                const uint64_t        now,
206                                const tr_direction    direction );
207
208/** @brief Get the number of piece data bytes read or sent by this bandwidth subtree. */
209double tr_bandwidthGetPieceSpeed( const tr_bandwidth  * bandwidth,
210                                  const uint64_t        now,
211                                  const tr_direction    direction );
212
213/**
214 * @brief Notify the bandwidth object that some of its allocated bandwidth has been consumed.
215 * This is is usually invoked by the peer-io after a read or write.
216 */
217void    tr_bandwidthUsed              ( tr_bandwidth        * bandwidth,
218                                        tr_direction          direction,
219                                        size_t                byteCount,
220                                        tr_bool               isPieceData );
221
222/******
223*******
224******/
225
226void    tr_bandwidthSetParent         ( tr_bandwidth        * bandwidth,
227                                        tr_bandwidth        * parent );
228
229/**
230 * Almost all the time we do want to honor a parents' bandwidth cap, so that
231 * (for example) a peer is constrained by a per-torrent cap and the global cap.
232 * But when we set a torrent's speed mode to TR_SPEEDLIMIT_UNLIMITED, then
233 * in that particular case we want to ignore the global speed limit...
234 */
235static TR_INLINE void tr_bandwidthHonorParentLimits ( tr_bandwidth        * bandwidth,
236                                                      tr_direction          direction,
237                                                      tr_bool               isEnabled )
238{
239    assert( tr_isBandwidth( bandwidth ) );
240    assert( tr_isDirection( direction ) );
241
242    bandwidth->band[direction].honorParentLimits = isEnabled;
243}
244
245/******
246*******
247******/
248
249void tr_bandwidthSetPeer( tr_bandwidth        * bandwidth,
250                          struct tr_peerIo    * peerIo );
251
252#endif
Note: See TracBrowser for help on using the repository browser.