chiark / gitweb /
movpos compiles and links
authorian <ian>
Sun, 6 Apr 2008 11:57:04 +0000 (11:57 +0000)
committerian <ian>
Sun, 6 Apr 2008 11:57:04 +0000 (11:57 +0000)
hostside/Makefile
hostside/cdumgr.c
hostside/errorcodes.h.gen
hostside/movpos.c
hostside/realtime.h
hostside/safety.h
hostside/startup.c

index 8f6aa74ef6eb7137f2889301635109c800b5a8a2..95873fe9a245c037420674a1dce248745c8c912a 100644 (file)
@@ -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)
index 089d9548c0705c600c393cf6c48ddd9c31ac5777..888c39c54c7b01169e79431a38eeb13f228e46bd 100644 (file)
@@ -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 */
index 9f724935c17f92fd671c82705af64062650661b2..5f44180962e67a501e53daf316fd0052d506dc24 100755 (executable)
@@ -4,7 +4,7 @@
        OK
        Invalid
        Safety
-       Points
+       MovFeatTooLate
        MovFeatKindsCombination
        BufferFull
        );
index 20cf5240bdb7ee17d399af99ad4af61b532a6411..3332ce17af323b01017fe34553b8985df20358d7 100644 (file)
@@ -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; i<pt_confirmed.n; i++) {
     PointReq *r= pt_confirmed.l[i];
     Segment *move= r->h.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;
-       feat<movei->n_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;
+        feat<movei->n_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;
-       feat<movei->n_movfeats;
+  for (feat=0, feati=move->i->movfeats;
+       feat<move->i->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);
 }
index ec9019155b28fadba2b72defe8984cda886872a6..f74ae99651e3e0f598f2768bd342ada6daddfb84 100644 (file)
@@ -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"
 
index ec9be10319ad6d3f93b39f8666e60ea98e18cbfb..95d4e27a494482b5bd0b45766fc4a609d23a639e 100644 (file)
@@ -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 ==========*/
 
index b30c766a59d103276fc9a0e34a2cccd9f093c12f..1831bb3b7d8aa8303f32c863d6cf3bdeda2d8a17 100644 (file)
@@ -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) { }