From: ian Date: Sun, 6 Apr 2008 11:57:04 +0000 (+0000) Subject: movpos compiles and links X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=f4e031f4e7407568a3fe3ba779fc2e13e5e74dd7;p=trains.git movpos compiles and links --- diff --git a/hostside/Makefile b/hostside/Makefile index 8f6aa74..95873fe 100644 --- a/hostside/Makefile +++ b/hostside/Makefile @@ -33,7 +33,7 @@ realtime: realtime.o startup.o cdumgr.o safety.o trackloc.o \ cmdinput.o commands.o obc.o eventhelp.o \ record.o record-l.o record-y.o \ utils.o serialio.o parseutils.o auproto-pic.o \ - nmra.o encode.o \ + nmra.o encode.o movpos.o \ ../layout/ours.layout-data.o \ __oop-read-copy.o -loop $(LINK) diff --git a/hostside/cdumgr.c b/hostside/cdumgr.c index 089d954..888c39c 100644 --- a/hostside/cdumgr.c +++ b/hostside/cdumgr.c @@ -5,11 +5,6 @@ #include "realtime.h" -void on_pic_charged(const PicInsnInfo *pii, const PicInsn *pi, int objnum) { - if (sta_state <= Sta_Settling) return; - /* fixme do something here */ -} - void on_pic_pointed(const PicInsnInfo *pii, const PicInsn *pi, int objnum) { if (sta_state <= Sta_Settling) return; /* fixme do something here */ diff --git a/hostside/errorcodes.h.gen b/hostside/errorcodes.h.gen index 9f72493..5f44180 100755 --- a/hostside/errorcodes.h.gen +++ b/hostside/errorcodes.h.gen @@ -4,7 +4,7 @@ OK Invalid Safety - Points + MovFeatTooLate MovFeatKindsCombination BufferFull ); diff --git a/hostside/movpos.c b/hostside/movpos.c index 20cf524..3332ce1 100644 --- a/hostside/movpos.c +++ b/hostside/movpos.c @@ -7,7 +7,7 @@ /*========== declarations ==========*/ typedef struct { - MoveFeatInfo *i; + const MovFeatInfo *i; Small posn; } Motion; @@ -26,14 +26,12 @@ typedef struct KindInfo KindInfo; * C Confirmed motion queued and will occur * D Done motion is complete and callback just needs to be made * E Erroneous indep must call destroy straight away - * seg->moving is in one of the states UCD + * seg->moving is in one of the states UC */ typedef struct MovPosChange { /* valid in: filled in by and when: */ const KindInfo *ki; /* ARCDE indep after allocate() */ Segment *move; /* ARCDE indep after allocate() */ - MovPosCallback *on_done; /* CD indep before confirm() */ - void *u; /* CD indep before confirm() */ MovPosComb actual; /* CD see below */ /* kind-specific data follows */ /* varies kind-specific code, varies */ } Change; @@ -94,7 +92,6 @@ typedef int PtSlotSigned; * Allocated Allocated yes * Reserved Reserved yes * Confirmed Confirmed yes - * Done Allocated yes * Erroneous A/R/C no * * Erroneous exists only after a failed reserve() or confirm() so it's @@ -103,8 +100,8 @@ typedef int PtSlotSigned; typedef struct { /* Allocated Reserved Confirmed */ /* in queue? absent reserved confirmed */ - ChangeHeader h; - Slot deadline; /* ~0 relative absolute <- */ + Change h; + PtSlot deadline; /* ~0 relative absolute <- */ int n_motions; /* alloc'd alloc'd undone */ Motion motions[]; /* [0].i: 0 0 non-0 <- */ /* [..].i: undef undef non-0 */ @@ -122,18 +119,13 @@ typedef struct { /* Allocated Reserved Confirmed */ #define CDU_RECHARGE 250 /*ms*/ #define POINT_MOVEMENT 50 /*ms*/ +#define PT_MAX_QUEUE 15 typedef struct { int n; PointReq *l[PT_MAX_QUEUE]; } PointQueue; -todo - actually fire points: use item, and remove it, etc. - write check routine - -#define PT_MAX_QUEUE 15 - /* * CDU and point queue states: * @@ -168,7 +160,9 @@ static PtSlot pt_cslot; static int pt_cdu_charged; static PointQueue pt_confirmed, pt_reserved; -static pt_maxdelay_reldeadline(int maxdelay_ms) { +static void pt_check_action(void); + +static PtSlot pt_maxdelay_reldeadline(int maxdelay_ms) { return (maxdelay_ms - POINT_MOVEMENT + CDU_RECHARGE) / CDU_RECHARGE; } @@ -177,14 +171,14 @@ static void pt_queue_remove_index(PointQueue *q, int index) { memmove(&q->l[index], &q->l[index+1], sizeof(q->l[0]) * (q->n - index)); } -static void pt_req_compar(const void *av, const void *bv) { - PointQueue *const *a= av; - PointQueue *const *b= av; +static int pt_req_compar(const void *av, const void *bv) { + PointReq *const *a= av; + PointReq *const *b= av; return (PtSlotSigned)((*b)->deadline - (*a)->deadline); } static void pt_queue_remove_item(PointQueue *q, PointReq *r) { - PointQueue **entry; + PointReq **entry; entry= bsearch(r, q->l, q->n, sizeof(q->l[0]), pt_req_compar); assert(entry); pt_queue_remove_index(q, entry - q->l); @@ -206,15 +200,15 @@ static void pt_mark_as_allocated(PointReq *r) { /* AX->X */ static ErrorCode pt_check_plan(void) { /* Checks whether we can meet the currently queued commitments */ - int future, conf, resv; + int future, conf, resv, usewhen; conf=resv=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_Points; - if (conf) return EC_Points; + pt_confirmed.l[0]->deadline==pt_cslot) { + if (!pt_cdu_charged) return EC_MovFeatTooLate; + if (conf) return EC_MovFeatTooLate; conf++; } @@ -232,14 +226,14 @@ static ErrorCode pt_check_plan(void) { usewhen= confwhen; conf++; } - if (usewhen > future) return EC_Points; + if (usewhen > future) return EC_MovFeatTooLate; future++; } return 0; } static ErrorCode pt_enqueue(PointQueue *q, PointReq *r) { /* XA -> X */ - ErrorCode ec; /* ... where X is R or C and corresponds to q */ + int insat; /* ... where X is R or C and corresponds to q */ /* or on error, XA -> A */ if (q->n == PT_MAX_QUEUE) { @@ -247,20 +241,20 @@ static ErrorCode pt_enqueue(PointQueue *q, PointReq *r) { /* XA -> X */ } for (insat= q->n; - insat>0 && CLOCK_COMPARE(r->deadline, <, q->l[insat-1]->deadline); + insat>0 && (PtSlotSigned)(r->deadline - q->l[insat-1]->deadline) < 0; insat--) q->l[insat]= q->l[insat-1]; q->l[insat]= r; q->n++; - return pt_check(); + return pt_check_plan(); /* if this fails, indep machinery calls pt_destroy which dequeues */ } /*---------- kind method entrypoints ----------*/ -static SomeChange pt_allocate(int alloc_motions) { - PointReq= *r; +static Change *point_allocate(int alloc_motions) { + PointReq *r; assert(pt_cdu_charged>=0); if (!alloc_motions) @@ -272,23 +266,24 @@ static SomeChange pt_allocate(int alloc_motions) { r->deadline= ~(PtSlot)0; r->n_motions= alloc_motions; r->motions[0].i= 0; - return (SomeChange*)r; + return (Change*)r; } -static ErrorCode point_reserve(SomeChange *chg, Segment *move, +static ErrorCode point_reserve(Change *chg, Segment *move, int maxdelay_ms) { PointReq *r= (PointReq*)chg; - r->deadline= pt_reldeadline(maxdelay_ms); - if (!r->deadline) { pt_mark_as_allocated(r); return EC_Points; } - return pt_queue_add(&pt_reserved, r); + r->deadline= pt_maxdelay_reldeadline(maxdelay_ms); + if (!r->deadline) { pt_mark_as_allocated(r); return EC_MovFeatTooLate; } + return pt_enqueue(&pt_reserved, r); } -static ErrorCode point_confirm(SomeChange *chg, Segment *move, +static ErrorCode point_confirm(Change *chg, Segment *move, int n_motions, const Motion *motions, int maxdelay_ms) { PointReq *r= (PointReq*)chg; PtSlot newdeadline; int allow_failure; + ErrorCode ec; /* If the segment is moving, these motions are already based on the * actual physical position which is stored in the existing request. @@ -297,19 +292,19 @@ static ErrorCode point_confirm(SomeChange *chg, Segment *move, */ assert(n_motions <= r->n_motions); - newdeadline= pt_reldeadline(maxdelay_ms) + cslot; + newdeadline= pt_maxdelay_reldeadline(maxdelay_ms) + pt_cslot; allow_failure= newdeadline < r->deadline; /* state A or R */ pt_dequeue(r); - /* states of existing: */ - PointReq *existing= move->moving; /* U or C */ - if (existing) pt_dequeue(existing); /* U or CA */ + /* states of existing: */ + PointReq *existing= (PointReq*)move->moving; /* U or C */ + if (existing) pt_dequeue(existing); /* U or CA */ /* state A or RA */ memcpy(r->motions, motions, sizeof(r->motions[0])*n_motions); - if (!n_motions) motions[0].i= move->i->movfeats; - assert(motions[0].i); + if (!n_motions) r->motions[0].i= move->i->movfeats; + assert(r->motions[0].i); r->n_motions= n_motions; r->deadline= newdeadline + pt_cslot; @@ -317,19 +312,19 @@ static ErrorCode point_confirm(SomeChange *chg, Segment *move, ec= pt_enqueue(&pt_confirmed, r); assert(allow_failure || !ec); - if (existing) { /* CA */ + if (existing) { /* CA */ if (ec) { /* state C but bad */ pt_dequeue(r); /* state CA */ pt_mark_as_allocated(r); /* state A */ ErrorCode ec_putback= pt_enqueue(&pt_confirmed, existing); - assert(!ec_putback); /* C */ + assert(!ec_putback); /* C */ } else { /* state C and good */ - free(existing); /* U */ + free(existing); /* U */ } } - /* either ec=0 state C U - * or ec!=0 state A C - * or ec!=0 state C but bad C + /* either ec=0 state C U + * or ec!=0 state A C + * or ec!=0 state C but bad C */ if (!ec) pt_check_action(); @@ -337,7 +332,7 @@ static ErrorCode point_confirm(SomeChange *chg, Segment *move, return ec; } -static void pt_destroy(Change *chg) { /* X->XA and then free it */ +static void point_destroy(Change *chg) { /* X->XA and then free it */ PointReq *r= (PointReq*)chg; pt_dequeue(r); free(r); @@ -361,9 +356,9 @@ static void pt_check_action(void) { pt_cdu_charged= 0; MovPosComb above_weight= m->i->weight * m->i->posns; - MovPosComb above= r->actual / above_weight; - MovPosComb below= r->actual % m->i->weight; - r->actual= above*above_weight + m->posn*m->i->weight + below; + MovPosComb above= r->h.actual / above_weight; + MovPosComb below= r->h.actual % m->i->weight; + r->h.actual= above*above_weight + m->posn*m->i->weight + below; } if (!r->n_motions) { @@ -372,17 +367,19 @@ static void pt_check_action(void) { * eg if we are asked to move the */ Segment *move= r->h.move; - assert(move->moving == r); + assert(move->moving == (Change*)r); pt_queue_remove_index(&pt_confirmed,0); pt_mark_as_allocated(r); /* now state A aka Done */ - movpos_done((Change*)r); + move->movposcomb= r->h.actual; + move->moving= 0; + free(r); pt_check_action(); } } /*---------- entrypoints from rest of program ----------*/ -static void points_all_abandon(void) { +void points_all_abandon(void) { int i; assert(!pt_reserved.n); @@ -390,69 +387,68 @@ static void points_all_abandon(void) { for (i=0; ih.move; - assert(move->moving == (PointReq*)r); + assert(move->moving == (Change*)r); move->moving= 0; move->movposcomb= r->h.actual; free(r); } pt_confirmed.n= 0; pt_cdu_charged= -1; - toev_stop(&pt_motion_timeout); } -static void points_turning_on(void) { +void points_turning_on(void) { pt_cdu_charged= 0; - pt_motion_timeout.duration= POINT_MOVEMENT; - pt_motion_timeout.callback= pt_motion_done; - assert(!pt_motion_timeout.running); } void on_pic_charged(const PicInsnInfo *pii, const PicInsn *pi, int objnum) { if (pt_cdu_charged<0) return; pt_cdu_charged= 1; - if (pt_motion_timeout.running) { - toev_stop(&pt_motion_timeout); - pt_motion_done(0); - } pt_check_action(); } +/*========== dummy `nomove' kind ==========*/ + +static Change *nomove_allocate(int alloc_motions) { + return mmalloc(sizeof(Change)); +} +static void nomove_destroy(Change *chg) { free(chg); } + +static ErrorCode nomove_reserve(Change *chg, Segment *move, int ms) { + return 0; +} +static ErrorCode nomove_confirm(Change *chg, Segment *move, int n_motions, + const Motion *motions, int ms) { + nomove_destroy(chg); + return 0; +} + /*========== method-independent machinery ==========*/ static const KindInfo methodinfos[]= { - { nomove_allocate, nomove_reserve, nomove_request, nomove_cancel }, - { point_allocate, point_reserve, point_request, point_cancel }, - 0 + { nomove_allocate, nomove_reserve, nomove_confirm, nomove_destroy }, + { point_allocate, point_reserve, point_confirm, point_destroy }, + { 0 } }; -static void movpos_done(Change *chg) { - Segment *move= chg->move; - events_ - move->movposcomb= r->actual; - move->moving= 0; - r->h.on_done(move, r->h.u); - free(r); -} - -ChangeHeader *mp_allocate(const KindInfo *ki, Segment *move, - int alloc_motions) { +static Change *mp_allocate(const KindInfo *ki, Segment *move, + int alloc_motions) { assert(sta_state >= Sta_Resolving); - chg= (ChangeHeader*)ki->allocate(alloc_motions); + Change *chg= ki->allocate(alloc_motions); chg->ki= ki; chg->move= move; return chg; } ErrorCode -movpos_change(Segment *back, Segment *move, *Segment *fwd, - int maxdelay_ms, MovPosChange chg, - MovPosCallback *on_done, *u) { +movpos_change(Segment *back, Segment *move, Segment *fwd, + int maxdelay_ms, MovPosChange *chg) { const SegmentInfo *movei= move->i; - SegPosCombInfo *pci; + const SegPosCombInfo *pci; + const MovFeatInfo *feati; + int feat; MovPosComb actual, tcomb, bestcomb=0; int tchanges, bestchanges=INT_MAX; ErrorCode ec; - MovFeatKind kind= mfk_none; if (move->moving) { @@ -467,8 +463,8 @@ movpos_change(Segment *back, Segment *move, *Segment *fwd, tcomb++, pci++) { Segment *tback= &segments[pci->backwards.next]; Segment *tfwd= &segments[pci->forwards .next]; - if (back && !(back==tback || back=tfwd)) continue; - if (fwd && !(fwd ==tback || fwd =tfwd)) continue; + if (back && !(back==tback || back==tfwd)) continue; + if (fwd && !(fwd ==tback || fwd ==tfwd)) continue; if (movei->n_movfeats>1) { /* we have to search for the one which is least effort, then */ @@ -486,36 +482,36 @@ movpos_change(Segment *back, Segment *move, *Segment *fwd, if (bestchanges==INT_MAX) { ec= EC_Invalid; goto x; } - int n_motions=0; - Motion motions[movei->n_movfeats]; + { + int n_motions=0; + Motion motions[movei->n_movfeats]; - for (feat=0, feati=movei->movfeats; - featn_movfeats; - feat++, feati++) { - if ((bestcomb - actual) / feati->weight % feati->posns) - continue; - if (kind) { - if (feati->kind != kind) { ec= EC_MovFeatKindsCombination; goto x; } - kind= feati->kind; + for (feat=0, feati=movei->movfeats; + featn_movfeats; + feat++, feati++) { + if ((bestcomb - actual) / feati->weight % feati->posns) + continue; + if (kind) { + if (feati->kind != kind) { ec= EC_MovFeatKindsCombination; goto x; } + kind= feati->kind; + } + motions[n_motions].i= feati; + motions[n_motions].posn= bestcomb / feati->weight % feati->posns; + n_motions++; } - motions[n_motions].i= feati; - motions[n_motions].posn= bestcomb / feati->weight % feati->posns; - n_motions++; - } - const KindInfo *ki= methodinfos[kind]; + const KindInfo *ki= &methodinfos[kind]; - if (chg) { - assert(move == chg->move); - } else { - chg= mp_allocate(ki,move,n_motions); - } - chg->actual= actual; - chg->on_done= on_done; - chg->u= u; + if (chg) { + assert(move == chg->move); + } else { + chg= mp_allocate(ki,move,n_motions); + } + chg->actual= actual; - ec= ki->request(chg, move, n_motions, motions, maxdelay_ms); - if (ec) goto x; + ec= ki->confirm(chg, move, n_motions, motions, maxdelay_ms); + if (ec) goto x; + } return 0; x: @@ -524,19 +520,22 @@ movpos_change(Segment *back, Segment *move, *Segment *fwd, } ErrorCode -movpos_reservechange(Segment *move, int maxdelay_ms, MovPosChange *res_r) { +movpos_reserve(Segment *move, int maxdelay_ms, MovPosChange **res_r) { MovFeatKind kind= mfk_none; + const MovFeatInfo *feati; + ErrorCode ec; + int feat; - for (feat=0; feati=movei->movfeats; - featn_movfeats; + for (feat=0, feati=move->i->movfeats; + feati->n_movfeats; feat++, feati++) if (kind) { if (feati->kind != kind) return EC_MovFeatKindsCombination; kind= feati->kind; } - const KindInfo *ki= methodinfos[kind]; - ChangeHeader *chg= mp_allocate(ki, move, movei->n_movfeats); + const KindInfo *ki= &methodinfos[kind]; + Change *chg= mp_allocate(ki, move, move->i->n_movfeats); ec= ki->reserve(chg, move, maxdelay_ms); if (ec) goto x; @@ -550,5 +549,5 @@ movpos_reservechange(Segment *move, int maxdelay_ms, MovPosChange *res_r) { void movpos_unreserve(MovPosChange *res) { if (!res) return; - req->ki->destroy(req); + res->ki->destroy(res); } diff --git a/hostside/realtime.h b/hostside/realtime.h index ec90191..f74ae99 100644 --- a/hostside/realtime.h +++ b/hostside/realtime.h @@ -118,9 +118,15 @@ int picinsn_polarity_testbit(const PicInsn *pi, const SegmentInfo *segi); /* this belongs in {au,skel}proto-pic.[ch] really but it's * more convenient here. */ +/*---------- from movpos.c ----------*/ + +void points_turning_on(void); +void points_all_abandon(void); + /*---------- tbi ----------*/ -void abandon_run(void); +void choreographers_all_abandon(void); + #include "record.h" diff --git a/hostside/safety.h b/hostside/safety.h index ec9be10..95d4e27 100644 --- a/hostside/safety.h +++ b/hostside/safety.h @@ -147,13 +147,6 @@ movpos_change(Segment *back, Segment *tomove, Segment *fwd, * If segment has already been requested to change, an attempt is * made to replace that change with the new request; if this is not * successful then the existing change will still happen. - - - If the - * new change can be done, then the old change's callback is - * forgotten and we only call the new change's when that's done. - - * * reservation should be 0, or the results of movpos_reservechange * on the same move. It is always consumed, even on error. @@ -171,7 +164,7 @@ movpos_change(Segment *back, Segment *tomove, Segment *fwd, */ ErrorCode -movpos_reserve(Segment *move, int maxdelay_ms, MovPosChange *res_r); +movpos_reserve(Segment *move, int maxdelay_ms, MovPosChange **res_r); /* Returns EC_MovFeatTooLate if the maxdelay_ms could not be met. * The resulting MovPosChange is a reservation which is guaranteed * to be useable successfully later for any movpos_change for @@ -181,8 +174,7 @@ movpos_reserve(Segment *move, int maxdelay_ms, MovPosChange *res_r); * points_all_abandon is called (see startup.c); */ -ErrorCode -movpos_unreserve(Segment *move, MovPosChange *reservation); +void movpos_unreserve(MovPosChange *reservation); /*========== speedmgr.c ==========*/ diff --git a/hostside/startup.c b/hostside/startup.c index b30c766..1831bb3 100644 --- a/hostside/startup.c +++ b/hostside/startup.c @@ -71,6 +71,11 @@ static void sta_goto(StartupState new_state) { case Sta_Run: break; } + if (new_state < Sta_Run) + choreographers_all_abandon(); + if (new_state < Sta_Resolving) + points_all_abandon(); + piob.l= 0; switch (new_state) { case Sta_Flush: break; @@ -80,6 +85,7 @@ static void sta_goto(StartupState new_state) { case Sta_Settling: enco_pic_off(&piob); break; case Sta_Resolving: resolve_begin(); + points_turning_on(); enco_pic_on(&piob); break; case Sta_Run: @@ -126,7 +132,6 @@ void serial_moredata(PicInsn *buf) { } if (PICMSG_HELLO_P(buf->d[0])) { ouhex("picioh in hello", buf->d, 1); - abandon_run(); sta_goto(Sta_Flush); buf->l= 1; return; @@ -236,6 +241,4 @@ void on_pic_nmradone(const PicInsnInfo *pii, const PicInsn *pi, int objnum) { void on_pic_detect0(const PicInsnInfo *pii, const PicInsn *pi, int objnum) { } -void abandon_run(void) { - /* fixme do something here */ -} +void choreographers_all_abandon(void) { }