chiark / gitweb /
use suid helper for sched_setscheduler
[trains.git] / hostside / realtime.h
1 /*
2  * declarations for realtime daemon
3  */
4
5 #ifndef REALTIME_H
6 #define REALTIME_H
7
8 #include "daemons.h"
9 #include "auproto-pic.h"
10 #include "dliste.h"
11
12 #include <stdarg.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <assert.h>
16 #include <stdlib.h>
17 #include <limits.h>
18 #include <stddef.h>
19 #include <ctype.h>
20 #include <math.h>
21
22 #include <sys/time.h>
23 #include <sys/stat.h>
24 #include <sys/mman.h>
25
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <dirent.h>
29
30 #include "../layout/layout-data.h"
31
32 typedef struct Segment Segment;
33 typedef struct Train Train;
34 typedef struct TimeoutEvent TimeoutEvent;
35
36 /*---------- from retransmit.c ----------*/
37
38 typedef struct RetransmitRelaxedNode RetransmitRelaxedNode;
39 typedef union RetransmitUrgentNode RetransmitUrgentNode;
40 typedef unsigned Retransmit__Time;
41
42   /* Contents of the retransmission nodes is generally all for use by
43    * retransmit.c only; as a special exception, caller may edit pi
44    * directly.  Normally, though, pi is set by supplying an NMRA
45    * command to one of the _queue functions; iff the Nmra* is
46    * non-null, _queue will add an NMRA checksum and update pi.
47    */
48 struct RetransmitRelaxedNode {
49   PicInsn pi;
50   DLIST_NODE(RetransmitRelaxedNode) rr;
51 };
52 union RetransmitUrgentNode {
53   PicInsn pi;
54   struct {
55     RetransmitRelaxedNode relaxed;
56     int ix;
57     Retransmit__Time when;
58     DLIST_NODE(RetransmitUrgentNode) queue;
59   } u;
60 };
61
62 void retransmit_start(void);
63 void retransmit_something(void);
64
65 void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, Nmra *n);
66 void retransmit_relaxed_requeue(RetransmitRelaxedNode *rn, Nmra *n);
67 void retransmit_relaxed_cancel(RetransmitRelaxedNode *rn);
68
69 void retransmit_urgent_queue(RetransmitUrgentNode *rn, Nmra *n);
70 void retransmit_urgent_queue_relaxed(RetransmitUrgentNode *urg, Nmra *n);
71 void retransmit_urgent_requeue(RetransmitUrgentNode *rn, Nmra *n);
72 void retransmit_urgent_cancel(RetransmitUrgentNode *rn);
73
74   /* ... NB: these are NOT idempotent.  Use _requeue it's queued;
75    * _requeue is just _cancel followed by queue. */
76
77 /*---------- features, filled in by record, used by features.c ----------*/
78
79 #define FEATURESADDR_TRANSMITS 4
80   /* 0..2 are func0to4 func5to8 func9to12 and speed cmd
81    * pi.l is 0 if not transmitting */
82
83 typedef struct FeaturesAddr {
84   struct FeaturesAddr *next;
85   int addr, cbitmap;
86   RetransmitRelaxedNode rn[FEATURESADDR_TRANSMITS];
87 } FeaturesAddr;
88
89 typedef struct {
90   FeaturesAddr *a;
91   int bitval; /* may have no or several bits set */
92   int speedstep; /* -ve means backwards; 0 means not to use motor for feat */
93 } FeaturesFeature;
94
95 typedef struct FeaturesTarget {
96   struct FeaturesTarget *next;
97   char *pname;
98   char *featchs; /* null-terminated */
99   FeaturesFeature **feats; /* same order as featchs */
100 } FeaturesTarget;
101
102 extern int n_trains;
103 extern Train *trains;
104 extern Segment *segments;
105
106 extern FeaturesTarget *feattargs;
107 extern FeaturesAddr *feataddrs;
108
109 /*---------- global variables, in realtime.c ----------*/
110
111 extern CommandInput cmdi;
112 extern int picio_send_noise;
113
114 #define UPO (&(cmdi.out))
115
116 #define CIXF_ANYSTA   1u
117 #define CIXF_FORCE    2u
118
119 /*---------- from/for startup.c ----------*/
120
121 #include "stastate.h"
122
123 void sta_startup(void);
124 void sta_finalising_done(void);
125 void serial_moredata(PicInsn *buf);
126
127 extern StartupState sta_state;
128 extern const char *const stastatelist[];
129
130 void resolve_begin(void); /* from resolve.c */
131 int resolve_complete(void);
132 void resolve_motioncheck(void);
133
134 void waggle_settle(void); /* from movpos.c */
135 void waggle_startup_manual(void);
136
137 /*---------- from/for record.c and persist.c ----------*/
138
139 void records_parse(const char **argv);
140 void persist_entrails_interpret(void);
141 void persist_entrails_run_converter(void);
142 void persist_install(void);
143
144 extern const char *persist_fn;
145 extern char *persist_record_converted;
146
147 void persist_map_veryearly(void);
148
149 /*---------- from/for realtime.c ----------*/
150
151 void oupicio(const char *dirn, const PicInsnInfo *pii, int obj, int v);
152 void ouhexi(const char *word, const Byte *command, int length);
153 void ouhexo(const char *word, const Byte *command, int length);
154
155 void serial_transmit(const PicInsn *pi);
156
157 /*---------- for/from simulate.c ----------*/
158
159 void serial_indata_process(int buf_used);
160
161 void sim_initialise(const char *logduplicate);
162 void sim_run(void);
163
164 void simlogv(const char *fmt, va_list al);
165 void simlog(const char *fmt, ...);
166 void simlog_serial(const Byte *data, int length);
167 void simlog_flush(void);
168 void simlog_open(const char *fn);
169
170 void mgettimeofday(struct timeval *tv); /* contains magic for simulation */
171 void *toev_callback(oop_source *source, struct timeval tv, void *t_v);
172
173 void sim_toev_start(TimeoutEvent *toev);
174 void sim_toev_stop(TimeoutEvent *toev);
175 void sim_mgettimeofday(struct timeval *tv);
176
177 extern int simlog_full;
178 extern const char *simulate;
179
180 extern PicInsn serial_buf;
181
182 /*---------- from actual.c ----------*/
183
184 int picinsn_polarity_testbit(const PicInsn *pi, const SegmentInfo *segi);
185   /* this belongs in {au,skel}proto-pic.[ch] really but it's
186    * more convenient here. */
187
188 /*---------- from movpos.c ----------*/
189
190 void points_turning_on(void);
191 void motions_all_abandon(void);
192
193 /*---------- from eventhelp.c ----------*/
194
195 extern const char toev_fast_pclass[];
196
197 typedef void TimeoutEventFn(TimeoutEvent*);
198 struct TimeoutEvent {         /* Undefined   Idle      Running     set by   */
199   int running;                /*  any         0         1           toev_   */
200   int duration; /*ms*/        /*  any         any[1]    any[1]      caller  */
201   TimeoutEventFn *callback;   /*  any         any       valid[2]    caller  */
202   struct timeval abs;         /*  any         any       valid       toev_   */
203   const char *pclass, *pinst; /*  any         any       valid       caller  */
204 };  /* [1] duration must be >=0 or -1 when toev_start is called;
205      * [2] callback may be modified while timeout is running;
206      *      value used is that prevailing when timeout happens
207      * when the timeout happens, TimeoutEvent's state goes from R to I
208      * and then callback member is read and the function called
209      */
210
211 void toev_init(TimeoutEvent*);    /* U -> I */
212 void toev_start(TimeoutEvent*);   /* IR -> R; reads duration */
213   /* if duration is -1 then is same as toev_stop */
214 void toev_stop(TimeoutEvent*);    /* IR -> I */
215
216 /*---------- from rtprio.c ----------*/
217
218 void realtime_priority(void);
219
220 #define RTFEAT_DEFAULTS  0100u /* turns on MLOCK and SCHEDPRIO iff not sim */
221 #define RTFEAT_MEM       0001u /* mlock */
222 #define RTFEAT_CPU       0002u /* hard CPU scheduling priority */
223
224 #define RTFEAT_ALL_SHIFT 16
225 #define RTFEAT_ALL(x) (RTFEAT_##x << RTFEAT_ALL_SHIFT)
226   /* RTFEAT_ALL(FOO) is relevant only if RTFEAT_FOO selected, and means
227    *  not to apply the normal limit to the grabbing of FOO */
228
229 extern unsigned rtfeats_use;
230
231 /*---------- tbi ----------*/
232
233 void choreographers_all_abandon(void);
234
235 #define DUPO(ctx) UPO, "debug " ctx " : "
236
237 #include "record.h"
238
239 #define PERSIST_CONVERT_OPTION "--persist-convert-entrails"
240
241 #include "safety.h"
242
243 #define CTYPE(isfoobar,ch) (isfoobar((unsigned char)(ch)))
244
245 #endif /*REALTIME_H*/