From: ian Date: Sun, 30 Mar 2008 22:50:52 +0000 (+0000) Subject: wip points handling before reorg point__enqueue etc. X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=def87206217a646ea2b227370a01c671e8296ba5;p=trains.git wip points handling before reorg point__enqueue etc. --- diff --git a/hostside/movpos.c b/hostside/movpos.c index 61ba390..d9bb74f 100644 --- a/hostside/movpos.c +++ b/hostside/movpos.c @@ -17,10 +17,12 @@ typedef struct { /* 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; @@ -31,6 +33,100 @@ typedef struct MovPosChangeDetails { 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 ----------*/ @@ -100,6 +196,8 @@ movpos_requestchange(Segment *back, Segment *move, *Segment *fwd, (*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); @@ -142,76 +240,3 @@ movpos_reservechange(Segment *move, int 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; - featn_movfeats; - feat++) { - unsigned posold= (move->movposcomb / feati->weight) % feati->posns; - for (poschange=0; poschangeposns; 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