chiark / gitweb /
fix use of INT_MAX; report movpos/point plans; etc.
authorian <ian>
Fri, 25 Apr 2008 18:24:32 +0000 (18:24 +0000)
committerian <ian>
Fri, 25 Apr 2008 18:24:32 +0000 (18:24 +0000)
hostside/TODO
hostside/commands.c
hostside/movpos.c
hostside/resolve.c
hostside/safety.c
hostside/safety.h

index 288da9c602f68ffc34a9ad7f858c4851bdcb0d13..004fb89ae4db484abb449f3d87d0db738ee0e1e9 100644 (file)
@@ -1,6 +1,5 @@
 bugs
-       see fixme in movpos.c
-       also startup resolve crashes due to findhead_nextseg returning -1
+       startup resolve crashes due to findhead_nextseg returning -1
 
 want to
        document commands [!]movfeat and speed
index a23a1a35bcc0e12b2c8bc198afdc8cfcda1a5df7..dff85353058583f4265abbd37622c3d92ae5be8f 100644 (file)
@@ -241,9 +241,9 @@ static int cmd_movfeat(ParseState *ps, const CmdInfo *ci) {
     MUSTECR( movpos_findcomb_bysegs(back,move,fwd,move->movposcomb,&poscomb) );
   }
   
-  ms= INT_MAX;
+  ms= -1;
   if (ps->remain)
-    MUSTECR( ps_neednumber(ps,&ms,0,INT_MAX,"milliseconds") );
+    MUSTECR( ps_neednumber(ps,&ms,0,100000,"milliseconds") );
 
   MUSTECR( ps_neednoargs(ps) );
 
index 977d9c96859dc1aa531e8f5f83abbf423db7b92d..e682abe5d43d6432daf09a10c129e88452b3fc27 100644 (file)
@@ -197,8 +197,10 @@ static int pt_cdu_charged;
 static PointQueue pt_confirmed, pt_reserved;
 
 static void pt_check_action(void);
+static ErrorCode pt_check_plan(void);
 
 static PtSlot pt_maxdelay_reldeadline(int maxdelay_ms) {
+  if (maxdelay_ms==-1) return PT_MAX_QUEUE*16;
   return (maxdelay_ms - POINT_MOVEMENT + CDU_RECHARGE) / CDU_RECHARGE;
 }
 
@@ -225,7 +227,10 @@ static void pt_dequeue(PointReq *r) { /* X->XA */
     pt_queue_remove_item(&pt_confirmed, r);
   } else if (~r->deadline) {
     pt_queue_remove_item(&pt_reserved, r);
+  } else {
+    return;
   }
+  pt_check_plan();
 }
 
 static void pt_mark_as_allocated(PointReq *r) { /* AX->X */
@@ -234,54 +239,59 @@ static void pt_mark_as_allocated(PointReq *r) { /* AX->X */
   r->motions[0].i=0;
 }
 
+#define WHICH(wh)                              \
+  (whichr= wh##r,                              \
+   whichwhen= wh##when,                                \
+   wh++)
+
 static ErrorCode pt_check_plan(void) {
   /* Checks whether we can meet the currently queued commitments */
-  int future, conf, resv, usewhen;
-
-  fixme there is something wrong as
-    INT_MAX maxdelay_ms should not work as it overflows and makes
-    negative deadlines
-
-debug movpos/change : A5/P0 maxdelay_ms=2147483647 actual=?
-  point allocate 1
-debug movpos/change-needed : point:P(2*1) -1<-0 => 1debug movpos/change : confirm point:1...
-debug movpos/point : confirm A5 n=1 maxdelay=2147483647 (res: n=1 deadline=[t+]-1)
-debug movpos/point :  newdeadline=t+-8589933 allow_failure=1
-  pt_enqueue
-debug movpos/point :  pt_enqueue=OK
-movpos A5 position ? moving
-debug movpos/change : confirm => OK
+  int future, conf, resv, whichwhen;
+  PointReq *whichr;
 
   conf=resv=0;
+  future=0;
 
-  /* If CDU is charged we can do one thing right away */
-  while (conf < pt_confirmed.n &&
-        pt_confirmed.l[0]->deadline==pt_cslot) {
-    if (!pt_cdu_charged) return EC_MovFeatTooLate;
-    if (conf) return EC_MovFeatTooLate;
-    conf++;
+  oprintf(DUPO("movpos/point") "  plan");
+
+  /* If CDU is charged we can't do one right away */
+  if (!pt_cdu_charged) {
+    oprintf(UPO, " +");
+    future++;
   }
 
-  future=1;
   for (;;) {
     PointReq *confr= conf < pt_confirmed.n ? pt_confirmed.l[conf] : 0;
     PointReq *resvr= resv < pt_reserved .n ? pt_reserved .l[conf] : 0;
     if (!confr && !resvr) break;
+    oprintf(UPO," %d:",future);
     int confwhen= confr ? confr->deadline - pt_cslot : INT_MAX;
     int resvwhen= resvr ? resvr->deadline            : INT_MAX;
-    if (resvwhen < confwhen) {
-      usewhen= resvwhen;
-      resv++;
+    if (future && resvwhen < confwhen) {
+      WHICH(resv);
+      oprintf(UPO,"~");
+    } else if (confr) {
+      WHICH(conf);
     } else {
-      usewhen= confwhen;
-      conf++;
+      oprintf(UPO,"-");
+      future++;
+      continue;
     }
-    if (usewhen > future) return EC_MovFeatTooLate;
-    future++;
+    oprintf(UPO, "%s/%s[%d@t+%d]", whichr->h.move->i->pname,
+           posnpname(whichr->h.move, whichr->h.intent),
+           whichr->n_motions, whichwhen);
+    if (future > whichwhen) {
+      oprintf(UPO,"!...bad\n");
+      return EC_MovFeatTooLate;
+    }
+    future += whichr->n_motions;
   }
+  oprintf(UPO," ok\n");
   return 0;
 }
 
+#undef WHICH
+
 static ErrorCode pt_enqueue(PointQueue *q, PointReq *r) { /* XA -> X */
   int insat;                 /* ... where X is R or C and corresponds to q */
                              /* or on error,   XA -> A */
@@ -290,7 +300,6 @@ static ErrorCode pt_enqueue(PointQueue *q, PointReq *r) { /* XA -> X */
     return EC_BufferFull;
   }
 
-fprintf(stderr,"  pt_enqueue\n");
   for (insat= q->n;
        insat>0 && (PtSlotSigned)(r->deadline - q->l[insat-1]->deadline) < 0;
        insat--)
@@ -307,7 +316,6 @@ fprintf(stderr,"  pt_enqueue\n");
 static Change *point_allocate(int alloc_motions) {
   PointReq *r;
 
-fprintf(stderr,"  point allocate %d\n",alloc_motions);
   assert(pt_cdu_charged>=0);
   if (!alloc_motions)
     /* we need at least one motion in the table so we can tell
@@ -337,8 +345,8 @@ static ErrorCode point_confirm(Change *chg, Segment *move,
   int allow_failure;
   ErrorCode ec;
 
-  oprintf(DUPO("movpos/point") "confirm %s n=%d maxdelay=%d"
-         " (res: n=%d deadline=[t+]%d)\n",
+  oprintf(DUPO("movpos/point") "confirm %s n=%d maxdelay=%dms"
+         " (res: [%d@t+%d])\n",
          move->i->pname, n_motions, maxdelay_ms,
          r->n_motions, r->deadline);
 
@@ -353,12 +361,13 @@ static ErrorCode point_confirm(Change *chg, Segment *move,
   assert(n_motions <= r->n_motions);
   if (maxdelay_ms == -1) {
     newdeadline= r->deadline;
+    if (!~newdeadline) newdeadline= pt_maxdelay_reldeadline(-1);
   } else {
     newdeadline= pt_maxdelay_reldeadline(maxdelay_ms);
   }
   allow_failure= newdeadline < r->deadline;
-  oprintf(DUPO("movpos/point") " newdeadline=t+%d allow_failure=%d\n",
-         newdeadline, allow_failure);
+  oprintf(DUPO("movpos/point") " newdeadline=[%d@t+%d] allow_failure=%d\n",
+         n_motions, newdeadline, allow_failure);
   newdeadline += pt_cslot;
 
   /* state A or R */
@@ -428,6 +437,7 @@ static void point_destroy(Change *chg) { /* X->XA and then free it */
 
 static void pt_check_action(void) {
   PicInsn piob;
+  ErrorCode ec;
 
   if (!pt_confirmed.n) {
     if (sta_state == Sta_Finalising) resolve_motioncheck();
@@ -445,6 +455,7 @@ static void pt_check_action(void) {
     oprintf(UPO, "movpos %s point %s%d\n", r->h.move->i->pname,
            m->i->pname, m->posn);
     pt_cdu_charged= 0;
+    pt_cslot++;
 
     MovPosComb above_weight= m->i->weight * m->i->posns;
     MovPosComb above= r->actual / above_weight;
@@ -466,6 +477,7 @@ static void pt_check_action(void) {
     pt_mark_as_allocated(r); /* now state A aka Done */
     motion_done(move,r->h.actual);
     free(r);
+    ec= pt_check_plan();  assert(!ec);
     pt_check_action();
   }
 }
@@ -542,7 +554,7 @@ static int change_needed(const MovFeatInfo *feati, MovPosComb target,
   int r;
   r= startpoint<0 ||
     (target - startpoint) / feati->weight % feati->posns;
-  oprintf(DUPO("movpos/change-needed") "%s:%s(%d*%d) %d<-%d => %d",
+  oprintf(DUPO("movpos/change-needed") "%s:%s(%d*%d) %d<-%d => %d\n",
          methodinfos[feati->kind].pname, feati->pname,
          feati->posns, feati->weight,
          target, startpoint, r);
@@ -636,7 +648,7 @@ ErrorCode movpos_change(Segment *move, MovPosComb target,
     actual= move->motion->actual;
   }
 
-  oprintf(DUPO("movpos/change") "%s/%s maxdelay_ms=%d actual=%s\n",
+  oprintf(DUPO("movpos/change") "%s/%s maxdelay=%dms actual=%s\n",
          move->i->pname, posnpname(move,target),
          maxdelay_ms, posnpname(move, actual));
   if (chg) oprintf(DUPO("movpos/change") " chg=%s:%s/%s\n",
@@ -694,7 +706,7 @@ movpos_reserve(Segment *move, int maxdelay_ms, MovPosChange **res_r,
   ErrorCode ec;
   int nchanges;
 
-  oprintf(DUPO("movpos/reserve") "%s/%s maxdelay_ms=%d startpoint=%s\n",
+  oprintf(DUPO("movpos/reserve") "%s/%s maxdelay=%dms startpoint=%s\n",
          move->i->pname, posnpname(move,target),
          maxdelay_ms, posnpname(move,startpoint));
 
index 782ff58282844d74a50ecb6ce965c57a8908a461..aea6188cbba958a123f29d03dae78e6ce13e3ea1 100644 (file)
@@ -323,7 +323,7 @@ int resolve_complete(void) {
     if (d->i->n_poscombs>1) {
       d->movposcomb= -1;
       if (target >= 0) {
-       ErrorCode ec= movpos_change(d,target,INT_MAX,0);
+       ErrorCode ec= movpos_change(d,target,-1,0);
        if (ec) {
          oprintf(UPO, "resolution movpos-change-failed %s/%s %s\n",
                  d->i->pname, d->i->poscombs[target].pname,
@@ -399,7 +399,7 @@ static void resolve_train_finalise(Segment *startpoint) {
 
   tra->backwards= 0;
 
-  tc.distance= INT_MAX;
+  tc.distance= TL_DIST_INF;
   tc.nextseg= findhead_nextseg;
   tc.trackend= 0;
   tc.getmovpos= 0;
index 1d10d4019ef9ba8227cf9100d0d1fd25175cecc4..c9be91bbd7816937ac988c9b841f6436eab3acef 100644 (file)
@@ -451,7 +451,7 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
   u->nosec.distance= advanced;
   r= trackloc_advance(&u->nose,&u->nosec);
   if (r == EC_SignallingHorizonReached &&
-      u->was_distance==INT_MAX) {
+      u->was_distance==TL_DIST_INF) {
     /* Our very first `next segment' lookahead found the end.  So we
      * know that our nose hasn't left this segment because that's what
      * the stopping distance is supposed to prove. */
@@ -478,7 +478,7 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
       return predict_problem(u, t->seg, "cannot set track polarity");
   }
 
-  if (u->was_distance == INT_MAX) {
+  if (u->was_distance == TL_DIST_INF) {
     t->seg->det_expected= 1;
 
     u->walk_compute_polarise= u->need_polarise=
@@ -519,7 +519,7 @@ static int fdet_nextseg(TrackLocation *t, TrackAdvanceContext *c,
 
   /* Final adjustments, prepare for next iteration */
 
-  if (u->was_distance == INT_MAX)
+  if (u->was_distance == TL_DIST_INF)
     c->distance= speedmanager_stoppingdistance(u->train);
 
   u->was_distance= c->distance;
@@ -588,7 +588,7 @@ void report_train_ownerships(Train *tra, Segment *furthest) {
   u.tail.remain= 0;
   u.tail.backwards= !u.tail.seg->tr_backwards;
 
-  u.tailc.distance= INT_MAX;;
+  u.tailc.distance= TL_DIST_INF;;
   u.tailc.nextseg= report_nextseg;
   u.tailc.getmovpos= pred_getmovpos;
   u.tailc.u= &u;
@@ -661,7 +661,7 @@ ErrorCode predict_confirm(Train *tra, int accelerate,
 
   /* predict the future */
 
-  u.fdetc.distance= u.was_distance= INT_MAX;
+  u.fdetc.distance= u.was_distance= TL_DIST_INF;
   u.fdetc.nextseg= fdet_nextseg;
   u.fdetc.getmovpos= pred_getmovpos;
   u.fdetc.trackend= pred_trackend;
index f00292d8655fbc8db13e36fdd5252c5f857ef1ef..1c4c4746b477e6ef57855a415be64837a8a955e4 100644 (file)
@@ -150,7 +150,8 @@ movpos_change(Segment *tomove, MovPosComb target,
    * requested.)
    *
    * If a reservation is supplied, maxdelay_ms may be -1 to use the
-   * same value as was given to movpos_reserve.
+   * same value as was given to movpos_reserve, or if no reservation
+   * given, to say we don't care.
    */
 
 ErrorCode movpos_findcomb_bysegs(Segment *back, Segment *move, Segment *fwd,
@@ -304,6 +305,8 @@ int trackloc_set_exactinto(TrackLocation *t, TrackAdvanceContext *c,
   /* c is used just as for trackloc_getlink.
    * If we can't determine the movposcombs we call abort. */
 
+#define TL_DIST_INF (INT_MAX/16)
+
 /*========== useful macros and declarations ==========*/
 
 /*---------- looping over trains and segments ----------*/