typedef unsigned Slot;
-typedef struct PointReq {
+typedef struct PointReq { /* Allocated Reserved Enqueued Deleting */
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;
+ int n_motions; /* alloc_.. alloc_.. n_motions 0 */
+ PointMotion motions[]; /* undef defined defined defined */
+}
+
+typedef struct PointMotion { /* Allocated Reserved Enqueued Deleting */
+ Motion m; /* .i: undef 0 non-0 PT_DEL */
+ /* .posn: undef undef defined any */
+ Slot deadline; /* undef relative absolute any */
+} PointReq; /* in plan? no yes yes removing */
+
+/* We increment cslot when we issue a POINT command to the PIC.
+ * deadline represents the latest allowable value of cslot
+ * just before that increment. */
#define CDU_RECHARGE 250 /*ms*/
#define POINT_MOVEMENT 50 /*ms*/
+#define PT_MAX_PLAN 15
-static Slot cslot;
-static struct { PointReq *head, *tail; } queue;
-static PointReq *lastinsert;
+static Slot pt_cslot;
+static int pt_planlen;
+static PointMotion *pt_plan[PT_MAX_PLAN];
-static SomeChange point_allocate(int alloc_motions) {
+#define PT_DEL ((const MovFeatInfo*)info_segments) /* some random struct */
+
+static SomeChange pt_allocate(int alloc_motions) {
PointReq= *p;
- p= mmalloc(sizeof(*p) + alloc_motions * sizeof(Motion));
- p->needs= 0;
+ p= mmalloc(sizeof(*p) + alloc_motions * sizeof(p->motions[0]));
+ p->n_motions= alloc_motions;
return (SomeChange*)p;
}
+static pt_maxdelay_reldeadline(int maxdelay_ms) {
+ return (maxdelay_ms - POINT_MOVEMENT + CDU_RECHARGE) / CDU_RECHARGE;
+}
+
+static ErrorCode pt_insertreq(PointReq *pt) {
+ int i;
+
+ int n_add= pt->n_motions;
+ if (n_add==0) return 0;
+
+ int new_planlen= pt_planlen + new->n_motions;
+ if (new_planlen > PT_MAX_PLAN) return EC_BufferFull;
+
+ insat= pt_planlen;
+ new_reldeadline= pt_motion_reldeadline(pt->motions[0].deadline);
+ for (;;) {
+ if (insat<=0) break;
+ delaying_reldeadline= pt_motion_reldeadline(pt_plan[insat]->deadline);
+ if (new_reldeadline >= delaying_reldeadline) break;
+ int copyto= insat + n_add;
+ if (copyto > new_reldeadline) return EC_Points;
+ insat--;
+ }
+ if (insat + n_add - 1 > new_reldeadline)
+ return EC_Points;
+
+ int copyto= insat + n_add;
+ memmove(&pt_plan[copyto], &pt_plan[insat], sizeof(pt_plan[0]) * n_add);
+ for (i=0; i<n_add; i++)
+ pt_plan[insat+i]= &pt->motions[i];
+
+ while (insat>0 &&
+
+ < (moving_reldeadline=
+
+
+ insat[-1]
+ int this_rel
+
+static ErrorCode pt_reserve(SomeChange *chg, Segment *move, int maxdelay_ms) {
+ PointReq *p= (PointReq*)chg;
+ PointMotion *m;
+ int mi;
+ Slot deadline= pt_reldeadline(maxdelay_ms);
+
+ for (mi=0, m=p->motions; mi < p->n_motions; mi++, m++) {
+ m->m.i= 0;
+ m->deadline= deadline;
+ }
+ return pt_insertreq(p);
+}
+
static int point__putbefore(PointReq *new, PointReq *existing) {
return new->startby < existing->startby;
}