#include "realtime.h"
-/*---------- declarations ----------*/
+/*========== declarations ==========*/
typedef struct SomeChange SomeChange;
void *u;
} ChangeHeader;
-/*---------- points ----------*/
+/*========== points ==========*/
/*
- * Currently there is only one queue for the one CDU.
+ * We maintain two queues, one for reserved one for actually confirmed
+ * requests where we know what we're doing.
*
- * We maintain a queue of change requests. The queue can also contain
- * reservations. We divide time into discrete slots, numbered with
- * clock arithmetic.
+ * We divide time into discrete slots, numbered with clock arithmetic.
*
* cslot cslot+1 cslot+2
*
* currently next in after
* changing line that
+ *
+ * We increment cslot when we issue a POINT command to the PIC.
+ * In a request, the deadline represents the latest allowable value
+ * of cslot just before that increment.
*/
typedef unsigned PtSlot;
* etc. They are only allowed while we are in a pt_... method function.
*/
-/* We increment cslot when we issue a POINT command to the PIC.
- * deadline represents the latest allowable value of cslot
- * just before that increment. */
-
#define CDU_RECHARGE 250 /*ms*/
#define POINT_MOVEMENT 50 /*ms*/
#define PT_MAX_QUEUE 15
static PtSlot pt_cslot;
-
-/*
- * We maintain two queues, one for reserved one for actually confirmed
- * requests where we know what we're doing.
- */
+static int pt_cdu_charged;
todo
actually fire points: use item, and remove it, etc.
r->motions[0].i=0;
}
+static ErrorCode pt__check(void) {
+ /* Checks whether we can meet the currently queued commitments */
+ int future, conf, resv;
+
+ 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;
+ conf++;
+ }
+
+ 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;
+ int confwhen= confr ? confr->deadline - pt_cslot : INT_MAX;
+ int resvwhen= resvr ? resvr->deadline : INT_MAX;
+ if (resvwhen < confwhen) {
+ usewhen= resvwhen;
+ resv++;
+ } else {
+ usewhen= confwhen;
+ conf++;
+ }
+ if (usewhen > future) return EC_Points;
+ future++;
+ }
+ return 0;
+}
+
+ ;
+
+
+
+
+ for (conf=0;
+ conf <
+
+
+}
+
static ErrorCode pt__enqueue(PointQueue *q, PointReq *r) { /* XA -> X */
ErrorCode ec; /* ... where X is R or C and corresponds to q */
/* or on error, XA -> A */
q->l[insat]= r;
q->n++;
- return pt_check();
+ return pt__check();
/* if this fails, indep machinery calls pt_destroy which dequeues */
}
static ErrorCode pt_reserve(SomeChange *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);
}
return ec;
}
+/*---------- entrypoints from rest of program ----------*/
+
+static void points_turning_on(void) {
+ pt_cdu_charged= 0;
+}
+
+void on_pic_charged(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
+ pt_cdu_charged= 1;
+ if (sta_state <= Sta_Settling) return;
+ fixme check fault arrangements wrt cdu and points etc.
+ fixme do something here
+}
+
-/*---------- method-independent machinery ----------*/
+/*========== method-independent machinery ==========*/
static const MethodInfo methodinfos[]= {
{ nomove_allocate, nomove_reserve, nomove_request, nomove_cancel }