1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
|
/***** spin: spin.h *****/
/* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */
/* All Rights Reserved. This software is for educational purposes only. */
/* No guarantee whatsoever is expressed or implied by the distribution of */
/* this code. Permission is given to distribute this code provided that */
/* this introductory message is not removed and no monies are exchanged. */
/* Software written by Gerard J. Holzmann. For tool documentation see: */
/* http://spinroot.com/ */
/* Send all bug-reports and/or questions to: bugs@spinroot.com */
#ifndef SEEN_SPIN_H
#define SEEN_SPIN_H
#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef struct Lextok {
unsigned short ntyp; /* node type */
short ismtyp; /* CONST derived from MTYP */
int val; /* value attribute */
int ln; /* line number */
int indstep; /* part of d_step sequence */
struct Symbol *fn; /* file name */
struct Symbol *sym; /* symbol reference */
struct Sequence *sq; /* sequence */
struct SeqList *sl; /* sequence list */
struct Lextok *lft, *rgt; /* children in parse tree */
} Lextok;
typedef struct Slicer {
Lextok *n; /* global var, usable as slice criterion */
short code; /* type of use: DEREF_USE or normal USE */
short used; /* set when handled */
struct Slicer *nxt; /* linked list */
} Slicer;
typedef struct Access {
struct Symbol *who; /* proctype name of accessor */
struct Symbol *what; /* proctype name of accessed */
int cnt, typ; /* parameter nr and, e.g., 's' or 'r' */
struct Access *lnk; /* linked list */
} Access;
typedef struct Symbol {
char *name;
int Nid; /* unique number for the name */
unsigned short type; /* bit,short,.., chan,struct */
unsigned char hidden; /* bit-flags:
1=hide, 2=show,
4=bit-equiv, 8=byte-equiv,
16=formal par, 32=inline par,
64=treat as if local; 128=read at least once
*/
unsigned char colnr; /* for use with xspin during simulation */
int nbits; /* optional width specifier */
int nel; /* 1 if scalar, >1 if array */
int setat; /* last depth value changed */
int *val; /* runtime value(s), initl 0 */
Lextok **Sval; /* values for structures */
int xu; /* exclusive r or w by 1 pid */
struct Symbol *xup[2]; /* xr or xs proctype */
struct Access *access;/* e.g., senders and receives of chan */
Lextok *ini; /* initial value, or chan-def */
Lextok *Slst; /* template for structure if struct */
struct Symbol *Snm; /* name of the defining struct */
struct Symbol *owner; /* set for names of subfields in typedefs */
struct Symbol *context; /* 0 if global, or procname */
struct Symbol *next; /* linked list */
} Symbol;
typedef struct Ordered { /* links all names in Symbol table */
struct Symbol *entry;
struct Ordered *next;
} Ordered;
typedef struct Queue {
short qid; /* runtime q index */
int qlen; /* nr messages stored */
int nslots, nflds; /* capacity, flds/slot */
int setat; /* last depth value changed */
int *fld_width; /* type of each field */
int *contents; /* the values stored */
int *stepnr; /* depth when each msg was sent */
struct Queue *nxt; /* linked list */
} Queue;
typedef struct FSM_state { /* used in pangen5.c - dataflow */
int from; /* state number */
int seen; /* used for dfs */
int in; /* nr of incoming edges */
int cr; /* has reachable 1-relevant successor */
int scratch;
unsigned long *dom, *mod; /* to mark dominant nodes */
struct FSM_trans *t; /* outgoing edges */
struct FSM_trans *p; /* incoming edges, predecessors */
struct FSM_state *nxt; /* linked list of all states */
} FSM_state;
typedef struct FSM_trans { /* used in pangen5.c - dataflow */
int to;
short relevant; /* when sliced */
short round; /* ditto: iteration when marked */
struct FSM_use *Val[2]; /* 0=reads, 1=writes */
struct Element *step;
struct FSM_trans *nxt;
} FSM_trans;
typedef struct FSM_use { /* used in pangen5.c - dataflow */
Lextok *n;
Symbol *var;
int special;
struct FSM_use *nxt;
} FSM_use;
typedef struct Element {
Lextok *n; /* defines the type & contents */
int Seqno; /* identifies this el within system */
int seqno; /* identifies this el within a proc */
int merge; /* set by -O if step can be merged */
int merge_start;
int merge_single;
short merge_in; /* nr of incoming edges */
short merge_mark; /* state was generated in merge sequence */
unsigned char status; /* used by analyzer generator */
struct FSM_use *dead; /* optional dead variable list */
struct SeqList *sub; /* subsequences, for compounds */
struct SeqList *esc; /* zero or more escape sequences */
struct Element *Nxt; /* linked list - for global lookup */
struct Element *nxt; /* linked list - program structure */
} Element;
typedef struct Sequence {
Element *frst;
Element *last; /* links onto continuations */
Element *extent; /* last element in original */
int maxel; /* 1+largest id in sequence */
} Sequence;
typedef struct SeqList {
Sequence *this; /* one sequence */
struct SeqList *nxt; /* linked list */
} SeqList;
typedef struct Label {
Symbol *s;
Symbol *c;
Element *e;
int visible; /* label referenced in claim (slice relevant) */
struct Label *nxt;
} Label;
typedef struct Lbreak {
Symbol *l;
struct Lbreak *nxt;
} Lbreak;
typedef struct RunList {
Symbol *n; /* name */
int tn; /* ordinal of type */
int pid; /* process id */
int priority; /* for simulations only */
Element *pc; /* current stmnt */
Sequence *ps; /* used by analyzer generator */
Lextok *prov; /* provided clause */
Symbol *symtab; /* local variables */
struct RunList *nxt; /* linked list */
} RunList;
typedef struct ProcList {
Symbol *n; /* name */
Lextok *p; /* parameters */
Sequence *s; /* body */
Lextok *prov; /* provided clause */
short tn; /* ordinal number */
short det; /* deterministic */
struct ProcList *nxt; /* linked list */
} ProcList;
typedef Lextok *Lexptr;
#define YYSTYPE Lexptr
#define ZN (Lextok *)0
#define ZS (Symbol *)0
#define ZE (Element *)0
#define DONE 1 /* status bits of elements */
#define ATOM 2 /* part of an atomic chain */
#define L_ATOM 4 /* last element in a chain */
#define I_GLOB 8 /* inherited global ref */
#define DONE2 16 /* used in putcode and main*/
#define D_ATOM 32 /* deterministic atomic */
#define ENDSTATE 64 /* normal endstate */
#define CHECK2 128
#define Nhash 255 /* slots in symbol hash-table */
#define XR 1 /* non-shared receive-only */
#define XS 2 /* non-shared send-only */
#define XX 4 /* overrides XR or XS tag */
#define CODE_FRAG 2 /* auto-numbered code-fragment */
#define CODE_DECL 4 /* auto-numbered c_decl */
#define PREDEF 3 /* predefined name: _p, _last */
#define UNSIGNED 5 /* val defines width in bits */
#define BIT 1 /* also equal to width in bits */
#define BYTE 8 /* ditto */
#define SHORT 16 /* ditto */
#define INT 32 /* ditto */
#define CHAN 64 /* not */
#define STRUCT 128 /* user defined structure name */
#define SOMETHINGBIG 65536
#define RATHERSMALL 512
#ifndef max
#define max(a,b) (((a)<(b)) ? (b) : (a))
#endif
enum { INIV, PUTV, LOGV }; /* for pangen[14].c */
/***** prototype definitions *****/
Element *eval_sub(Element *);
Element *get_lab(Lextok *, int);
Element *huntele(Element *, int, int);
Element *huntstart(Element *);
Element *target(Element *);
Lextok *do_unless(Lextok *, Lextok *);
Lextok *expand(Lextok *, int);
Lextok *getuname(Symbol *);
Lextok *mk_explicit(Lextok *, int, int);
Lextok *nn(Lextok *, int, Lextok *, Lextok *);
Lextok *rem_lab(Symbol *, Lextok *, Symbol *);
Lextok *rem_var(Symbol *, Lextok *, Symbol *, Lextok *);
Lextok *tail_add(Lextok *, Lextok *);
ProcList *ready(Symbol *, Lextok *, Sequence *, int, Lextok *);
SeqList *seqlist(Sequence *, SeqList *);
Sequence *close_seq(int);
Symbol *break_dest(void);
Symbol *findloc(Symbol *);
Symbol *has_lab(Element *, int);
Symbol *lookup(char *);
Symbol *prep_inline(Symbol *, Lextok *);
char *emalloc(int);
long Rand(void);
int any_oper(Lextok *, int);
int any_undo(Lextok *);
int c_add_sv(FILE *);
int cast_val(int, int, int);
int checkvar(Symbol *, int);
int Cnt_flds(Lextok *);
int cnt_mpars(Lextok *);
int complete_rendez(void);
int enable(Lextok *);
int Enabled0(Element *);
int eval(Lextok *);
int find_lab(Symbol *, Symbol *, int);
int find_maxel(Symbol *);
int full_name(FILE *, Lextok *, Symbol *, int);
int getlocal(Lextok *);
int getval(Lextok *);
int glob_inline(char *);
int has_typ(Lextok *, int);
int in_bound(Symbol *, int);
int interprint(FILE *, Lextok *);
int printm(FILE *, Lextok *);
int ismtype(char *);
int isproctype(char *);
int isutype(char *);
int Lval_struct(Lextok *, Symbol *, int, int);
int main(int, char **);
int pc_value(Lextok *);
int proper_enabler(Lextok *);
int putcode(FILE *, Sequence *, Element *, int, int, int);
int q_is_sync(Lextok *);
int qlen(Lextok *);
int qfull(Lextok *);
int qmake(Symbol *);
int qrecv(Lextok *, int);
int qsend(Lextok *);
int remotelab(Lextok *);
int remotevar(Lextok *);
int Rval_struct(Lextok *, Symbol *, int);
int setlocal(Lextok *, int);
int setval(Lextok *, int);
int sputtype(char *, int);
int Sym_typ(Lextok *);
int tl_main(int, char *[]);
int Width_set(int *, int, Lextok *);
int yyparse(void);
int yywrap(void);
int yylex(void);
void AST_track(Lextok *, int);
void add_seq(Lextok *);
void alldone(int);
void announce(char *);
void c_state(Symbol *, Symbol *, Symbol *);
void c_add_def(FILE *);
void c_add_loc(FILE *, char *);
void c_add_locinit(FILE *, int, char *);
void c_add_use(FILE *);
void c_chandump(FILE *);
void c_preview(void);
void c_struct(FILE *, char *, Symbol *);
void c_track(Symbol *, Symbol *, Symbol *);
void c_var(FILE *, char *, Symbol *);
void c_wrapper(FILE *);
void chanaccess(void);
void check_param_count(int, Lextok *);
void checkrun(Symbol *, int);
void comment(FILE *, Lextok *, int);
void cross_dsteps(Lextok *, Lextok *);
void doq(Symbol *, int, RunList *);
void dotag(FILE *, char *);
void do_locinits(FILE *);
void do_var(FILE *, int, char *, Symbol *, char *, char *, char *);
void dump_struct(Symbol *, char *, RunList *);
void dumpclaims(FILE *, int, char *);
void dumpglobals(void);
void dumplabels(void);
void dumplocal(RunList *);
void dumpsrc(int, int);
void fatal(char *, char *);
void fix_dest(Symbol *, Symbol *);
void genaddproc(void);
void genaddqueue(void);
void gencodetable(FILE *);
void genheader(void);
void genother(void);
void gensrc(void);
void gensvmap(void);
void genunio(void);
void ini_struct(Symbol *);
void loose_ends(void);
void make_atomic(Sequence *, int);
void match_trail(void);
void no_side_effects(char *);
void nochan_manip(Lextok *, Lextok *, int);
void non_fatal(char *, char *);
void ntimes(FILE *, int, int, char *c[]);
void open_seq(int);
void p_talk(Element *, int);
void pickup_inline(Symbol *, Lextok *);
void plunk_c_decls(FILE *);
void plunk_c_fcts(FILE *);
void plunk_expr(FILE *, char *);
void plunk_inline(FILE *, char *, int);
void prehint(Symbol *);
void preruse(FILE *, Lextok *);
void prune_opts(Lextok *);
void pstext(int, char *);
void pushbreak(void);
void putname(FILE *, char *, Lextok *, int, char *);
void putremote(FILE *, Lextok *, int);
void putskip(int);
void putsrc(Element *);
void putstmnt(FILE *, Lextok *, int);
void putunames(FILE *);
void rem_Seq(void);
void runnable(ProcList *, int, int);
void sched(void);
void setaccess(Symbol *, Symbol *, int, int);
void set_lab(Symbol *, Element *);
void setmtype(Lextok *);
void setpname(Lextok *);
void setptype(Lextok *, int, Lextok *);
void setuname(Lextok *);
void setutype(Lextok *, Symbol *, Lextok *);
void setxus(Lextok *, int);
void Srand(unsigned);
void start_claim(int);
void struct_name(Lextok *, Symbol *, int, char *);
void symdump(void);
void symvar(Symbol *);
void trackchanuse(Lextok *, Lextok *, int);
void trackvar(Lextok *, Lextok *);
void trackrun(Lextok *);
void trapwonly(Lextok *, char *); /* spin.y and main.c */
void typ2c(Symbol *);
void typ_ck(int, int, char *);
void undostmnt(Lextok *, int);
void unrem_Seq(void);
void unskip(int);
void varcheck(Element *, Element *);
void whoruns(int);
void wrapup(int);
void yyerror(char *, ...);
#endif
|