9 * There are two kinds of messages: urgent and relaxed.
11 * Urgent messages may be due for speedy transmission. The due urgent
12 * message with the highest priority is always transmitted as soon as
13 * a slot is available. This is known as `speedy transmission'.
15 * When no urgent messages are due for speedy transmission, messages
16 * (urgent or relaxed) are transmitted in a round-robin fashion. This
17 * round-robin transmission is completely independent of the speedy
20 * Each urgent message is due for speedy transmission as follows:
21 * - When it is first queued and has not yet been
22 * speedily transmitted:
23 * immediately due, with maximum priority
24 * - Following each speedy transmission:
25 * due after an interval since the previous
26 * transmission; this interval increases exponentially
27 * for each transmission
28 * with priority which decreases with later transmissions
29 * until it has been speedily transmitted a certain number of times
31 * no longer ever due; subject to round-robin transmission only.
32 * Intervals are measured in messages regardless of length.
36 * All messages are on one of the relaxed queues; urgent messages
37 * are on the relaxed[0] queue and messages which are explicitly
38 * relaxed are on the relaxed[1] queue. This gives the previously-
39 * urgent messages 50% of the bandwidth.
40 * There is one queue for each speedy retransmission; messages are on
41 * it in chronological order of dueness.
46 #include "retransmit-table.h"
48 #define RETRANSMIT_TIME_SIGNED_MAX ((~(Retransmit__Time)0) >> 1)
50 static PicInsn linefill;
52 static DLIST2_HEAD(RetransmitRelaxedNode) relaxed[2];
53 static int last_relaxed_qn;
54 static Retransmit__Time elapsed;
55 static PerSpeedyTrans speedies[] = SPEEDIESINIT;
57 static void retransmit_this(const PicInsn *pi) {
62 void retransmit_start(void) {
67 nmra_encodeforpic(&n, &linefill);
69 retransmit_something();
70 retransmit_something();
71 retransmit_something();
74 void retransmit_something(void) {
76 RetransmitUrgentNode *urg;
77 RetransmitRelaxedNode *rlx;
80 for (ix=0, spd=speedies;
85 if (elapsed - urg->u.when > RETRANSMIT_TIME_SIGNED_MAX) continue;
87 /* found one to transmit: */
88 DLIST2_REMOVE(spd->queue,urg,u.queue);
89 if (++ix < SPEEDYCOUNT) {
91 urg->u.when= elapsed + spd->interval;
93 DLIST2_APPEND(spd->queue,urg,u.queue);
97 retransmit_this(&urg->pi);
101 for (ix=0; ix<2; ix++) {
102 int qn= last_relaxed_qn ^ ix ^ 1;
103 rlx= relaxed[qn].head;
106 DLIST2_REMOVE(relaxed[qn],rlx,rr);
107 DLIST2_APPEND(relaxed[qn],rlx,rr);
108 retransmit_this(&rlx->pi);
113 serial_transmit(&linefill);
116 static void relaxed_queue(int qn, RetransmitRelaxedNode *rn, Nmra *n) {
117 if (n) { nmra_addchecksum(n); nmra_encodeforpic(n, &rn->pi); }
118 DLIST2_PREPEND(relaxed[qn],rn,rr);
120 static void relaxed_cancel(int qn, RetransmitRelaxedNode *rlx) {
121 DLIST2_REMOVE(relaxed[qn],rlx,rr);
124 void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, Nmra *n) {
125 relaxed_queue(1,rn,n);
127 void retransmit_relaxed_cancel(RetransmitRelaxedNode *rlx) {
128 relaxed_cancel(1,rlx);
131 void retransmit_urgent_queue(RetransmitUrgentNode *urg, Nmra *n) {
132 relaxed_queue(0, &urg->u.relaxed, n);
134 urg->u.when= elapsed;
135 DLIST2_APPEND(speedies[0].queue,urg,u.queue);
137 void retransmit_urgent_queue_relaxed(RetransmitUrgentNode *urg, Nmra *n){
138 relaxed_queue(0, &urg->u.relaxed, n);
140 urg->u.when= elapsed;
142 void retransmit_urgent_requeue(RetransmitUrgentNode *rn, Nmra *n) {
143 retransmit_urgent_cancel(rn);
144 retransmit_urgent_queue(rn, n);
146 void retransmit_urgent_cancel(RetransmitUrgentNode *urg) {
148 DLIST2_REMOVE(speedies[urg->u.ix].queue,urg,u.queue);
149 relaxed_cancel(0, &urg->u.relaxed);
153 void on_pic_nmradone(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
155 if (sta_state == Sta_Run || sta_state == Sta_Manual)
157 retransmit_something();
159 if (sta_state > Sta_Settling)
160 die("PIC sent NMRADONE in %s", stastatelist[sta_state]);