/* call flow is: allocate [[reserve] request] cancel
* error from reserve or request causes call to destroy
*/
- SomeChange *(*allocate)(int n_motions); /* always succeeds */
+ SomeChange *(*allocate)(int alloc_motions); /* always succeeds */
ErrorCode (*reserve)(SomeChange*, Segment *move, int maxdelay_ms);
+ /* indep machinery guarantees alloc_motions >= move->i->n_motions */
ErrorCode (*request)(SomeChange*, Segment *move,
int n_motions, const Motion*, int maxdelay_ms);
+ /* indep machinery guarantees alloc_motions >= n_motions */
void (*destroy)(SomeChange*);
} MethodInfo;
void *u;
} ChangeHeader;
+/*---------- points ----------*/
+
+/*
+ * Currently there is only one queue for the one CDU.
+ *
+ * We maintain a queue of change requests. The queue can also contain
+ * reservations. We divide time into discrete slots, numbered with
+ * clock arithmetic.
+ *
+ * cslot cslot+1 cslot+2
+ *
+ * currently next in after
+ * changing line that
+ */
+
+typedef unsigned Slot;
+
+typedef struct PointReq {
+ ChangeHeader h;
+ /* Allocated Reserved Enqueued */
+ Slot needs; /* 0 ~0 remaining */
+ Slot startby; /* any defined defined */
+ struct PointReq { *next, *back } qe; /* unlinked linked linked */
+ Motion motions[]; /* none none 0..needs-1 */
+ /* are valid and defined; */
+ /* motions is alloc_motions long */
+} PointReq;
+
+#define CDU_RECHARGE 250 /*ms*/
+#define POINT_MOVEMENT 50 /*ms*/
+
+static Slot cslot;
+static struct { PointReq *head, *tail; } queue;
+static PointReq *lastinsert;
+
+static SomeChange point_allocate(int alloc_motions) {
+ PointReq= *p;
+
+ p= mmalloc(sizeof(*p) + alloc_motions * sizeof(Motion));
+ p->needs= 0;
+ return (SomeChange*)p;
+}
+
+static int point__putbefore(PointReq *new, PointReq *existing) {
+ return new->startby < existing->startby;
+}
+
+static ErrorCode point__enqueue(PointReq *p, int count, int maxdelay_ms,
+ Slot minrelslot) {
+ Slot relslot;
+ PointReq *ref;
+
+ relslot= (maxdelay_ms - POINT_MOVEMENT + CDU_RECHARGE) / CDU_RECHARGE
+ - count;
+ if (relslot < minrelslot) return EC_Point;
+
+ p->startby= cslot + relslot;
+
+ if (!queue.tail || !point__putbefore(p, queue.tail)) {
+ DLIST2_APPEND(queue,p,qe);
+ return;
+ }
+ if (point_putbefore(p, lastinsert)) {
+ for (ref=lastinsert;
+ ref->qe.back && point_putbefore(p, ref);
+ ref= ref->qe.back);
+ DLIST2_INSERT_BEFORE(queue,p,qe,ref);
+ } else {
+ for (ref=lastinsert;
+ ref->qe.next && !point_putbefore(p, ref);
+ );
+ DLIST2_INSERT_AFTER(queue,p,qe,ref);
+
+
+
+ if (!lastinsert)
+}
+
+static ErrorCode point_reserve(SomeChange *chg, Segment *move,
+ int maxdelay_ms) {
+
+
+ cslot + maxdelay_ms / POINT_EVERY_MS this is not right;
+
+
+ ErrorCode (*request)(SomeChange*, Segment *move,
+ int n_motions, const Motion*, int maxdelay_ms);
+ void (*destroy)(SomeChange*);
+
+
+convert incoming latest's into queue lengths as simple counts
+maintain latest count number for each
+
+
/*---------- method-independent machinery ----------*/
(*req_io)->on_moving= on_moving;
(*req_io)->on_done= on_done;
(*req_io)->u= u;
+ } else {
+ if (n_motions > (*req_io)->move->i->n_movfeats) { ec= EC_Invalid; return; }
}
ec= mi->request((SomeChange*)*req_io, move, n_motions, motions, maxdelay_ms);
movpos_cancelchange((ChangeHeader*)chg);
return ec;
}
-
-
-
- }
-
-
- }
-
-
- (*req_io)->move= move;
- (*req_io)->move= move;
-
- ChangeHeader *change= method(move, n_motions, motions, *req_io);
- if (!change)
- return EC_Point;
-
- change
- change.on_moving= on_moving;
- change.on_done= on_done;
- change.u= u;
-
- *req_io=
-
-
-
- MovFeatKind tkind
- if (tchanges
-
- unsigned diff= (
-
-
- / feati->weight
-
- unsigned posold= (move->movposcomb / feati->weight) % feati->posns;
-
- }
-
- for (feat=0, feati=movei->movfeats, result=0;
- feat<movei->n_movfeats;
- feat++) {
- unsigned posold= (move->movposcomb / feati->weight) % feati->posns;
- for (poschange=0; poschange<feati->posns; poschange++) {
- unsigned posnew= poschange % feati->posns;
-
-
-/*
- * Currently there is only one queue for the one CDU.
- *
- * We maintain a queue of change requests. The queue can also contain
- * reservations. We divide time into discrete slots, numbered with
- * clock arithmetic.
- *
- * cslot cslot+1 cslot+2
- *
- * currently next in after
- * changing line that
- */
-
-typedef unsigned Slot;
-
-typedef struct PointChangeQueueEntry {
- struct PointChangeQueueEntry *next, *back;
-
- Slot latest, needs;
- Segment *move;
- Motion motions[];
-} QE;
-
-static Slot cslot;
-static struct { QE *head, *tail; } queue;
-
-convert incoming latest's into queue lengths as simple counts
-maintain latest count number for each