ソースを参照

* Get rid of net_bw_hz and run the bw stuff at one hz.

* The peer rates are now only updated when data transfer is enabled
  in the corresponding direction. They are also computed differently
  from before. The rates are computed in the bw callback once a second.
  This facilitates later improvements in the choke algorithm.
master
Richard Nyberg 19年前
コミット
a01ffd8423
8個のファイルの変更64行の追加50行の削除
  1. +0
    -4
      btpd/main.c
  2. +42
    -17
      btpd/net.c
  3. +0
    -1
      btpd/opts.c
  4. +0
    -1
      btpd/opts.h
  5. +13
    -9
      btpd/peer.c
  6. +4
    -5
      btpd/peer.h
  7. +5
    -5
      btpd/policy_choke.c
  8. +0
    -8
      btpd/policy_if.c

+ 0
- 4
btpd/main.c ファイルの表示

@@ -118,7 +118,6 @@ static int longval = 0;


static struct option longopts[] = { static struct option longopts[] = {
{ "port", required_argument, NULL, 'p' }, { "port", required_argument, NULL, 'p' },
{ "bw-hz", required_argument, &longval, 6 },
{ "bw-in", required_argument, &longval, 1 }, { "bw-in", required_argument, &longval, 1 },
{ "bw-out", required_argument, &longval, 2 }, { "bw-out", required_argument, &longval, 2 },
{ "help", no_argument, &longval, 5 }, { "help", no_argument, &longval, 5 },
@@ -150,9 +149,6 @@ main(int argc, char **argv)
case 2: case 2:
net_bw_limit_out = atoi(optarg) * 1024; net_bw_limit_out = atoi(optarg) * 1024;
break; break;
case 6:
net_bw_hz = atoi(optarg);
break;
default: default:
usage(); usage();
} }


+ 42
- 17
btpd/net.c ファイルの表示

@@ -101,7 +101,7 @@ net_write(struct peer *p, unsigned long wmax)
peer_sent(p, nl->nb); peer_sent(p, nl->nb);
if (nl->nb->type == NB_TORRENTDATA) { if (nl->nb->type == NB_TORRENTDATA) {
p->tp->uploaded += bufdelta; p->tp->uploaded += bufdelta;
p->rate_from_me[btpd_seconds % RATEHISTORY] += bufdelta;
p->count_up += bufdelta;
} }
bcount -= bufdelta; bcount -= bufdelta;
BTPDQ_REMOVE(&p->outq, nl, entry); BTPDQ_REMOVE(&p->outq, nl, entry);
@@ -112,7 +112,7 @@ net_write(struct peer *p, unsigned long wmax)
} else { } else {
if (nl->nb->type == NB_TORRENTDATA) { if (nl->nb->type == NB_TORRENTDATA) {
p->tp->uploaded += bcount; p->tp->uploaded += bcount;
p->rate_from_me[btpd_seconds % RATEHISTORY] += bcount;
p->count_up += bcount;
} }
p->outq_off += bcount; p->outq_off += bcount;
bcount = 0; bcount = 0;
@@ -221,7 +221,7 @@ net_progress(struct peer *p, size_t length)
{ {
if (p->net.state == BTP_MSGBODY && p->net.msg_num == MSG_PIECE) { if (p->net.state == BTP_MSGBODY && p->net.msg_num == MSG_PIECE) {
p->tp->downloaded += length; p->tp->downloaded += length;
p->rate_to_me[btpd_seconds % RATEHISTORY] += length;
p->count_dwn += length;
} }
} }


@@ -435,14 +435,37 @@ net_connection_cb(int sd, short type, void *arg)
btpd_log(BTPD_L_CONN, "got connection.\n"); btpd_log(BTPD_L_CONN, "got connection.\n");
} }


void
add_bw_timer(void)
#define RATEHISTORY 20

long
compute_rate_sub(long rate)
{ {
long wait = 1000000 / net_bw_hz;
struct timeval now;
gettimeofday(&now, NULL);
wait = wait - now.tv_usec % wait;
evtimer_add(&m_bw_timer, (& (struct timeval) { 0, wait}));
if (rate > 256 * RATEHISTORY)
return rate / RATEHISTORY;
else
return 256;
}

static void
compute_peer_rates(void) {
struct torrent *tp;
BTPDQ_FOREACH(tp, btpd_get_torrents(), entry) {
struct peer *p;
BTPDQ_FOREACH(p, &tp->peers, p_entry) {
if (p->count_up > 0 || peer_active_up(p)) {
p->rate_up += p->count_up - compute_rate_sub(p->rate_up);
if (p->rate_up < 0)
p->rate_up = 0;
p->count_up = 0;
}
if (p->count_dwn > 0 || peer_active_down(p)) {
p->rate_dwn += p->count_dwn - compute_rate_sub(p->rate_dwn);
if (p->rate_dwn < 0)
p->rate_dwn = 0;
p->count_dwn = 0;
}
}
}
} }


void void
@@ -450,8 +473,12 @@ net_bw_cb(int sd, short type, void *arg)
{ {
struct peer *p; struct peer *p;


m_bw_bytes_out = net_bw_limit_out / net_bw_hz;
m_bw_bytes_in = net_bw_limit_in / net_bw_hz;
evtimer_add(&m_bw_timer, (& (struct timeval) { 1, 0 }));

compute_peer_rates();

m_bw_bytes_out = net_bw_limit_out;
m_bw_bytes_in = net_bw_limit_in;


if (net_bw_limit_in > 0) { if (net_bw_limit_in > 0) {
while ((p = BTPDQ_FIRST(&net_bw_readq)) != NULL && m_bw_bytes_in > 0) { while ((p = BTPDQ_FIRST(&net_bw_readq)) != NULL && m_bw_bytes_in > 0) {
@@ -480,7 +507,6 @@ net_bw_cb(int sd, short type, void *arg)
net_write(p, 0); net_write(p, 0);
} }
} }
add_bw_timer();
} }


void void
@@ -519,8 +545,8 @@ net_write_cb(int sd, short type, void *arg)
void void
net_init(void) net_init(void)
{ {
m_bw_bytes_out = net_bw_limit_out / net_bw_hz;
m_bw_bytes_in = net_bw_limit_in / net_bw_hz;
m_bw_bytes_out = net_bw_limit_out;
m_bw_bytes_in = net_bw_limit_in;


int nfiles = getdtablesize(); int nfiles = getdtablesize();
if (nfiles <= 20) if (nfiles <= 20)
@@ -553,6 +579,5 @@ net_init(void)
event_add(&m_net_incoming, NULL); event_add(&m_net_incoming, NULL);


evtimer_set(&m_bw_timer, net_bw_cb, NULL); evtimer_set(&m_bw_timer, net_bw_cb, NULL);
if (net_bw_limit_out > 0 || net_bw_limit_in > 0)
add_bw_timer();
evtimer_add(&m_bw_timer, (& (struct timeval) { 1, 0 }));
} }

+ 0
- 1
btpd/opts.c ファイルの表示

@@ -10,5 +10,4 @@ uint32_t btpd_logmask = BTPD_L_BTPD | BTPD_L_ERROR;
unsigned net_max_peers; unsigned net_max_peers;
unsigned net_bw_limit_in; unsigned net_bw_limit_in;
unsigned net_bw_limit_out; unsigned net_bw_limit_out;
short net_bw_hz = 8;
int net_port = 6881; int net_port = 6881;

+ 0
- 1
btpd/opts.h ファイルの表示

@@ -4,5 +4,4 @@ extern uint32_t btpd_logmask;
extern unsigned net_max_peers; extern unsigned net_max_peers;
extern unsigned net_bw_limit_in; extern unsigned net_bw_limit_in;
extern unsigned net_bw_limit_out; extern unsigned net_bw_limit_out;
extern short net_bw_hz;
extern int net_port; extern int net_port;

+ 13
- 9
btpd/peer.c ファイルの表示

@@ -9,15 +9,6 @@


#include "btpd.h" #include "btpd.h"


unsigned long
peer_get_rate(unsigned long *rates)
{
unsigned long ret = 0;
for (int i = 0; i < RATEHISTORY; i++)
ret += rates[i];
return ret;
}

void void
peer_kill(struct peer *p) peer_kill(struct peer *p)
{ {
@@ -525,3 +516,16 @@ peer_leech_ok(struct peer *p)
{ {
return (p->flags & (PF_I_WANT|PF_P_CHOKE)) == PF_I_WANT; return (p->flags & (PF_I_WANT|PF_P_CHOKE)) == PF_I_WANT;
} }

int
peer_active_down(struct peer *p)
{
return peer_leech_ok(p) || p->nreqs_out > 0;
}

int
peer_active_up(struct peer *p)
{
return (p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT
|| p->npiece_msgs > 0;
}

+ 4
- 5
btpd/peer.h ファイルの表示

@@ -12,7 +12,6 @@
#define PF_INCOMING 0x100 #define PF_INCOMING 0x100
#define PF_DO_UNWANT 0x200 #define PF_DO_UNWANT 0x200


#define RATEHISTORY 20
#define MAXPIECEMSGS 128 #define MAXPIECEMSGS 128
#define MAXPIPEDREQUESTS 10 #define MAXPIPEDREQUESTS 10


@@ -47,8 +46,8 @@ struct peer {
struct event in_ev; struct event in_ev;
struct event out_ev; struct event out_ev;


unsigned long rate_to_me[RATEHISTORY];
unsigned long rate_from_me[RATEHISTORY];
long rate_up, rate_dwn;
long count_up, count_dwn;


struct { struct {
uint32_t msg_len; uint32_t msg_len;
@@ -83,8 +82,6 @@ void peer_cancel(struct peer *p, struct block_request *req,


int peer_requested(struct peer *p, struct block *blk); int peer_requested(struct peer *p, struct block *blk);


unsigned long peer_get_rate(unsigned long *rates);

void peer_create_in(int sd); void peer_create_in(int sd);
void peer_create_out(struct torrent *tp, const uint8_t *id, void peer_create_out(struct torrent *tp, const uint8_t *id,
const char *ip, int port); const char *ip, int port);
@@ -107,6 +104,8 @@ void peer_on_request(struct peer *p, uint32_t index, uint32_t begin,
void peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin, void peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin,
uint32_t length); uint32_t length);


int peer_active_down(struct peer *p);
int peer_active_up(struct peer *p);
int peer_chokes(struct peer *p); int peer_chokes(struct peer *p);
int peer_wanted(struct peer *p); int peer_wanted(struct peer *p);
int peer_laden(struct peer *p); int peer_laden(struct peer *p);


+ 5
- 5
btpd/policy_choke.c ファイルの表示

@@ -1,7 +1,7 @@
#include "btpd.h" #include "btpd.h"


static int static int
rate_cmp(unsigned long rate1, unsigned long rate2)
rate_cmp(long rate1, long rate2)
{ {
if (rate1 < rate2) if (rate1 < rate2)
return -1; return -1;
@@ -14,16 +14,16 @@ rate_cmp(unsigned long rate1, unsigned long rate2)
static int static int
dwnrate_cmp(const void *p1, const void *p2) dwnrate_cmp(const void *p1, const void *p2)
{ {
unsigned long rate1 = peer_get_rate((*(struct peer **)p1)->rate_to_me);
unsigned long rate2 = peer_get_rate((*(struct peer **)p2)->rate_to_me);
long rate1 = (*(struct peer **)p1)->rate_dwn;
long rate2 = (*(struct peer **)p2)->rate_dwn;
return rate_cmp(rate1, rate2); return rate_cmp(rate1, rate2);
} }


static int static int
uprate_cmp(const void *p1, const void *p2) uprate_cmp(const void *p1, const void *p2)
{ {
unsigned long rate1 = peer_get_rate((*(struct peer **)p1)->rate_from_me);
unsigned long rate2 = peer_get_rate((*(struct peer **)p2)->rate_from_me);
long rate1 = (*(struct peer **)p1)->rate_up;
long rate2 = (*(struct peer **)p2)->rate_up;
return rate_cmp(rate1, rate2); return rate_cmp(rate1, rate2);
} }




+ 0
- 8
btpd/policy_if.c ファイルの表示

@@ -15,14 +15,6 @@ dl_by_second(struct torrent *tp)


if (btpd_seconds == tp->choke_time) if (btpd_seconds == tp->choke_time)
choke_alg(tp); choke_alg(tp);

struct peer *p;
int ri = btpd_seconds % RATEHISTORY;

BTPDQ_FOREACH(p, &tp->peers, p_entry) {
p->rate_to_me[ri] = 0;
p->rate_from_me[ri] = 0;
}
} }


/* /*


読み込み中…
キャンセル
保存