From: ian Date: Thu, 26 Jun 2008 16:19:52 +0000 (+0000) Subject: Give relaxed xmissions of urgent messages >=50% share X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=8f149ea527f7bb32434a85ff9446049f6e30c718;p=trains.git Give relaxed xmissions of urgent messages >=50% share --- diff --git a/hostside/realtime.h b/hostside/realtime.h index 419f143..7dc083c 100644 --- a/hostside/realtime.h +++ b/hostside/realtime.h @@ -55,17 +55,17 @@ union RetransmitUrgentNode { void retransmit_start(void); void retransmit_something(void); -void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, Nmra *n); -void retransmit_relaxed_requeue(RetransmitRelaxedNode *rn, Nmra *n); -void retransmit_relaxed_cancel(RetransmitRelaxedNode *rn); - void retransmit_urgent_queue(RetransmitUrgentNode *rn, Nmra *n); void retransmit_urgent_queue_relaxed(RetransmitUrgentNode *urg, Nmra *n); void retransmit_urgent_requeue(RetransmitUrgentNode *rn, Nmra *n); void retransmit_urgent_cancel(RetransmitUrgentNode *rn); - /* ... NB: these are NOT idempotent. Use _requeue it's queued; - * _requeue is just _cancel followed by queue. */ +void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, Nmra *n); +void retransmit_relaxed_cancel(RetransmitRelaxedNode *rn); + + /* ... NB: these are NOT idempotent and NOT interchangeable. Use + * urgent_requeue if it's queued and has changed and must get a new + * quota of urgency; _requeue is just _cancel followed by queue. */ /*---------- features, filled in by record, used by features.c ----------*/ diff --git a/hostside/retransmit.c b/hostside/retransmit.c index ab35463..0f404c0 100644 --- a/hostside/retransmit.c +++ b/hostside/retransmit.c @@ -33,7 +33,10 @@ */ /* * Implementation: - * All messages are on the single relaxed queue. + * All messages are on one of the relaxed queues; urgent messages + * are on the relaxed[0] queue and messages which are explicitly + * relaxed are on the relaxed[1] queue. This gives the previously- + * urgent messages 50% of the bandwidth. * There is one queue for each speady retransmission; messages are on * it in chronological order of dueness. */ @@ -46,7 +49,8 @@ static PicInsn linefill; -static DLIST2_HEAD(RetransmitRelaxedNode) relaxed; +static DLIST2_HEAD(RetransmitRelaxedNode) relaxed[2]; +static int last_relaxed_qn; static Retransmit__Time elapsed; static PerSpeedyTrans speedies[] = SPEEDIESINIT; @@ -94,37 +98,44 @@ void retransmit_something(void) { return; } - rlx= relaxed.head; - if (rlx) { - DLIST2_REMOVE(relaxed,rlx,rr); - DLIST2_APPEND(relaxed,rlx,rr); + for (ix=0; ix<2; ix++) { + int qn= last_relaxed_qn ^ ix ^ 1; + rlx= relaxed[qn].head; + if (!rlx) continue; + + DLIST2_REMOVE(relaxed[qn],rlx,rr); + DLIST2_APPEND(relaxed[qn],rlx,rr); retransmit_this(&rlx->pi); + last_relaxed_qn= qn; return; } serial_transmit(&linefill); } -void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, Nmra *n) { +static void relaxed_queue(int qn, RetransmitRelaxedNode *rn, Nmra *n) { if (n) { nmra_addchecksum(n); nmra_encodeforpic(n, &rn->pi); } - DLIST2_PREPEND(relaxed,rn,rr); + DLIST2_PREPEND(relaxed[qn],rn,rr); +} +static void relaxed_cancel(int qn, RetransmitRelaxedNode *rlx) { + DLIST2_REMOVE(relaxed[qn],rlx,rr); } -void retransmit_relaxed_requeue(RetransmitRelaxedNode *rn, Nmra *n) { - retransmit_relaxed_cancel(rn); - retransmit_relaxed_queue(rn, n); + +void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, Nmra *n) { + relaxed_queue(1,rn,n); } void retransmit_relaxed_cancel(RetransmitRelaxedNode *rlx) { - DLIST2_REMOVE(relaxed,rlx,rr); + relaxed_cancel(1,rlx); } void retransmit_urgent_queue(RetransmitUrgentNode *urg, Nmra *n) { - retransmit_relaxed_queue(&urg->u.relaxed, n); + relaxed_queue(0, &urg->u.relaxed, n); urg->u.ix= 0; urg->u.when= elapsed; DLIST2_APPEND(speedies[0].queue,urg,u.queue); } void retransmit_urgent_queue_relaxed(RetransmitUrgentNode *urg, Nmra *n){ - retransmit_relaxed_queue(&urg->u.relaxed, n); + relaxed_queue(0, &urg->u.relaxed, n); urg->u.ix= -1; urg->u.when= elapsed; } @@ -135,7 +146,7 @@ void retransmit_urgent_requeue(RetransmitUrgentNode *rn, Nmra *n) { void retransmit_urgent_cancel(RetransmitUrgentNode *urg) { if (urg->u.ix >= 0) DLIST2_REMOVE(speedies[urg->u.ix].queue,urg,u.queue); - retransmit_relaxed_cancel(&urg->u.relaxed); + relaxed_cancel(0, &urg->u.relaxed); }