From cbaa2b44224be1f55e1713df4974ec18ce3d8824 Mon Sep 17 00:00:00 2001 From: ian Date: Fri, 25 Apr 2008 18:24:32 +0000 Subject: [PATCH] fix use of INT_MAX; report movpos/point plans; etc. --- hostside/TODO | 3 +- hostside/commands.c | 4 +-- hostside/movpos.c | 88 +++++++++++++++++++++++++-------------------- hostside/resolve.c | 4 +-- hostside/safety.c | 10 +++--- hostside/safety.h | 5 ++- 6 files changed, 64 insertions(+), 50 deletions(-) diff --git a/hostside/TODO b/hostside/TODO index 288da9c..004fb89 100644 --- a/hostside/TODO +++ b/hostside/TODO @@ -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 diff --git a/hostside/commands.c b/hostside/commands.c index a23a1a3..dff8535 100644 --- a/hostside/commands.c +++ b/hostside/commands.c @@ -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) ); diff --git a/hostside/movpos.c b/hostside/movpos.c index 977d9c9..e682abe 100644 --- a/hostside/movpos.c +++ b/hostside/movpos.c @@ -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)); diff --git a/hostside/resolve.c b/hostside/resolve.c index 782ff58..aea6188 100644 --- a/hostside/resolve.c +++ b/hostside/resolve.c @@ -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; diff --git a/hostside/safety.c b/hostside/safety.c index 1d10d40..c9be91b 100644 --- a/hostside/safety.c +++ b/hostside/safety.c @@ -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; diff --git a/hostside/safety.h b/hostside/safety.h index f00292d..1c4c474 100644 --- a/hostside/safety.h +++ b/hostside/safety.h @@ -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 ----------*/ -- 2.30.2