xref: /plan9-contrib/sys/src/cmd/spin/pangen7.h (revision de2caf28f9ba1a56e70be94a699435d36eb50311)
1*de2caf28SDavid du Colombier /***** spin: pangen7.h *****/
2*de2caf28SDavid du Colombier 
3*de2caf28SDavid du Colombier /*
4*de2caf28SDavid du Colombier  * This file is part of the public release of Spin. It is subject to the
5*de2caf28SDavid du Colombier  * terms in the LICENSE file that is included in this source directory.
6*de2caf28SDavid du Colombier  * Tool documentation is available at http://spinroot.com
7*de2caf28SDavid du Colombier  */
8*de2caf28SDavid du Colombier 
9*de2caf28SDavid du Colombier static const char *pan_par[] = {	/* generates pan.p */
10*de2caf28SDavid du Colombier 	"#include <sys/ipc.h>",
11*de2caf28SDavid du Colombier 	"#include <sys/shm.h>",
12*de2caf28SDavid du Colombier 	"#include <time.h>",	/* for nanosleep */
13*de2caf28SDavid du Colombier 	"#include <assert.h>",
14*de2caf28SDavid du Colombier 	"#include <limits.h>",
15*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
16*de2caf28SDavid du Colombier 	"#include <unistd.h>",		/* for rmdir */
17*de2caf28SDavid du Colombier 	"#include <sys/stat.h>",	/* for mkdir */
18*de2caf28SDavid du Colombier 	"#include <sys/types.h>",
19*de2caf28SDavid du Colombier 	"#include <fcntl.h>",		/* for open */
20*de2caf28SDavid du Colombier 	"#endif",
21*de2caf28SDavid du Colombier 	"",
22*de2caf28SDavid du Colombier 	"#define Max(a,b)	(((a)>(b))?(a):(b))",
23*de2caf28SDavid du Colombier 	"#ifndef WAIT_MAX",
24*de2caf28SDavid du Colombier 	"	#define WAIT_MAX	2	/* seconds */",
25*de2caf28SDavid du Colombier 	"#endif",
26*de2caf28SDavid du Colombier 	"#define BFS_GEN 	2	/* current and next generation */",
27*de2caf28SDavid du Colombier 	"",
28*de2caf28SDavid du Colombier 	"typedef struct BFS_Slot BFS_Slot;",
29*de2caf28SDavid du Colombier 	"typedef struct BFS_shared BFS_shared;",
30*de2caf28SDavid du Colombier 	"typedef struct BFS_data BFS_data;",
31*de2caf28SDavid du Colombier 	"",
32*de2caf28SDavid du Colombier 	"struct BFS_Slot {",
33*de2caf28SDavid du Colombier 	" #ifdef BFS_FIFO",
34*de2caf28SDavid du Colombier 	"	enum bfs_types	type;		/* message type */",
35*de2caf28SDavid du Colombier 	" #endif",
36*de2caf28SDavid du Colombier 	"	BFS_State	*s_data;	/* state data */",
37*de2caf28SDavid du Colombier 	" #ifndef BFS_QSZ",
38*de2caf28SDavid du Colombier 	"	BFS_Slot	*nxt;		/* linked list */",
39*de2caf28SDavid du Colombier 	" #endif",
40*de2caf28SDavid du Colombier 	"};",
41*de2caf28SDavid du Colombier 	"",
42*de2caf28SDavid du Colombier 	"struct BFS_data {",
43*de2caf28SDavid du Colombier 	"	double memcnt;",
44*de2caf28SDavid du Colombier 	"	double nstates;",
45*de2caf28SDavid du Colombier 	"	double nlinks;",
46*de2caf28SDavid du Colombier 	"	double truncs;",
47*de2caf28SDavid du Colombier 	"	ulong mreached;",
48*de2caf28SDavid du Colombier 	"	ulong vsize;",
49*de2caf28SDavid du Colombier 	"	ulong memory_left;",
50*de2caf28SDavid du Colombier 	"	ulong punted;",
51*de2caf28SDavid du Colombier 	"	ulong errors;",
52*de2caf28SDavid du Colombier 	"	int   override;	/* after crash, if another proc clears locks */",
53*de2caf28SDavid du Colombier 	"};",
54*de2caf28SDavid du Colombier 	"",
55*de2caf28SDavid du Colombier 	"struct BFS_shared {	/* about 13K for BFS_MAXPROCS=16 and BFS_MAXLOCKS=1028 */",
56*de2caf28SDavid du Colombier 	"	volatile ulong	quit;	/* set to signal termination -- one word */",
57*de2caf28SDavid du Colombier 	"	volatile ulong	started;",
58*de2caf28SDavid du Colombier 	"",
59*de2caf28SDavid du Colombier 	"	volatile uchar	sh_owner[BFS_MAXLOCKS];		/* optional */",
60*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
61*de2caf28SDavid du Colombier 	"	volatile uchar	in_count[BFS_MAXLOCKS];		/* optional */",
62*de2caf28SDavid du Colombier 	"#endif",
63*de2caf28SDavid du Colombier 	"	volatile int	sh_locks[BFS_MAXLOCKS];",
64*de2caf28SDavid du Colombier 	"	volatile ulong	wait_count[BFS_MAXLOCKS];	/* optional */",
65*de2caf28SDavid du Colombier 	"",
66*de2caf28SDavid du Colombier 	"	volatile BFS_data bfs_data[BFS_MAXPROCS];",
67*de2caf28SDavid du Colombier 	"	volatile uchar	bfs_flag[BFS_MAXPROCS]; /* running 0, normal exit 1, abnormal 2 */",
68*de2caf28SDavid du Colombier 	"	volatile uchar	bfs_idle[BFS_MAXPROCS]; /* set when all input queues are empty */",
69*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
70*de2caf28SDavid du Colombier 	"	volatile uchar	bfs_out_cnt[BFS_MAXPROCS]; /* set when core writes a state */",
71*de2caf28SDavid du Colombier 	"#endif",
72*de2caf28SDavid du Colombier 	"",
73*de2caf28SDavid du Colombier 	"#ifdef BFS_QSZ",
74*de2caf28SDavid du Colombier 	"	#define BFS_NORECYCLE",
75*de2caf28SDavid du Colombier 	"	#if BFS_QSZ<=0",
76*de2caf28SDavid du Colombier 	"		#error BFS_QSZ must be positive",
77*de2caf28SDavid du Colombier 	"	#endif",
78*de2caf28SDavid du Colombier 	"	#ifdef BFS_FIFO",
79*de2caf28SDavid du Colombier 	"		#error BFS_QSZ cannot be combined with BFS_FIFO",
80*de2caf28SDavid du Colombier 	"	#endif",
81*de2caf28SDavid du Colombier 	"	#ifdef BFS_DISK",
82*de2caf28SDavid du Colombier 	"		#error BFS_QSZ cannot be combined with BFS_DISK",
83*de2caf28SDavid du Colombier 	"	#endif",
84*de2caf28SDavid du Colombier 	"	volatile BFS_Slot bfsq[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS][BFS_QSZ];",
85*de2caf28SDavid du Colombier 	"	volatile uint bfs_ix[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];",
86*de2caf28SDavid du Colombier 	"#else",
87*de2caf28SDavid du Colombier 	"	volatile BFS_Slot *head[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];",
88*de2caf28SDavid du Colombier 	"#endif",
89*de2caf28SDavid du Colombier 	"",
90*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
91*de2caf28SDavid du Colombier 	"	volatile BFS_Slot *tail[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];",
92*de2caf28SDavid du Colombier 	"	volatile BFS_Slot *dels[BFS_GEN][BFS_MAXPROCS][BFS_MAXPROCS];",
93*de2caf28SDavid du Colombier 	"#endif",
94*de2caf28SDavid du Colombier 	"#ifdef BFS_LOGMEM",
95*de2caf28SDavid du Colombier 	"	volatile ulong logmem[1024];",
96*de2caf28SDavid du Colombier 	"#endif",
97*de2caf28SDavid du Colombier 	"	volatile ulong mem_left;",
98*de2caf28SDavid du Colombier 	"	volatile uchar *allocator;	/* start of shared heap, must be last */",
99*de2caf28SDavid du Colombier 	"};",
100*de2caf28SDavid du Colombier 	"",
101*de2caf28SDavid du Colombier 	"enum bfs_types { EMPTY = 0, STATE, DELETED };",
102*de2caf28SDavid du Colombier 	"",
103*de2caf28SDavid du Colombier 	"extern volatile uchar *bfs_get_shared_mem(key_t, size_t);",
104*de2caf28SDavid du Colombier 	"extern BFS_Slot  * bfs_new_slot(BFS_Trail *);",
105*de2caf28SDavid du Colombier 	"extern BFS_Slot  * bfs_prep_slot(BFS_Trail *, BFS_Slot *);",
106*de2caf28SDavid du Colombier 	"extern BFS_Slot  * bfs_next(void);",
107*de2caf28SDavid du Colombier 	"extern BFS_Slot  * bfs_pack_state(Trail *, BFS_Trail *, int, BFS_Slot *);",
108*de2caf28SDavid du Colombier 	"extern SV_Hold   * bfs_new_sv(int);",
109*de2caf28SDavid du Colombier 	"#if NRUNS>0",
110*de2caf28SDavid du Colombier 	"extern EV_Hold   * bfs_new_sv_mask(int);",
111*de2caf28SDavid du Colombier 	"#endif",
112*de2caf28SDavid du Colombier 	"extern BFS_Trail * bfs_grab_trail(void);",
113*de2caf28SDavid du Colombier 	"extern BFS_Trail * bfs_unpack_state(BFS_Slot *);",
114*de2caf28SDavid du Colombier 	"extern int         bfs_all_empty(void);",
115*de2caf28SDavid du Colombier 	"extern int         bfs_all_idle(void);",
116*de2caf28SDavid du Colombier 	"extern int         bfs_all_running(void);",
117*de2caf28SDavid du Colombier 	"extern int         bfs_idle_and_empty(void);",
118*de2caf28SDavid du Colombier 	"extern size_t	    bfs_find_largest(key_t);",
119*de2caf28SDavid du Colombier 	"",
120*de2caf28SDavid du Colombier 	"extern void	bfs_clear_locks(void);",
121*de2caf28SDavid du Colombier 	"extern void	bfs_drop_shared_memory(void);",
122*de2caf28SDavid du Colombier 	"extern void	bfs_explore_state(BFS_Slot *);",
123*de2caf28SDavid du Colombier 	"extern void	bfs_initial_state(void);",
124*de2caf28SDavid du Colombier 	"extern void	bfs_mark_done(int);",
125*de2caf28SDavid du Colombier 	"extern void	bfs_printf(const char *fmt, ...);",
126*de2caf28SDavid du Colombier 	"extern void	bfs_push_state(Trail *, BFS_Trail *, int);",
127*de2caf28SDavid du Colombier 	"extern void	bfs_recycle(BFS_Slot *);",
128*de2caf28SDavid du Colombier 	"extern void	bfs_release_trail(BFS_Trail *);",
129*de2caf28SDavid du Colombier 	"extern void	bfs_run(void);",
130*de2caf28SDavid du Colombier 	"extern void	bfs_setup_mem(void);",
131*de2caf28SDavid du Colombier 	"extern void	bfs_setup(void);",
132*de2caf28SDavid du Colombier 	"extern void	bfs_shutdown(const char *);",
133*de2caf28SDavid du Colombier 	"extern void	bfs_statistics(void);",
134*de2caf28SDavid du Colombier 	"extern void	bfs_store_state(Trail *, short);",
135*de2caf28SDavid du Colombier 	"extern void	bfs_set_toggle(void);",
136*de2caf28SDavid du Colombier 	"extern void	bfs_update(void);",
137*de2caf28SDavid du Colombier 	"",
138*de2caf28SDavid du Colombier 	"#ifdef MA",
139*de2caf28SDavid du Colombier 	"	#error cannot combine -DMA with -DBFS_PAR",
140*de2caf28SDavid du Colombier 	"	/* would require us to parallelize g_store */",
141*de2caf28SDavid du Colombier 	"#endif",
142*de2caf28SDavid du Colombier 	"#ifdef BCS",
143*de2caf28SDavid du Colombier 	"	#error cannot combine -DBCS with -DBFS_PAR",
144*de2caf28SDavid du Colombier 	"#endif",
145*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
146*de2caf28SDavid du Colombier 	"	#ifdef BFS_FIFO",
147*de2caf28SDavid du Colombier 	"		#error cannot combine BFS_DISK and BFS_FIFO",
148*de2caf28SDavid du Colombier 	"	#endif",
149*de2caf28SDavid du Colombier 	"	extern void bfs_disk_start(void);",
150*de2caf28SDavid du Colombier 	"	extern void bfs_disk_stop(void);",
151*de2caf28SDavid du Colombier 	"	extern void bfs_disk_out(void);",
152*de2caf28SDavid du Colombier 	"	extern void bfs_disk_inp(void);",
153*de2caf28SDavid du Colombier 	"	extern void bfs_disk_iclose(void);",
154*de2caf28SDavid du Colombier 	"	extern void bfs_disk_oclose(void);",
155*de2caf28SDavid du Colombier 	"	int bfs_out_fd[BFS_MAXPROCS];",
156*de2caf28SDavid du Colombier 	"	int bfs_inp_fd[BFS_MAXPROCS];",
157*de2caf28SDavid du Colombier 	"#endif",
158*de2caf28SDavid du Colombier 	"",
159*de2caf28SDavid du Colombier 	"static BFS_shared *shared_memory;",
160*de2caf28SDavid du Colombier 	"#ifndef BFS_QSZ",
161*de2caf28SDavid du Colombier 	"static BFS_Slot   *bfs_free_slot; /* local free list */",
162*de2caf28SDavid du Colombier 	"#endif",
163*de2caf28SDavid du Colombier 	"static BFS_Slot    bfs_null;",
164*de2caf28SDavid du Colombier 	"static SV_Hold    *bfs_svfree[VECTORSZ];",
165*de2caf28SDavid du Colombier 	"static uchar	*bfs_heap;	/* local pointer into heap */",
166*de2caf28SDavid du Colombier 	"static ulong	bfs_left;	/* local part of shared heap */",
167*de2caf28SDavid du Colombier 	"#if NRUNS>0",
168*de2caf28SDavid du Colombier 	"static void	bfs_keep(EV_Hold *);",
169*de2caf28SDavid du Colombier 	"#endif",
170*de2caf28SDavid du Colombier 	"static long	bfs_sent;	/* nr msgs sent -- local to each process */",
171*de2caf28SDavid du Colombier 	"static long	bfs_rcvd;	/* nr msgs rcvd */",
172*de2caf28SDavid du Colombier 	"static long	bfs_sleep_cnt;	/* stats */",
173*de2caf28SDavid du Colombier 	"static long	bfs_wcount;",
174*de2caf28SDavid du Colombier 	"static long	bfs_gcount;",
175*de2caf28SDavid du Colombier 	"static ulong	bfs_total_shared;",
176*de2caf28SDavid du Colombier 	"#ifdef BFS_STAGGER",
177*de2caf28SDavid du Colombier 	" static int	bfs_stage_cnt = 0;",
178*de2caf28SDavid du Colombier 	" static void	bfs_stagger_flush(void);",
179*de2caf28SDavid du Colombier 	"#endif",
180*de2caf28SDavid du Colombier 	"static int	bfs_toggle;	/* local variable, 0 or 1 */",
181*de2caf28SDavid du Colombier 	"static int	bfs_qscan;	/* scan input queues in order */",
182*de2caf28SDavid du Colombier 	"static ulong	bfs_snapped;",
183*de2caf28SDavid du Colombier 	"static int	shared_mem_id;",
184*de2caf28SDavid du Colombier 	"#ifndef NOREDUCE",
185*de2caf28SDavid du Colombier 	"static int	bfs_nps;	/* no preselection */",
186*de2caf28SDavid du Colombier 	"#endif",
187*de2caf28SDavid du Colombier 	"ulong	bfs_punt;	/* states dropped for lack of memory */",
188*de2caf28SDavid du Colombier 	"#if defined(VERBOSE) || defined(BFS_CHECK)",
189*de2caf28SDavid du Colombier 	"static const char *bfs_sname[] = {",
190*de2caf28SDavid du Colombier 	"	\"EMPTY\",	/* 0 */",
191*de2caf28SDavid du Colombier 	"	\"STATE\",	/* 1 */",
192*de2caf28SDavid du Colombier 	"	\"STATE\",	/* 2 = DELETED */",
193*de2caf28SDavid du Colombier 	"	0",
194*de2caf28SDavid du Colombier 	"};",
195*de2caf28SDavid du Colombier 	"#endif",
196*de2caf28SDavid du Colombier 	"static const char *bfs_lname[] = { /* match values defined in pangen2.c */",
197*de2caf28SDavid du Colombier 	"	\"global lock\",	/* BFS_GLOB  */",
198*de2caf28SDavid du Colombier 	"	\"ordinal\",		/* BFS_ORD  */",
199*de2caf28SDavid du Colombier 	"	\"shared memory\",	/* BFS_MEM   */",
200*de2caf28SDavid du Colombier 	"	\"print to stdout\",	/* BFS_PRINT */",
201*de2caf28SDavid du Colombier 	"	\"hashtable\",		/* BFS_STATE */",
202*de2caf28SDavid du Colombier 	"	0",
203*de2caf28SDavid du Colombier 	"};",
204*de2caf28SDavid du Colombier 	"",
205*de2caf28SDavid du Colombier 	"static ulong bfs_count[DELETED+1];	/* indexed with bfs_types: EMPTY=0, STATE=1, DELETED=2 */",
206*de2caf28SDavid du Colombier 	"",
207*de2caf28SDavid du Colombier 	"static int bfs_keep_state;",
208*de2caf28SDavid du Colombier 	"",
209*de2caf28SDavid du Colombier 	"int Cores = 1;",
210*de2caf28SDavid du Colombier 	"int who_am_i = 0;	/* root */",
211*de2caf28SDavid du Colombier 	"",
212*de2caf28SDavid du Colombier 	"#ifdef L_BOUND",
213*de2caf28SDavid du Colombier 	"	int L_bound = L_BOUND;",
214*de2caf28SDavid du Colombier 	"#endif",
215*de2caf28SDavid du Colombier 	"",
216*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
217*de2caf28SDavid du Colombier 	"void",
218*de2caf28SDavid du Colombier 	"bfs_dump_now(char *s)",
219*de2caf28SDavid du Colombier 	"{	int i; char *p = (char *) &now;",
220*de2caf28SDavid du Colombier 	"",
221*de2caf28SDavid du Colombier 	"	e_critical(BFS_PRINT);",
222*de2caf28SDavid du Colombier 	"	printf(\"%%s\\t\", s);",
223*de2caf28SDavid du Colombier 	"	printf(\"%%3lu: \", vsize);",
224*de2caf28SDavid du Colombier 	"	for (i = 0; i < vsize; i++)",
225*de2caf28SDavid du Colombier 	"	{	printf(\"%%3d \", *p++);",
226*de2caf28SDavid du Colombier 	"	}",
227*de2caf28SDavid du Colombier 	"	printf(\"	%%s\\noffsets:\\t\", s);",
228*de2caf28SDavid du Colombier 	"	for (i = 0; i < now._nr_pr; i++)",
229*de2caf28SDavid du Colombier 	"	{	printf(\"%%3d \", proc_offset[i]);",
230*de2caf28SDavid du Colombier 	"	}",
231*de2caf28SDavid du Colombier 	"	printf(\"\\n\");",
232*de2caf28SDavid du Colombier 	"	x_critical(BFS_PRINT);",
233*de2caf28SDavid du Colombier 	"}",
234*de2caf28SDavid du Colombier 	"",
235*de2caf28SDavid du Colombier 	"void",
236*de2caf28SDavid du Colombier 	"view_state(char *s)	/* debugging */",
237*de2caf28SDavid du Colombier 	"{	int i;",
238*de2caf28SDavid du Colombier 	"	char *p;",
239*de2caf28SDavid du Colombier 	"	e_critical(BFS_PRINT);",
240*de2caf28SDavid du Colombier 	"	printf(\"cpu%%02d %%s: \", who_am_i, s);",
241*de2caf28SDavid du Colombier 	"	p = (char *)&now;",
242*de2caf28SDavid du Colombier 	"	for (i = 0; i < vsize; i++)",
243*de2caf28SDavid du Colombier 	"		printf(\"%%3d, \", *p++);",
244*de2caf28SDavid du Colombier 	"	printf(\"\\n\"); fflush(stdout);",
245*de2caf28SDavid du Colombier 	"	x_critical(BFS_PRINT);",
246*de2caf28SDavid du Colombier 	"}",
247*de2caf28SDavid du Colombier 	"#endif",
248*de2caf28SDavid du Colombier 	"",
249*de2caf28SDavid du Colombier 	"void",
250*de2caf28SDavid du Colombier 	"bfs_main(int ncores, int cycles)",
251*de2caf28SDavid du Colombier 	"{",
252*de2caf28SDavid du Colombier 	"	if (cycles)",
253*de2caf28SDavid du Colombier 	"	{	fprintf(stderr, \"pan: cycle detection is not supported in this mode\\n\");",
254*de2caf28SDavid du Colombier 	"		exit(1);",
255*de2caf28SDavid du Colombier 	"	}",
256*de2caf28SDavid du Colombier 	"",
257*de2caf28SDavid du Colombier 	"	if (ncores == 0)	/* i.e., find out */",
258*de2caf28SDavid du Colombier 	"	{	FILE *fd;",
259*de2caf28SDavid du Colombier 	"		char buf[512];",
260*de2caf28SDavid du Colombier 	"		if ((fd = fopen(\"/proc/cpuinfo\", \"r\")) == NULL)",
261*de2caf28SDavid du Colombier 	"		{	/* cannot tell */",
262*de2caf28SDavid du Colombier 	"			ncores = Cores; /* use the default */",
263*de2caf28SDavid du Colombier 	"		} else",
264*de2caf28SDavid du Colombier 	"		{	while (fgets(buf, sizeof(buf), fd))",
265*de2caf28SDavid du Colombier 	"			{	if (strncmp(buf, \"processor\", strlen(\"processor\")) == 0)",
266*de2caf28SDavid du Colombier 	"				{	ncores++;",
267*de2caf28SDavid du Colombier 	"			}	}",
268*de2caf28SDavid du Colombier 	"			fclose(fd);",
269*de2caf28SDavid du Colombier 	"			ncores--;",
270*de2caf28SDavid du Colombier 	"			if (verbose)",
271*de2caf28SDavid du Colombier 	"			{	printf(\"pan: %%d available cores\\n\", ncores+1);",
272*de2caf28SDavid du Colombier 	"	}	}	}",
273*de2caf28SDavid du Colombier 	"	if (ncores >= BFS_MAXPROCS)",
274*de2caf28SDavid du Colombier 	"	{	Cores = BFS_MAXPROCS-1; /* why -1? */",
275*de2caf28SDavid du Colombier 	"	} else if (ncores <  1)",
276*de2caf28SDavid du Colombier 	"	{	Cores = 1;",
277*de2caf28SDavid du Colombier 	"	} else",
278*de2caf28SDavid du Colombier 	"	{	Cores = ncores;",
279*de2caf28SDavid du Colombier 	"	}",
280*de2caf28SDavid du Colombier 	"	printf(\"pan: using %%d core%%s\\n\", Cores, (Cores>1)?\"s\":\"\");",
281*de2caf28SDavid du Colombier 	"	fflush(stdout);",
282*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
283*de2caf28SDavid du Colombier 	"	bfs_disk_start();",	/* create .spin */
284*de2caf28SDavid du Colombier 	"#endif",
285*de2caf28SDavid du Colombier 	"	bfs_setup();	/* shared memory segments and fork */",
286*de2caf28SDavid du Colombier 	"	bfs_run();",
287*de2caf28SDavid du Colombier 	"	if (who_am_i == 0)",
288*de2caf28SDavid du Colombier 	"	{	stop_timer(0);",
289*de2caf28SDavid du Colombier 	"	}",
290*de2caf28SDavid du Colombier 	"	bfs_statistics();",
291*de2caf28SDavid du Colombier 	"	bfs_mark_done(1);",
292*de2caf28SDavid du Colombier 	"	if (who_am_i == 0)",
293*de2caf28SDavid du Colombier 	"	{	report_time();",
294*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
295*de2caf28SDavid du Colombier 	"		bfs_disk_stop();",
296*de2caf28SDavid du Colombier 	"#endif",
297*de2caf28SDavid du Colombier 	"	}",
298*de2caf28SDavid du Colombier 	"#ifdef C_EXIT",
299*de2caf28SDavid du Colombier 	"	C_EXIT; /* trust that it defines a fct */",
300*de2caf28SDavid du Colombier 	"#endif",
301*de2caf28SDavid du Colombier 	"	bfs_drop_shared_memory();",
302*de2caf28SDavid du Colombier 	"	exit(0);",
303*de2caf28SDavid du Colombier 	"}",
304*de2caf28SDavid du Colombier 	"",
305*de2caf28SDavid du Colombier 	"void",
306*de2caf28SDavid du Colombier 	"bfs_setup_mem(void)",
307*de2caf28SDavid du Colombier 	"{	size_t n;",
308*de2caf28SDavid du Colombier 	"	key_t key;",
309*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
310*de2caf28SDavid du Colombier 	"	bfs_null.type = EMPTY;",
311*de2caf28SDavid du Colombier 	"#endif",
312*de2caf28SDavid du Colombier 	"	ntrpt = (Trail *) emalloc(sizeof(Trail));", /* just once */
313*de2caf28SDavid du Colombier 	"",
314*de2caf28SDavid du Colombier 	"	if ((key = ftok(\".\", (int) 'L')) == -1)",
315*de2caf28SDavid du Colombier 	"	{	perror(\"ftok shared memory\");",
316*de2caf28SDavid du Colombier 	"		exit(1);",
317*de2caf28SDavid du Colombier 	"	}",
318*de2caf28SDavid du Colombier 	"	n = bfs_find_largest(key);",
319*de2caf28SDavid du Colombier 	"	bfs_total_shared = (ulong) n;",
320*de2caf28SDavid du Colombier 	"",
321*de2caf28SDavid du Colombier 	"	shared_memory            = (BFS_shared *) bfs_get_shared_mem(key, n);	/* root */",
322*de2caf28SDavid du Colombier 	"	shared_memory->allocator = (uchar *) shared_memory + sizeof(BFS_shared);",
323*de2caf28SDavid du Colombier 	"	shared_memory->mem_left  = (ulong) (n - sizeof(BFS_shared));",
324*de2caf28SDavid du Colombier 	"}",
325*de2caf28SDavid du Colombier 	"",
326*de2caf28SDavid du Colombier 	"ulong bfs_LowLim;",
327*de2caf28SDavid du Colombier 	"#ifndef BFS_RESERVE",
328*de2caf28SDavid du Colombier 	"	#define BFS_RESERVE 5",
329*de2caf28SDavid du Colombier 	/* keep memory on global heap in reserve for first few cores */
330*de2caf28SDavid du Colombier 	/* that run out of their local allocation of shared mem */
331*de2caf28SDavid du Colombier 	/* 1~50 percent, 2~30 percent, 5~20 percent, >Cores=none */
332*de2caf28SDavid du Colombier 	"#else",
333*de2caf28SDavid du Colombier 	"	#if BFS_RESERVE<1",
334*de2caf28SDavid du Colombier 	"	#error BFS_RESERVE must be at least 1",
335*de2caf28SDavid du Colombier 	"	#endif",
336*de2caf28SDavid du Colombier 	"#endif",
337*de2caf28SDavid du Colombier 	"",
338*de2caf28SDavid du Colombier 	"void",
339*de2caf28SDavid du Colombier 	"bfs_setup(void)	/* executed by root */",
340*de2caf28SDavid du Colombier 	"{	int i, j;",
341*de2caf28SDavid du Colombier 	"	ulong n;	/* share of shared memory allocated to each core */",
342*de2caf28SDavid du Colombier 	"",
343*de2caf28SDavid du Colombier 	"	n = shared_memory->mem_left / (Cores + Cores/(BFS_RESERVE)); /* keep some reserve */",
344*de2caf28SDavid du Colombier 	"",
345*de2caf28SDavid du Colombier 	"	if ((n%%sizeof(void *)) != 0)",
346*de2caf28SDavid du Colombier 	"	{       n -= (n%%sizeof(void *)); /* align, without exceeding total */",
347*de2caf28SDavid du Colombier 	"	}",
348*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores-1; i++)",
349*de2caf28SDavid du Colombier 	"	{	j = fork();",
350*de2caf28SDavid du Colombier 	"		if (j == -1)",
351*de2caf28SDavid du Colombier 	"		{	bfs_printf(\"fork failed\\n\");",
352*de2caf28SDavid du Colombier 	"			exit(1);",
353*de2caf28SDavid du Colombier 	"		}",
354*de2caf28SDavid du Colombier 	"		if (j == 0)",
355*de2caf28SDavid du Colombier 	"		{	who_am_i = i+1;	/* 1..Cores-1 */",
356*de2caf28SDavid du Colombier 	"			break;",
357*de2caf28SDavid du Colombier 	"	}	}",
358*de2caf28SDavid du Colombier 	"",
359*de2caf28SDavid du Colombier 	"	e_critical(BFS_MEM);",
360*de2caf28SDavid du Colombier 	"	 bfs_heap = (uchar *) shared_memory->allocator;",
361*de2caf28SDavid du Colombier 	"	 shared_memory->allocator += n;",
362*de2caf28SDavid du Colombier 	"	 shared_memory->mem_left  -= n;",
363*de2caf28SDavid du Colombier 	"	x_critical(BFS_MEM);",
364*de2caf28SDavid du Colombier 	"",
365*de2caf28SDavid du Colombier 	"	bfs_left = n;",
366*de2caf28SDavid du Colombier 	"	bfs_runs = 1;",
367*de2caf28SDavid du Colombier 	"	bfs_LowLim = n / (2 * (ulong) Cores);", /* 50% */
368*de2caf28SDavid du Colombier 	"}",
369*de2caf28SDavid du Colombier 	"",
370*de2caf28SDavid du Colombier 	"void",
371*de2caf28SDavid du Colombier 	"bfs_run(void)",
372*de2caf28SDavid du Colombier 	"{	BFS_Slot *v;",
373*de2caf28SDavid du Colombier 	"",
374*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
375*de2caf28SDavid du Colombier 	"	bfs_disk_out();",	/* create outqs */
376*de2caf28SDavid du Colombier 	"#endif",
377*de2caf28SDavid du Colombier 	"	if (who_am_i == 0)",
378*de2caf28SDavid du Colombier 	"	{	bfs_initial_state();",
379*de2caf28SDavid du Colombier 	"	}",
380*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
381*de2caf28SDavid du Colombier 	"	#ifdef BFS_STAGGER",
382*de2caf28SDavid du Colombier 	"	bfs_stagger_flush();",
383*de2caf28SDavid du Colombier 	"	#endif",
384*de2caf28SDavid du Colombier 	"	bfs_disk_oclose();",	/* sync and close outqs */
385*de2caf28SDavid du Colombier 	"#endif",
386*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
387*de2caf28SDavid du Colombier 	"	static int i_count;",
388*de2caf28SDavid du Colombier 	"#endif",
389*de2caf28SDavid du Colombier 	"",
390*de2caf28SDavid du Colombier 	"	srand(s_rand+HASH_NR);",
391*de2caf28SDavid du Colombier 	"	bfs_qscan = 0;",
392*de2caf28SDavid du Colombier 	"	bfs_toggle = 1 - bfs_toggle; /* after initial state */",
393*de2caf28SDavid du Colombier 	"	e_critical(BFS_GLOB);",
394*de2caf28SDavid du Colombier 	"	 shared_memory->started++;",
395*de2caf28SDavid du Colombier 	"	x_critical(BFS_GLOB);",
396*de2caf28SDavid du Colombier 	"",
397*de2caf28SDavid du Colombier 	"	while (shared_memory->started != Cores)	/* wait for all cores to connect */",
398*de2caf28SDavid du Colombier 	"	{	usleep(1);",
399*de2caf28SDavid du Colombier 	"	}",
400*de2caf28SDavid du Colombier 	"",
401*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
402*de2caf28SDavid du Colombier 	"	bfs_disk_out();",
403*de2caf28SDavid du Colombier 	"	bfs_disk_inp();",
404*de2caf28SDavid du Colombier 	"#endif",
405*de2caf28SDavid du Colombier 	"",
406*de2caf28SDavid du Colombier 	"	start_timer();",
407*de2caf28SDavid du Colombier 	"	while (shared_memory->quit == 0)",
408*de2caf28SDavid du Colombier 	"	{	v = bfs_next(); /* get next message from current generation */",
409*de2caf28SDavid du Colombier 	"		if (v->s_data) /* v->type == STATE || v->type == DELETED */",
410*de2caf28SDavid du Colombier 	"		{	bfs_count[STATE]++;",
411*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
412*de2caf28SDavid du Colombier 	"			bfs_printf(\"GOT STATE (depth %%d, nr %%u)\\n\",",
413*de2caf28SDavid du Colombier 	"				v->s_data->t_info->o_tt, v->s_data->nr);",
414*de2caf28SDavid du Colombier 	"#endif",
415*de2caf28SDavid du Colombier 	"			/* last resort: start dropping states when out of memory */",
416*de2caf28SDavid du Colombier 	"			if (bfs_left > 1024 || shared_memory->mem_left > 1024)",
417*de2caf28SDavid du Colombier 	"			{	bfs_explore_state(v);",
418*de2caf28SDavid du Colombier 	"			} else",
419*de2caf28SDavid du Colombier 	"			{	static int warned_loss = 0;",
420*de2caf28SDavid du Colombier 	"				if (warned_loss == 0 && who_am_i == 0)",
421*de2caf28SDavid du Colombier 	"				{	warned_loss++;",
422*de2caf28SDavid du Colombier 	"					bfs_printf(\"out of shared memory - losing states\\n\");",
423*de2caf28SDavid du Colombier 	"				}",
424*de2caf28SDavid du Colombier 	"				bfs_punt++;",
425*de2caf28SDavid du Colombier 	"			}",
426*de2caf28SDavid du Colombier 	"#if !defined(BFS_FIFO) && !defined(BFS_NORECYCLE)",
427*de2caf28SDavid du Colombier 	"			bfs_recycle(v);",
428*de2caf28SDavid du Colombier 	"#endif",
429*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
430*de2caf28SDavid du Colombier 	"			i_count = 0;",
431*de2caf28SDavid du Colombier 	"#endif",
432*de2caf28SDavid du Colombier 	"		} else",
433*de2caf28SDavid du Colombier 	"		{	bfs_count[EMPTY]++;",
434*de2caf28SDavid du Colombier 	"#if defined(BFS_FIFO) && defined(BFS_CHECK)",
435*de2caf28SDavid du Colombier 	"			assert(v->type == EMPTY);",
436*de2caf28SDavid du Colombier 	"#endif",
437*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
438*de2caf28SDavid du Colombier 	"			if (who_am_i == 0)",
439*de2caf28SDavid du Colombier 	"			{	if (bfs_idle_and_empty())",
440*de2caf28SDavid du Colombier 	"				{	if (i_count++ > 10)",
441*de2caf28SDavid du Colombier 	"					{	shared_memory->quit = 1;",
442*de2caf28SDavid du Colombier 	"					}",
443*de2caf28SDavid du Colombier 	"					else usleep(1);",
444*de2caf28SDavid du Colombier 	"				}",
445*de2caf28SDavid du Colombier 	"			} else if (!bfs_all_running())",
446*de2caf28SDavid du Colombier 	"			{	bfs_shutdown(\"early termination\");",
447*de2caf28SDavid du Colombier 	"			}",
448*de2caf28SDavid du Colombier 	"#else",
449*de2caf28SDavid du Colombier 	"			if (who_am_i == 0)",
450*de2caf28SDavid du Colombier 	"			{	if (bfs_all_idle())		/* wait for it */",
451*de2caf28SDavid du Colombier 	"				{	if (!bfs_all_empty())	/* more states to process */",
452*de2caf28SDavid du Colombier 	"					{	bfs_set_toggle();",
453*de2caf28SDavid du Colombier 	"						goto do_toggle;",
454*de2caf28SDavid du Colombier 	"					} else			/* done */",
455*de2caf28SDavid du Colombier 	"					{	shared_memory->quit = 1; /* step 4 */",
456*de2caf28SDavid du Colombier 	"					}",
457*de2caf28SDavid du Colombier 	"				} else",
458*de2caf28SDavid du Colombier 	"				{	bfs_sleep_cnt++;",
459*de2caf28SDavid du Colombier 	"				}",
460*de2caf28SDavid du Colombier 	"			} else",
461*de2caf28SDavid du Colombier 	"			{	/* wait for quit or idle bit to be reset by root */",
462*de2caf28SDavid du Colombier 	"				while (shared_memory->bfs_idle[who_am_i] == 1",
463*de2caf28SDavid du Colombier 	"				&&     shared_memory->quit == 0)",
464*de2caf28SDavid du Colombier 	"				{	if (bfs_all_running())",
465*de2caf28SDavid du Colombier 	"					{	bfs_sleep_cnt++;",
466*de2caf28SDavid du Colombier 	"						usleep(10);	/* new 6.2.3 */",
467*de2caf28SDavid du Colombier 	"					} else",
468*de2caf28SDavid du Colombier 	"					{	bfs_shutdown(\"early termination\");",
469*de2caf28SDavid du Colombier 	"						/* no return */",
470*de2caf28SDavid du Colombier 	"				}	}",
471*de2caf28SDavid du Colombier 	"do_toggle:			bfs_qscan = 0;",
472*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
473*de2caf28SDavid du Colombier 	"				bfs_disk_iclose();",
474*de2caf28SDavid du Colombier 	"				bfs_disk_oclose();",
475*de2caf28SDavid du Colombier 	"#endif",
476*de2caf28SDavid du Colombier 	"				bfs_toggle = 1 - bfs_toggle;",
477*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
478*de2caf28SDavid du Colombier 	"				bfs_disk_out();",
479*de2caf28SDavid du Colombier 	"				bfs_disk_inp();",
480*de2caf28SDavid du Colombier 	"#endif",
481*de2caf28SDavid du Colombier 	"	#ifdef BFS_CHECK",
482*de2caf28SDavid du Colombier 	"				bfs_printf(\"toggle: recv from %%d, send to %%d\\n\",",
483*de2caf28SDavid du Colombier 	"					bfs_toggle, 1 - bfs_toggle);",
484*de2caf28SDavid du Colombier 	"	#endif",
485*de2caf28SDavid du Colombier 	"			}",
486*de2caf28SDavid du Colombier 	"#endif",
487*de2caf28SDavid du Colombier 	"	}	}",
488*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
489*de2caf28SDavid du Colombier 	"	bfs_printf(\"done, sent %%5ld recvd %%5ld punt %%5lu sleep: %%ld\\n\",",
490*de2caf28SDavid du Colombier 	"		bfs_sent, bfs_rcvd, bfs_punt, bfs_sleep_cnt);",
491*de2caf28SDavid du Colombier 	"#endif",
492*de2caf28SDavid du Colombier 	"}",
493*de2caf28SDavid du Colombier 	"",
494*de2caf28SDavid du Colombier 	"void",
495*de2caf28SDavid du Colombier 	"bfs_report_mem(void)	/* called from within wrapup() */",
496*de2caf28SDavid du Colombier 	"{",
497*de2caf28SDavid du Colombier 	"	printf(\"%%9.3f	total shared memory usage\\n\\n\",",
498*de2caf28SDavid du Colombier 	"		((double) bfs_total_shared - (double) bfs_left)/(1024.*1024.));",
499*de2caf28SDavid du Colombier 	"}",
500*de2caf28SDavid du Colombier 	"",
501*de2caf28SDavid du Colombier 	"void",
502*de2caf28SDavid du Colombier 	"bfs_statistics(void)",
503*de2caf28SDavid du Colombier 	"{",
504*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
505*de2caf28SDavid du Colombier 	"	enum bfs_types i;",
506*de2caf28SDavid du Colombier 	"	#endif",
507*de2caf28SDavid du Colombier 	"	if (verbose)",
508*de2caf28SDavid du Colombier 	"		bfs_printf(\"states sent %%7ld recvd %%7ld stored %%8g sleeps: %%4ld, %%4ld, %%ld\\n\",",
509*de2caf28SDavid du Colombier 	"			bfs_sent, bfs_rcvd, nstates, bfs_wcount, bfs_gcount, bfs_sleep_cnt);",
510*de2caf28SDavid du Colombier 	"	if (0) bfs_printf(\"states punted %%7lu\\n\", bfs_punt);",
511*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
512*de2caf28SDavid du Colombier 	"	for (i = EMPTY; i <= DELETED; i++)",
513*de2caf28SDavid du Colombier 	"	{	if (bfs_count[i] > 0)",
514*de2caf28SDavid du Colombier 	"		{	bfs_printf(\"%%6s	%%8lu\\n\",",
515*de2caf28SDavid du Colombier 	"				bfs_sname[i], bfs_count[i]);",
516*de2caf28SDavid du Colombier 	"	}	}",
517*de2caf28SDavid du Colombier 	"	#endif",
518*de2caf28SDavid du Colombier 	"	bfs_update();",
519*de2caf28SDavid du Colombier 	"",
520*de2caf28SDavid du Colombier 	"	if (who_am_i == 0 && shared_memory)",
521*de2caf28SDavid du Colombier 	"	{	int i; ulong count = 0L;",
522*de2caf28SDavid du Colombier 	"		done = 1;",
523*de2caf28SDavid du Colombier 	"",
524*de2caf28SDavid du Colombier 	"		e_critical(BFS_PRINT);",
525*de2caf28SDavid du Colombier 	"		  wrapup();",
526*de2caf28SDavid du Colombier 	"		  if (verbose)",
527*de2caf28SDavid du Colombier 	"		  {	  printf(\"\\nlock-wait counts:\\n\");",
528*de2caf28SDavid du Colombier 	"	 	  	for (i = 0; i < BFS_STATE; i++)",
529*de2caf28SDavid du Colombier 	"	 			printf(\"%%16s  %%9lu\\n\",",
530*de2caf28SDavid du Colombier 	"					bfs_lname[i], shared_memory->wait_count[i]);",
531*de2caf28SDavid du Colombier 	"#ifndef BITSTATE",
532*de2caf28SDavid du Colombier 	"		  	for (i = BFS_STATE; i < BFS_MAXLOCKS; i++)",
533*de2caf28SDavid du Colombier 	"		  	{	if (0)",
534*de2caf28SDavid du Colombier 	"				printf(\"	[%%6d]  %%9lu\\n\",",
535*de2caf28SDavid du Colombier 	"					i, shared_memory->wait_count[i]);",
536*de2caf28SDavid du Colombier 	"				count += shared_memory->wait_count[i];",
537*de2caf28SDavid du Colombier 	"		  	}",
538*de2caf28SDavid du Colombier 	"	 	  	printf(\"%%16s  %%9lu (avg per region)\\n\",",
539*de2caf28SDavid du Colombier 	"				bfs_lname[BFS_STATE], count/(BFS_MAXLOCKS - BFS_STATE));",
540*de2caf28SDavid du Colombier 	"#endif",
541*de2caf28SDavid du Colombier 	"		  }",
542*de2caf28SDavid du Colombier 	"		  fflush(stdout);",
543*de2caf28SDavid du Colombier 	"		x_critical(BFS_PRINT);",
544*de2caf28SDavid du Colombier 	"	}",
545*de2caf28SDavid du Colombier 	"}",
546*de2caf28SDavid du Colombier 	"",
547*de2caf28SDavid du Colombier 	"void",
548*de2caf28SDavid du Colombier 	"bfs_snapshot(void)",
549*de2caf28SDavid du Colombier 	"{	clock_t stop_time;",
550*de2caf28SDavid du Colombier 	"	double delta_time;",
551*de2caf28SDavid du Colombier 	"	struct tms stop_tm;",
552*de2caf28SDavid du Colombier 	"	volatile BFS_data *s;",
553*de2caf28SDavid du Colombier 	"",
554*de2caf28SDavid du Colombier 	"	e_critical(BFS_PRINT);",
555*de2caf28SDavid du Colombier 	"	 printf(\"cpu%%02d Depth= %%7lu States= %%8.3g Transitions= %%8.3g \",",
556*de2caf28SDavid du Colombier 	"		who_am_i, mreached, nstates, nstates+truncs);",
557*de2caf28SDavid du Colombier 	"	 printf(\"Memory= %%9.3f\\t\", memcnt/1048576.);",
558*de2caf28SDavid du Colombier 	"	 printf(\"SharedMLeft= %%4lu \", bfs_left/1048576);",
559*de2caf28SDavid du Colombier 	"	 stop_time  = times(&stop_tm);",
560*de2caf28SDavid du Colombier 	"	 delta_time = ((double) (stop_time - start_time))/((double) sysconf(_SC_CLK_TCK));",
561*de2caf28SDavid du Colombier 	"	 if (delta_time > 0.01)",
562*de2caf28SDavid du Colombier 	"	 {	printf(\"t= %%6.3g R= %%6.0g\\n\", delta_time, nstates/delta_time);",
563*de2caf28SDavid du Colombier 	"	 } else",
564*de2caf28SDavid du Colombier 	"	 {	printf(\"t= %%6.3g R= %%6.0g\\n\", 0., 0.);",
565*de2caf28SDavid du Colombier 	"	 }",
566*de2caf28SDavid du Colombier 	"	 fflush(stdout);",
567*de2caf28SDavid du Colombier 	"	x_critical(BFS_PRINT);",
568*de2caf28SDavid du Colombier 	"",
569*de2caf28SDavid du Colombier 	"	s = &shared_memory->bfs_data[who_am_i];",
570*de2caf28SDavid du Colombier 	"	s->mreached = (ulong) mreached;",
571*de2caf28SDavid du Colombier 	"	s->vsize    = (ulong) vsize;",
572*de2caf28SDavid du Colombier 	"	s->errors   = (int) errors;",
573*de2caf28SDavid du Colombier 	"	s->memcnt   = (double) memcnt;",
574*de2caf28SDavid du Colombier 	"	s->nstates  = (double) nstates;",
575*de2caf28SDavid du Colombier 	"	s->nlinks   = (double) nlinks;",
576*de2caf28SDavid du Colombier 	"	s->truncs   = (double) truncs;",
577*de2caf28SDavid du Colombier 	"	s->memory_left = (ulong) bfs_left;",
578*de2caf28SDavid du Colombier 	"	s->punted      = (ulong) bfs_punt;",
579*de2caf28SDavid du Colombier 	"	bfs_snapped++; /* for bfs_best */",
580*de2caf28SDavid du Colombier 	"}",
581*de2caf28SDavid du Colombier 	"",
582*de2caf28SDavid du Colombier 	"void",
583*de2caf28SDavid du Colombier 	"bfs_shutdown(const char *s)",
584*de2caf28SDavid du Colombier 	"{",
585*de2caf28SDavid du Colombier 	"	bfs_clear_locks(); /* in case we interrupted at a bad point */",
586*de2caf28SDavid du Colombier 	"	if (!strstr(s, \"early \") || verbose)",
587*de2caf28SDavid du Colombier 	"	{	bfs_printf(\"stop (%%s)\\n\", s);",
588*de2caf28SDavid du Colombier 	"	}",
589*de2caf28SDavid du Colombier 	"	bfs_update();",
590*de2caf28SDavid du Colombier 	"	if (who_am_i == 0)",
591*de2caf28SDavid du Colombier 	"	{	wrapup();",
592*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
593*de2caf28SDavid du Colombier 	"		bfs_disk_stop();",
594*de2caf28SDavid du Colombier 	"#endif",
595*de2caf28SDavid du Colombier 	"	}",
596*de2caf28SDavid du Colombier 	"	bfs_mark_done(2);",
597*de2caf28SDavid du Colombier 	"	pan_exit(2);",
598*de2caf28SDavid du Colombier 	"}",
599*de2caf28SDavid du Colombier 	"",
600*de2caf28SDavid du Colombier 	"SV_Hold *bfs_free_hold;",
601*de2caf28SDavid du Colombier 	"",
602*de2caf28SDavid du Colombier 	"SV_Hold *",
603*de2caf28SDavid du Colombier 	"bfs_get_hold(void)",
604*de2caf28SDavid du Colombier 	"{	SV_Hold *x;",
605*de2caf28SDavid du Colombier 	"	if (bfs_free_hold)",
606*de2caf28SDavid du Colombier 	"	{	x = bfs_free_hold;",
607*de2caf28SDavid du Colombier 	"		bfs_free_hold = bfs_free_hold->nxt;",
608*de2caf28SDavid du Colombier 	"	} else",
609*de2caf28SDavid du Colombier 	"	{	x = (SV_Hold *) sh_malloc((ulong) sizeof(SV_Hold));",
610*de2caf28SDavid du Colombier 	"	}",
611*de2caf28SDavid du Colombier 	"	return x;",
612*de2caf28SDavid du Colombier 	"}",
613*de2caf28SDavid du Colombier 	"",
614*de2caf28SDavid du Colombier 	"BFS_Trail *",
615*de2caf28SDavid du Colombier 	"bfs_unpack_state(BFS_Slot *n)		/* called in bfs_explore_state */",
616*de2caf28SDavid du Colombier 	"{	BFS_Trail *otrpt;",
617*de2caf28SDavid du Colombier 	"	BFS_State *bfs_t;",
618*de2caf28SDavid du Colombier 	"	int vecsz;",
619*de2caf28SDavid du Colombier 	"",
620*de2caf28SDavid du Colombier 	"	if (!n || !n->s_data || !n->s_data->t_info)",
621*de2caf28SDavid du Colombier 	"	{	bfs_Uerror(\"internal error\");",
622*de2caf28SDavid du Colombier 	"	}",
623*de2caf28SDavid du Colombier 	"	otrpt = (BFS_Trail *) ((BFS_State *) n->s_data)->t_info;",
624*de2caf28SDavid du Colombier 	"",
625*de2caf28SDavid du Colombier 	"	trpt->ostate = otrpt->ostate;",
626*de2caf28SDavid du Colombier 	"	trpt->st     = otrpt->st;",
627*de2caf28SDavid du Colombier 	"	trpt->o_tt   = otrpt->o_tt;",
628*de2caf28SDavid du Colombier 	"	trpt->pr     = otrpt->pr;",
629*de2caf28SDavid du Colombier 	"	trpt->tau    = otrpt->tau;",
630*de2caf28SDavid du Colombier 	"	trpt->o_pm   = otrpt->o_pm;",
631*de2caf28SDavid du Colombier 	"	if (trpt->ostate)",
632*de2caf28SDavid du Colombier 	"	trpt->o_t    = t_id_lkup[otrpt->t_id];",
633*de2caf28SDavid du Colombier 	"#if defined(C_States) && (HAS_TRACK==1)",
634*de2caf28SDavid du Colombier 	"	c_revert((uchar *) &(now.c_state[0]));",
635*de2caf28SDavid du Colombier 	"#endif",
636*de2caf28SDavid du Colombier 	"	if (trpt->o_pm & 4)			/* rv succeeded */",
637*de2caf28SDavid du Colombier 	"	{	return (BFS_Trail *) 0;		/* revisit not needed */",
638*de2caf28SDavid du Colombier 	"	}",
639*de2caf28SDavid du Colombier 	"#ifndef NOREDUCE",
640*de2caf28SDavid du Colombier 	"	bfs_nps = 0;",
641*de2caf28SDavid du Colombier 	"#endif",
642*de2caf28SDavid du Colombier 	"	if (trpt->o_pm & 8)			/* rv attempt failed */",
643*de2caf28SDavid du Colombier 	"	{	revrv++;",
644*de2caf28SDavid du Colombier 	"		if (trpt->tau&8)",
645*de2caf28SDavid du Colombier 	"		{	trpt->tau &= ~8;	/* break atomic */",
646*de2caf28SDavid du Colombier 	"#ifndef NOREDUCE",
647*de2caf28SDavid du Colombier 	"		} else if (trpt->tau&32)	/* void preselection */",
648*de2caf28SDavid du Colombier 	"		{	trpt->tau &= ~32;",
649*de2caf28SDavid du Colombier 	"			bfs_nps = 1;		/* no preselection in repeat */",
650*de2caf28SDavid du Colombier 	"#endif",
651*de2caf28SDavid du Colombier 	"	}	}",
652*de2caf28SDavid du Colombier 	"	trpt->o_pm &= ~(4|8);",
653*de2caf28SDavid du Colombier 	"	if (trpt->o_tt > mreached)",
654*de2caf28SDavid du Colombier 	"	{	static ulong nr = 0L, nc;",
655*de2caf28SDavid du Colombier 	"		mreached = trpt->o_tt;",
656*de2caf28SDavid du Colombier 	"		nc = (long) nstates/FREQ;",
657*de2caf28SDavid du Colombier 	"		if (nc > nr)",
658*de2caf28SDavid du Colombier 	"		{	nr = nc;",
659*de2caf28SDavid du Colombier 	"			bfs_snapshot();",
660*de2caf28SDavid du Colombier 	"	}	}",
661*de2caf28SDavid du Colombier 	"	depth = trpt->o_tt;",
662*de2caf28SDavid du Colombier 	"	if (depth >= maxdepth)",
663*de2caf28SDavid du Colombier 	"	{",
664*de2caf28SDavid du Colombier 	"#if SYNC",
665*de2caf28SDavid du Colombier 	"		if (boq != -1)",
666*de2caf28SDavid du Colombier 	"		{	BFS_Trail *x = (BFS_Trail *) trpt->ostate;",
667*de2caf28SDavid du Colombier 	"			if (x) x->o_pm |= 4; /* rv not failing */",
668*de2caf28SDavid du Colombier 	"		}",
669*de2caf28SDavid du Colombier 	"#endif",
670*de2caf28SDavid du Colombier 	"		truncs++;",
671*de2caf28SDavid du Colombier 	"		if (!warned)",
672*de2caf28SDavid du Colombier 	"		{	warned = 1;",
673*de2caf28SDavid du Colombier 	"			bfs_printf(\"error: max search depth too small\\n\");",
674*de2caf28SDavid du Colombier 	"		}",
675*de2caf28SDavid du Colombier 	"		if (bounded)",
676*de2caf28SDavid du Colombier 	"		{	bfs_uerror(\"depth limit reached\");",
677*de2caf28SDavid du Colombier 	"		}",
678*de2caf28SDavid du Colombier 	"		return (BFS_Trail *) 0;",
679*de2caf28SDavid du Colombier 	"	}",
680*de2caf28SDavid du Colombier 	"",
681*de2caf28SDavid du Colombier 	"	bfs_t = n->s_data;",
682*de2caf28SDavid du Colombier 	"#if NRUNS>0",
683*de2caf28SDavid du Colombier 	"	vsize = bfs_t->omask->sz;",
684*de2caf28SDavid du Colombier 	"#else",
685*de2caf28SDavid du Colombier 	"	vsize = ((State *) (bfs_t->osv))->_vsz;",
686*de2caf28SDavid du Colombier 	"#endif",
687*de2caf28SDavid du Colombier 	"#if SYNC",
688*de2caf28SDavid du Colombier 	"	boq   = bfs_t->boq;",
689*de2caf28SDavid du Colombier 	"#endif",
690*de2caf28SDavid du Colombier 	"",
691*de2caf28SDavid du Colombier 	"#if defined(Q_PROVISO) && !defined(BITSTATE) && defined(FULLSTACK)",
692*de2caf28SDavid du Colombier 	"	#ifdef USE_TDH",
693*de2caf28SDavid du Colombier 	"		if (((uchar *)(bfs_t->lstate)))		/* if BFS_INQ is set */",
694*de2caf28SDavid du Colombier 	"		{	*((uchar *) bfs_t->lstate) = 0;	/* turn it off */",
695*de2caf28SDavid du Colombier 	"		}",
696*de2caf28SDavid du Colombier 	"	#else",
697*de2caf28SDavid du Colombier 	"		if (bfs_t->lstate)			/* bfs_par */",
698*de2caf28SDavid du Colombier 	"		{	bfs_t->lstate->tagged = 0;	/* bfs_par state removed from q */",
699*de2caf28SDavid du Colombier 	"		}",
700*de2caf28SDavid du Colombier 	"	#endif",
701*de2caf28SDavid du Colombier 	"#endif",
702*de2caf28SDavid du Colombier 	"	memcpy((char *) &now, (uchar *) bfs_t->osv, vsize);",
703*de2caf28SDavid du Colombier 	"#if !defined(NOCOMP) && !defined(HC) && NRUNS>0",
704*de2caf28SDavid du Colombier 	"	Mask = (uchar *) bfs_t->omask->sv;	/* in shared memory */",
705*de2caf28SDavid du Colombier 	"#endif",
706*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
707*de2caf28SDavid du Colombier 	"	if (0) bfs_dump_now(\"got1\");",
708*de2caf28SDavid du Colombier 	"#endif",
709*de2caf28SDavid du Colombier 	"#ifdef TRIX",
710*de2caf28SDavid du Colombier 	"	re_populate();",
711*de2caf28SDavid du Colombier 	"#else",
712*de2caf28SDavid du Colombier 	"	#if NRUNS>0",
713*de2caf28SDavid du Colombier 	"		if (now._nr_pr > 0)",
714*de2caf28SDavid du Colombier 	"		{",
715*de2caf28SDavid du Colombier 	"		#if VECTORSZ>32000",
716*de2caf28SDavid du Colombier 	"			proc_offset = (int *) bfs_t->omask->po;",
717*de2caf28SDavid du Colombier 	"		#else",
718*de2caf28SDavid du Colombier 	"			proc_offset = (short *) bfs_t->omask->po;",
719*de2caf28SDavid du Colombier 	"		#endif",
720*de2caf28SDavid du Colombier 	"			proc_skip   = (uchar *) bfs_t->omask->ps;",
721*de2caf28SDavid du Colombier 	"		}",
722*de2caf28SDavid du Colombier 	"		if (now._nr_qs > 0)",
723*de2caf28SDavid du Colombier 	"		{",
724*de2caf28SDavid du Colombier 	"		#if VECTORSZ>32000",
725*de2caf28SDavid du Colombier 	"			q_offset = (int *) bfs_t->omask->qo;",
726*de2caf28SDavid du Colombier 	"		#else",
727*de2caf28SDavid du Colombier 	"			q_offset = (short *) bfs_t->omask->qo;",
728*de2caf28SDavid du Colombier 	"		#endif",
729*de2caf28SDavid du Colombier 	"			q_skip   = (uchar *) bfs_t->omask->qs;",
730*de2caf28SDavid du Colombier 	"		}",
731*de2caf28SDavid du Colombier 	"	#endif",
732*de2caf28SDavid du Colombier 	"#endif",
733*de2caf28SDavid du Colombier 	"	vecsz = ((State *) bfs_t->osv)->_vsz;",
734*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
735*de2caf28SDavid du Colombier 	"	assert(vecsz > 0 && vecsz < VECTORSZ);",
736*de2caf28SDavid du Colombier 	"#endif",
737*de2caf28SDavid du Colombier 	"	{ SV_Hold *x = bfs_get_hold();",
738*de2caf28SDavid du Colombier 	"		x->sv  = bfs_t->osv;",
739*de2caf28SDavid du Colombier 	"		x->nxt = bfs_svfree[vecsz];",
740*de2caf28SDavid du Colombier 	"		bfs_svfree[vecsz] = x;",
741*de2caf28SDavid du Colombier 	"		bfs_t->osv = (State *) 0;",
742*de2caf28SDavid du Colombier 	"	}",
743*de2caf28SDavid du Colombier 	"#if NRUNS>0",
744*de2caf28SDavid du Colombier 	"	bfs_keep(bfs_t->omask);",
745*de2caf28SDavid du Colombier 	"#endif",
746*de2caf28SDavid du Colombier 	"",
747*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
748*de2caf28SDavid du Colombier 	"	if (0) bfs_dump_now(\"got2\");",
749*de2caf28SDavid du Colombier 	"	if (0) view_state(\"after\");",
750*de2caf28SDavid du Colombier 	"#endif",
751*de2caf28SDavid du Colombier 	"	return (BFS_Trail *) bfs_t->t_info;",
752*de2caf28SDavid du Colombier 	"}",
753*de2caf28SDavid du Colombier 	"void",
754*de2caf28SDavid du Colombier 	"bfs_initial_state(void)",
755*de2caf28SDavid du Colombier 	"{",
756*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
757*de2caf28SDavid du Colombier 	"	assert(trpt != NULL);",
758*de2caf28SDavid du Colombier 	"#endif",
759*de2caf28SDavid du Colombier 	"	trpt->ostate = (H_el *) 0;",
760*de2caf28SDavid du Colombier 	"	trpt->o_tt   = -1;",
761*de2caf28SDavid du Colombier 	"	trpt->tau    = 0;",
762*de2caf28SDavid du Colombier 	"#ifdef VERI",
763*de2caf28SDavid du Colombier 	"	trpt->tau |= 4;	/* claim moves first */",
764*de2caf28SDavid du Colombier 	"#endif",
765*de2caf28SDavid du Colombier 	"	bfs_store_state(trpt, boq);	/* initial state : bfs_lib.c */",
766*de2caf28SDavid du Colombier 	"}",
767*de2caf28SDavid du Colombier 	"",
768*de2caf28SDavid du Colombier 	"#ifdef BITSTATE",
769*de2caf28SDavid du Colombier 	"		#define bfs_do_store(v, n) b_store(v, n)",
770*de2caf28SDavid du Colombier 	"#else",
771*de2caf28SDavid du Colombier 	"	#ifdef USE_TDH",
772*de2caf28SDavid du Colombier 	"		#define bfs_do_store(v, n) o_store(v, n)",
773*de2caf28SDavid du Colombier 	"	#else",
774*de2caf28SDavid du Colombier 	"		#define bfs_do_store(v, n) h_store(v, n)",
775*de2caf28SDavid du Colombier 	"	#endif",
776*de2caf28SDavid du Colombier 	"#endif",
777*de2caf28SDavid du Colombier 	"",
778*de2caf28SDavid du Colombier 	"#ifdef BFS_SEP_HASH",
779*de2caf28SDavid du Colombier 	"int",
780*de2caf28SDavid du Colombier 	"bfs_seen_before(void)",
781*de2caf28SDavid du Colombier 	"{	/* cannot set trpt->tau |= 64 to mark successors outside stack */",
782*de2caf28SDavid du Colombier 	"	/* since the check is done remotely and the trpt value is gone */",
783*de2caf28SDavid du Colombier 	" #ifdef VERI",
784*de2caf28SDavid du Colombier 	"	if (!trpt->ostate		/* initial state */",
785*de2caf28SDavid du Colombier 	"	|| ((trpt->tau&4)		/* starting claim moves(s) */",
786*de2caf28SDavid du Colombier 	"	&& !(((BFS_Trail *)trpt->ostate)->tau&4))) /* prev move: prog */",
787*de2caf28SDavid du Colombier 	"	{	return 0; /* claim move: mid-state not stored */",
788*de2caf28SDavid du Colombier 	"	} /* else */",
789*de2caf28SDavid du Colombier 	" #endif",
790*de2caf28SDavid du Colombier 	"	if (!bfs_do_store((char *)&now, vsize))	/* sep_hash */",
791*de2caf28SDavid du Colombier 	"	{	nstates++;		/* local count */",
792*de2caf28SDavid du Colombier 	"		return 0;		/* new state */",
793*de2caf28SDavid du Colombier 	"	}",
794*de2caf28SDavid du Colombier 	" #ifdef BFS_CHECK",
795*de2caf28SDavid du Colombier 	"	bfs_printf(\"seen before\\n\");",
796*de2caf28SDavid du Colombier 	" #endif",
797*de2caf28SDavid du Colombier 	"	truncs++;",
798*de2caf28SDavid du Colombier 	"	return 1;			/* old state */",
799*de2caf28SDavid du Colombier 	"}",
800*de2caf28SDavid du Colombier 	"#endif",
801*de2caf28SDavid du Colombier 	"",
802*de2caf28SDavid du Colombier 	"void",
803*de2caf28SDavid du Colombier 	"bfs_explore_state(BFS_Slot *v)		/* generate all successors of v */",
804*de2caf28SDavid du Colombier 	"{	BFS_Trail *otrpt;",
805*de2caf28SDavid du Colombier 	"	Trans *t;",
806*de2caf28SDavid du Colombier 	"#ifdef HAS_UNLESS",
807*de2caf28SDavid du Colombier 	"	int E_state;",
808*de2caf28SDavid du Colombier 	"#endif",
809*de2caf28SDavid du Colombier 	"	int tt;",
810*de2caf28SDavid du Colombier 	"	short II, To = BASE, From = (short) (now._nr_pr-1);",
811*de2caf28SDavid du Colombier 	"	short oboq = boq;",
812*de2caf28SDavid du Colombier 	"	uchar _n, _m, ot;",
813*de2caf28SDavid du Colombier 	"",
814*de2caf28SDavid du Colombier 	"	memset(ntrpt, 0, sizeof(Trail));",
815*de2caf28SDavid du Colombier 	"	otrpt = bfs_unpack_state(v); /* BFS_Trail */",
816*de2caf28SDavid du Colombier 	"",
817*de2caf28SDavid du Colombier 	"	if (!otrpt) { return; } /* e.g., depth limit reached */",
818*de2caf28SDavid du Colombier 	"#ifdef L_BOUND",
819*de2caf28SDavid du Colombier 	"	#if defined(VERBOSE)",
820*de2caf28SDavid du Colombier 	"	bfs_printf(\"Unpacked state with l_bound %%d -- sds %%p\\n\",",
821*de2caf28SDavid du Colombier 	"		now._l_bnd, now._l_sds);",
822*de2caf28SDavid du Colombier 	"	#endif",
823*de2caf28SDavid du Colombier 	"#endif",
824*de2caf28SDavid du Colombier 	"",
825*de2caf28SDavid du Colombier 	"#if defined(C_States) && (HAS_TRACK==1)",
826*de2caf28SDavid du Colombier 	"	c_revert((uchar *) &(now.c_state[0]));",
827*de2caf28SDavid du Colombier 	"#endif",
828*de2caf28SDavid du Colombier 	"",
829*de2caf28SDavid du Colombier 	"#ifdef BFS_SEP_HASH",
830*de2caf28SDavid du Colombier 	"	if (bfs_seen_before()) return;",
831*de2caf28SDavid du Colombier 	"#endif",
832*de2caf28SDavid du Colombier 	"",
833*de2caf28SDavid du Colombier 	"#ifdef VERI",	/* could move to just before store_state */
834*de2caf28SDavid du Colombier 	"	if (now._nr_pr == 0	/* claim terminated */",
835*de2caf28SDavid du Colombier 	"	||  stopstate[((Pclaim *)pptr(0))->_t][((Pclaim *)pptr(0))->_p])",
836*de2caf28SDavid du Colombier 	"	{	bfs_uerror(\"end state in claim reached\");",
837*de2caf28SDavid du Colombier 	"	}",
838*de2caf28SDavid du Colombier 	"#endif",
839*de2caf28SDavid du Colombier 	"	trpt->tau &= ~1;	/* timeout off */",
840*de2caf28SDavid du Colombier 	"#ifdef VERI",
841*de2caf28SDavid du Colombier 	"	if (trpt->tau&4)	/* claim move */",
842*de2caf28SDavid du Colombier 	"	{	trpt->tau |= (otrpt->tau)&1; /* inherit from prog move */",
843*de2caf28SDavid du Colombier 	"		From = To = 0;	/* claim */",
844*de2caf28SDavid du Colombier 	"		goto Repeat_two;",
845*de2caf28SDavid du Colombier 	"	}",
846*de2caf28SDavid du Colombier 	"#endif",
847*de2caf28SDavid du Colombier 	"#ifndef NOREDUCE",
848*de2caf28SDavid du Colombier 	"	if (boq == -1 && !(trpt->tau&8) && bfs_nps == 0)",
849*de2caf28SDavid du Colombier 	"	for (II = now._nr_pr-1; II >= BASE; II -= 1)",
850*de2caf28SDavid du Colombier 	"	{",
851*de2caf28SDavid du Colombier 	"Pickup:	_this = pptr(II);",
852*de2caf28SDavid du Colombier 	"		tt = (int) ((P0 *)_this)->_p;",
853*de2caf28SDavid du Colombier 	"		ot = (uchar) ((P0 *)_this)->_t;",
854*de2caf28SDavid du Colombier 	"		if (trans[ot][tt]->atom & 8)",
855*de2caf28SDavid du Colombier 	"		{	t = trans[ot][tt];",
856*de2caf28SDavid du Colombier 	"			if (t->qu[0] != 0)",
857*de2caf28SDavid du Colombier 	"			{	if (!q_cond(II, t))",
858*de2caf28SDavid du Colombier 	"					continue;",
859*de2caf28SDavid du Colombier 	"			}",
860*de2caf28SDavid du Colombier 	"			From = To = II;",
861*de2caf28SDavid du Colombier 	"			trpt->tau |= 32; /* preselect marker */",
862*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
863*de2caf28SDavid du Colombier 	"			bfs_printf(\"%%3ld: proc %%d PreSelected (tau=%%d)\\n\", ",
864*de2caf28SDavid du Colombier 	"				depth, II, trpt->tau);",
865*de2caf28SDavid du Colombier 	"	#endif",
866*de2caf28SDavid du Colombier 	"			goto Repeat_two;",
867*de2caf28SDavid du Colombier 	"	}	}",
868*de2caf28SDavid du Colombier 	"	trpt->tau &= ~32;",
869*de2caf28SDavid du Colombier 	"#endif",
870*de2caf28SDavid du Colombier 	"",
871*de2caf28SDavid du Colombier 	"Repeat_one:",
872*de2caf28SDavid du Colombier 	"	if (trpt->tau&8)",
873*de2caf28SDavid du Colombier 	"	{	From = To = (short ) trpt->pr;	/* atomic */",
874*de2caf28SDavid du Colombier 	"	} else",
875*de2caf28SDavid du Colombier 	"	{	From = now._nr_pr-1;",
876*de2caf28SDavid du Colombier 	"		To = BASE;",
877*de2caf28SDavid du Colombier 	"	}",
878*de2caf28SDavid du Colombier 	"#if defined(VERI) || !defined(NOREDUCE) || defined(ETIM)",
879*de2caf28SDavid du Colombier 	"Repeat_two: /* MainLoop */",
880*de2caf28SDavid du Colombier 	"#endif",
881*de2caf28SDavid du Colombier 	"	_n = _m = 0;",
882*de2caf28SDavid du Colombier 	"	for (II = From; II >= To; II -= 1)	/* all processes */",
883*de2caf28SDavid du Colombier 	"	{",
884*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
885*de2caf28SDavid du Colombier 	"		bfs_printf(\"proc %%d (%%d - %%d)\\n\", II, From, To);",
886*de2caf28SDavid du Colombier 	"#endif",
887*de2caf28SDavid du Colombier 	"#if SYNC	",
888*de2caf28SDavid du Colombier 	"		if (boq != -1 && trpt->pr == II)",
889*de2caf28SDavid du Colombier 	"		{	continue;	/* no rendezvous with same proc */",
890*de2caf28SDavid du Colombier 	"		}",
891*de2caf28SDavid du Colombier 	"#endif",
892*de2caf28SDavid du Colombier 	"		_this = pptr(II);",
893*de2caf28SDavid du Colombier 	"		tt = (int) ((P0 *)_this)->_p;",
894*de2caf28SDavid du Colombier 	"		ot = (uchar) ((P0 *)_this)->_t;",
895*de2caf28SDavid du Colombier 	"		ntrpt->pr = (uchar) II;",
896*de2caf28SDavid du Colombier 	"		ntrpt->st = tt;	",
897*de2caf28SDavid du Colombier 	"		trpt->o_pm &= ~1; /* no move yet */",
898*de2caf28SDavid du Colombier 	"#ifdef EVENT_TRACE",
899*de2caf28SDavid du Colombier 	"		trpt->o_event = now._event;",
900*de2caf28SDavid du Colombier 	"#endif",
901*de2caf28SDavid du Colombier 	"#ifdef HAS_PRIORITY",
902*de2caf28SDavid du Colombier 	"		if (!highest_priority(((P0 *)_this)->_pid, II, t))",
903*de2caf28SDavid du Colombier 	"		{	continue;",
904*de2caf28SDavid du Colombier 	"		}",
905*de2caf28SDavid du Colombier 	"#else",
906*de2caf28SDavid du Colombier 	"	#ifdef HAS_PROVIDED",
907*de2caf28SDavid du Colombier 	"		if (!provided(II, ot, tt, t))",
908*de2caf28SDavid du Colombier 	"		{	continue;",
909*de2caf28SDavid du Colombier 	"		}",
910*de2caf28SDavid du Colombier 	"	#endif",
911*de2caf28SDavid du Colombier 	"#endif",
912*de2caf28SDavid du Colombier 	"#ifdef HAS_UNLESS",
913*de2caf28SDavid du Colombier 	"		E_state = 0;",
914*de2caf28SDavid du Colombier 	"#endif",
915*de2caf28SDavid du Colombier 	"		for (t = trans[ot][tt]; t; t = t->nxt)	/* all process transitions */",
916*de2caf28SDavid du Colombier 	"		{",
917*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
918*de2caf28SDavid du Colombier 	"			assert(t_id_lkup[t->t_id] == t); /* for reverse lookup in bfs_unpack_state */",
919*de2caf28SDavid du Colombier 	"#endif",
920*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
921*de2caf28SDavid du Colombier 	"			if (0) bfs_printf(\"\\tproc %%d tr %%d\\n\", II, t->forw);",
922*de2caf28SDavid du Colombier 	"#endif",
923*de2caf28SDavid du Colombier 	"#ifdef HAS_UNLESS",
924*de2caf28SDavid du Colombier 	"			if (E_state > 0",
925*de2caf28SDavid du Colombier 	"			&&  E_state != t->e_trans)",
926*de2caf28SDavid du Colombier 	"				break;",
927*de2caf28SDavid du Colombier 	"#endif",
928*de2caf28SDavid du Colombier 	"			/* trpt->o_t = */ ntrpt->o_t = t;",
929*de2caf28SDavid du Colombier 	"			oboq = boq;",
930*de2caf28SDavid du Colombier 	"",
931*de2caf28SDavid du Colombier 	"			if (!(_m = do_transit(t, II)))",
932*de2caf28SDavid du Colombier 	"				continue;",
933*de2caf28SDavid du Colombier 	"",
934*de2caf28SDavid du Colombier 	"			trpt->o_pm |= 1;		/* we moved */",
935*de2caf28SDavid du Colombier 	"			(trpt+1)->o_m = _m;		/* for unsend */",
936*de2caf28SDavid du Colombier 	"#ifdef PEG",
937*de2caf28SDavid du Colombier 	"			peg[t->forw]++;",
938*de2caf28SDavid du Colombier 	"#endif",
939*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
940*de2caf28SDavid du Colombier 	"			e_critical(BFS_PRINT);",
941*de2caf28SDavid du Colombier 	"			printf(\"%%3ld: proc %%d exec %%d, \",",
942*de2caf28SDavid du Colombier 	"				depth, II, t->forw);",
943*de2caf28SDavid du Colombier 	"			printf(\"%%d to %%d, %%s %%s %%s\",",
944*de2caf28SDavid du Colombier 	"				tt, t->st, t->tp,",
945*de2caf28SDavid du Colombier 	"				(t->atom&2)?\"atomic\":\"\",",
946*de2caf28SDavid du Colombier 	"				(boq != -1)?\"rendez-vous\":\"\");",
947*de2caf28SDavid du Colombier 	"	#ifdef HAS_UNLESS",
948*de2caf28SDavid du Colombier 	"			if (t->e_trans)",
949*de2caf28SDavid du Colombier 	"				printf(\" (escapes to state %%d)\", t->st);",
950*de2caf28SDavid du Colombier 	"	#endif",
951*de2caf28SDavid du Colombier 	"			printf(\" %%saccepting [tau=%%d]\\n\",",
952*de2caf28SDavid du Colombier 	"				(trpt->o_pm&2)?\"\":\"non-\", trpt->tau);",
953*de2caf28SDavid du Colombier 	"			x_critical(BFS_PRINT);",
954*de2caf28SDavid du Colombier 	"#endif",
955*de2caf28SDavid du Colombier 	"#ifdef HAS_UNLESS",
956*de2caf28SDavid du Colombier 	"			E_state = t->e_trans;",
957*de2caf28SDavid du Colombier 	"	#if SYNC>0",
958*de2caf28SDavid du Colombier 	"			if (t->e_trans > 0 && boq != -1)",
959*de2caf28SDavid du Colombier 	"			{ fprintf(efd, \"error:	rendezvous stmnt in the escape clause\\n\");",
960*de2caf28SDavid du Colombier 	"			  fprintf(efd, \"	of unless stmnt not compatible with -DBFS\\n\");",
961*de2caf28SDavid du Colombier 	"			  pan_exit(1);",
962*de2caf28SDavid du Colombier 	"			}",
963*de2caf28SDavid du Colombier 	"	#endif",
964*de2caf28SDavid du Colombier 	"#endif",
965*de2caf28SDavid du Colombier 	"			if (t->st > 0)",
966*de2caf28SDavid du Colombier 	"			{	((P0 *)_this)->_p = t->st;",
967*de2caf28SDavid du Colombier 	"			}",
968*de2caf28SDavid du Colombier 	"			/* use the ostate ptr, with type *H_el, to temporarily store *BFS_Trail */",
969*de2caf28SDavid du Colombier 	"#ifdef BFS_NOTRAIL",
970*de2caf28SDavid du Colombier 	"			ntrpt->ostate = (H_el *) 0;	/* no error-traces in this mode */",
971*de2caf28SDavid du Colombier 	"#else",
972*de2caf28SDavid du Colombier 	"			ntrpt->ostate = (H_el *) otrpt;	/* parent stackframe */",
973*de2caf28SDavid du Colombier 	"#endif",
974*de2caf28SDavid du Colombier 	"		/*	ntrpt->st = tt;		* was already set above */",
975*de2caf28SDavid du Colombier 	"",
976*de2caf28SDavid du Colombier 	"			if (boq == -1 && (t->atom&2))	/* atomic */",
977*de2caf28SDavid du Colombier 	"			{	ntrpt->tau = 8;		/* record for next move */",
978*de2caf28SDavid du Colombier 	"			} else",
979*de2caf28SDavid du Colombier 	"			{	ntrpt->tau = 0;		/* no timeout or preselect etc */",
980*de2caf28SDavid du Colombier 	"			}",
981*de2caf28SDavid du Colombier 	"#ifdef VERI",
982*de2caf28SDavid du Colombier 	"			ntrpt->tau |= trpt->tau&4;	/* if claim, inherit */",
983*de2caf28SDavid du Colombier 	"			if (boq == -1 && !(ntrpt->tau&8))	/* unless rv or atomic */",
984*de2caf28SDavid du Colombier 	"			{	if (ntrpt->tau&4)	/* claim */",
985*de2caf28SDavid du Colombier 	"				{	ntrpt->tau &= ~4; /* switch to prog */",
986*de2caf28SDavid du Colombier 	"				} else",
987*de2caf28SDavid du Colombier 	"				{	ntrpt->tau |=  4; /* switch to claim */",
988*de2caf28SDavid du Colombier 	"			}	}",
989*de2caf28SDavid du Colombier 	"#endif",
990*de2caf28SDavid du Colombier 	"#ifdef L_BOUND",
991*de2caf28SDavid du Colombier 	"			{  uchar obnd = now._l_bnd;",
992*de2caf28SDavid du Colombier 	"			   uchar *os  = now._l_sds;",
993*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
994*de2caf28SDavid du Colombier 	"			   bfs_printf(\"saving bound %%d -- sds %%p\\n\", obnd, (void *) os);",
995*de2caf28SDavid du Colombier 	"	#endif",
996*de2caf28SDavid du Colombier 	"#endif",
997*de2caf28SDavid du Colombier 	"",
998*de2caf28SDavid du Colombier 	"			   bfs_store_state(ntrpt, oboq);",
999*de2caf28SDavid du Colombier 	"#ifdef EVENT_TRACE",
1000*de2caf28SDavid du Colombier 	"			   now._event = trpt->o_event;",
1001*de2caf28SDavid du Colombier 	"#endif",
1002*de2caf28SDavid du Colombier 	"			   /* undo move and generate other successor states */",
1003*de2caf28SDavid du Colombier 	"			   trpt++;	/* this is where ovals and ipt are set */",
1004*de2caf28SDavid du Colombier 	"			   do_reverse(t, II, _m);	/* restore now. */",
1005*de2caf28SDavid du Colombier 	"#ifdef L_BOUND",
1006*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
1007*de2caf28SDavid du Colombier 	"			   bfs_printf(\"restoring bound %%d -- sds %%p\\n\", obnd, (void *) os);",
1008*de2caf28SDavid du Colombier 	"	#endif",
1009*de2caf28SDavid du Colombier 	"			   now._l_bnd = obnd;",
1010*de2caf28SDavid du Colombier 	"			   now._l_sds = os;",
1011*de2caf28SDavid du Colombier 	"			}",
1012*de2caf28SDavid du Colombier 	"#endif",
1013*de2caf28SDavid du Colombier 	"			trpt--;",
1014*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1015*de2caf28SDavid du Colombier 	"			e_critical(BFS_PRINT);",
1016*de2caf28SDavid du Colombier 	"			printf(\"%%3ld: proc %%d \",  depth, II);",
1017*de2caf28SDavid du Colombier 	"			printf(\"reverses %%d, %%d to %%d,\", t->forw, tt, t->st);",
1018*de2caf28SDavid du Colombier 	"			printf(\" %%s [abit=%%d,adepth=%%d,\", t->tp, now._a_t, 0);",
1019*de2caf28SDavid du Colombier 	"			printf(\"tau=%%d,%%d]\\n\", trpt->tau, (trpt-1)->tau);",
1020*de2caf28SDavid du Colombier 	"			x_critical(BFS_PRINT);",
1021*de2caf28SDavid du Colombier 	"#endif",
1022*de2caf28SDavid du Colombier 	"			reached[ot][t->st] = 1;",
1023*de2caf28SDavid du Colombier 	"			reached[ot][tt]    = 1;",
1024*de2caf28SDavid du Colombier 	"",
1025*de2caf28SDavid du Colombier 	"			((P0 *)_this)->_p = tt;",
1026*de2caf28SDavid du Colombier 	"			_n |= _m;",
1027*de2caf28SDavid du Colombier 	"	}	}",
1028*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1029*de2caf28SDavid du Colombier 	"	bfs_printf(\"done _n = %%d\\n\", _n);",
1030*de2caf28SDavid du Colombier 	"#endif",
1031*de2caf28SDavid du Colombier 	"",
1032*de2caf28SDavid du Colombier 	"#ifndef NOREDUCE",
1033*de2caf28SDavid du Colombier 	"	/* preselected - no succ definitely outside stack */",
1034*de2caf28SDavid du Colombier 	"	if ((trpt->tau&32) && !(trpt->tau&64))",
1035*de2caf28SDavid du Colombier 	"	{	From = now._nr_pr-1; To = BASE;",
1036*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
1037*de2caf28SDavid du Colombier 	"		bfs_printf(\"%%3ld: proc %%d UnSelected (_n=%%d, tau=%%d)\\n\", ",
1038*de2caf28SDavid du Colombier 	"			depth, II+1, (int) _n, trpt->tau);",
1039*de2caf28SDavid du Colombier 	"	#endif",
1040*de2caf28SDavid du Colombier 	"		_n = 0; trpt->tau &= ~32;",
1041*de2caf28SDavid du Colombier 	"		if (II >= BASE)",
1042*de2caf28SDavid du Colombier 	"		{	goto Pickup;",
1043*de2caf28SDavid du Colombier 	"		}",
1044*de2caf28SDavid du Colombier 	"		goto Repeat_two;",
1045*de2caf28SDavid du Colombier 	"	}",
1046*de2caf28SDavid du Colombier 	"	trpt->tau &= ~(32|64);",
1047*de2caf28SDavid du Colombier 	"#endif",
1048*de2caf28SDavid du Colombier 	"	if (_n == 0",
1049*de2caf28SDavid du Colombier 	"#ifdef VERI",
1050*de2caf28SDavid du Colombier 	"	&& !(trpt->tau&4)",
1051*de2caf28SDavid du Colombier 	"#endif",
1052*de2caf28SDavid du Colombier 	"	)",
1053*de2caf28SDavid du Colombier 	"	{	/* no successor states generated */",
1054*de2caf28SDavid du Colombier 	"		if (boq != -1)				/* was rv move */",
1055*de2caf28SDavid du Colombier 	"		{	BFS_Trail *x = (BFS_Trail *) trpt->ostate; /* pre-rv state */",
1056*de2caf28SDavid du Colombier 	"			if (x && ((x->tau&8) || (x->tau&32))) /* break atomic or preselect */",
1057*de2caf28SDavid du Colombier 	"			{	x->o_pm |= 8;		/* mark failure */",
1058*de2caf28SDavid du Colombier 	"				_this = pptr(otrpt->pr);",
1059*de2caf28SDavid du Colombier 	"				((P0 *) _this)->_p = otrpt->st;	/* reset state */",
1060*de2caf28SDavid du Colombier 	"				unsend(boq);		/* retract rv offer */",
1061*de2caf28SDavid du Colombier 	"				boq = -1;",
1062*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1063*de2caf28SDavid du Colombier 	"				printf(\"repush state\\n\");",
1064*de2caf28SDavid du Colombier 	"#endif",
1065*de2caf28SDavid du Colombier 	"				bfs_push_state(NULL, x, x->o_tt); /* repush rv fail */",
1066*de2caf28SDavid du Colombier 	"			} /* else the rv need not be retried */",
1067*de2caf28SDavid du Colombier 	"		} else if (now._nr_pr > BASE)		/* possible deadlock */",
1068*de2caf28SDavid du Colombier 	"		{	if ((trpt->tau&8))		/* atomic step blocked */",
1069*de2caf28SDavid du Colombier 	"			{	trpt->tau &= ~(1|8);	/* 1=timeout, 8=atomic */",
1070*de2caf28SDavid du Colombier 	"				goto Repeat_one;",
1071*de2caf28SDavid du Colombier 	"			}",
1072*de2caf28SDavid du Colombier 	"#ifdef ETIM",
1073*de2caf28SDavid du Colombier 	"			/* if timeouts were used in the model */",
1074*de2caf28SDavid du Colombier 	"			if (!(trpt->tau&1))",
1075*de2caf28SDavid du Colombier 	"			{	trpt->tau |= 1;		/* enable timeout */",
1076*de2caf28SDavid du Colombier 	"				goto Repeat_two;",
1077*de2caf28SDavid du Colombier 	"			}",
1078*de2caf28SDavid du Colombier 	"#endif",
1079*de2caf28SDavid du Colombier 	"			if (!noends && !endstate())",
1080*de2caf28SDavid du Colombier 	"			{	bfs_uerror(\"invalid end state.\");",
1081*de2caf28SDavid du Colombier 	"			}",
1082*de2caf28SDavid du Colombier 	"		}",
1083*de2caf28SDavid du Colombier 	"#ifdef VERI",
1084*de2caf28SDavid du Colombier 	"		else /* boq == -1 && now._nr_pr == BASE && trpt->tau != 4 */",
1085*de2caf28SDavid du Colombier 	"		{	trpt->tau |= 4; /* switch to claim for stutter moves */",
1086*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
1087*de2caf28SDavid du Colombier 	"			printf(\"%%3ld: proc -1 exec -1, (stutter move)\\n\", depth, II);",
1088*de2caf28SDavid du Colombier 	"	#endif",
1089*de2caf28SDavid du Colombier 	"			bfs_store_state(trpt, boq);", /* doesn't store it but queues it */
1090*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
1091*de2caf28SDavid du Colombier 	"			printf(\"%%3ld: proc -1 reverses -1, (stutter move)\\n\", depth, II);",
1092*de2caf28SDavid du Colombier 	"	#endif",
1093*de2caf28SDavid du Colombier 	"			trpt->tau &= ~4; /* undo, probably not needed */",
1094*de2caf28SDavid du Colombier 	"		}",
1095*de2caf28SDavid du Colombier 	"#endif",
1096*de2caf28SDavid du Colombier 	"	}",
1097*de2caf28SDavid du Colombier 	"#ifdef BFS_NOTRAIL",
1098*de2caf28SDavid du Colombier 	"	bfs_release_trail(otrpt);",
1099*de2caf28SDavid du Colombier 	"#endif",
1100*de2caf28SDavid du Colombier 	"}",
1101*de2caf28SDavid du Colombier 	"#if !defined(BFS_FIFO) && !defined(BFS_NORECYCLE)",
1102*de2caf28SDavid du Colombier 	"void",
1103*de2caf28SDavid du Colombier 	"bfs_recycle(BFS_Slot *n)",
1104*de2caf28SDavid du Colombier 	"{",
1105*de2caf28SDavid du Colombier 	"	#ifdef BFS_CHECK",
1106*de2caf28SDavid du Colombier 	"	 assert(n != &bfs_null);",
1107*de2caf28SDavid du Colombier 	"	#endif",
1108*de2caf28SDavid du Colombier 	"	n->nxt = bfs_free_slot;",
1109*de2caf28SDavid du Colombier 	"	bfs_free_slot = n;",
1110*de2caf28SDavid du Colombier 	"",
1111*de2caf28SDavid du Colombier 	"	#ifdef BFS_CHECK",
1112*de2caf28SDavid du Colombier 	"	 bfs_printf(\"recycles %%s -- %%p\\n\",",
1113*de2caf28SDavid du Colombier 	"		n->s_data?\"STATE\":\"EMPTY\", (void *) n);",
1114*de2caf28SDavid du Colombier 	"	#endif",
1115*de2caf28SDavid du Colombier 	"}",
1116*de2caf28SDavid du Colombier 	"#endif",
1117*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
1118*de2caf28SDavid du Colombier 	"int",
1119*de2caf28SDavid du Colombier 	"bfs_empty(int p)",	/* return Cores if all empty or index of first non-empty q of p */
1120*de2caf28SDavid du Colombier 	"{	int i;",
1121*de2caf28SDavid du Colombier 	"	const int dst = 0;",
1122*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
1123*de2caf28SDavid du Colombier 	"	{	if (shared_memory->head[dst][p][i] != (BFS_Slot *) 0)",
1124*de2caf28SDavid du Colombier 	"		{",
1125*de2caf28SDavid du Colombier 	"			volatile BFS_Slot *x = shared_memory->head[dst][p][i];",
1126*de2caf28SDavid du Colombier 	"			while (x && x->type == DELETED)",
1127*de2caf28SDavid du Colombier 	"			{	x = x->nxt;",
1128*de2caf28SDavid du Colombier 	"			}",
1129*de2caf28SDavid du Colombier 	"			if (!x)",
1130*de2caf28SDavid du Colombier 	"			{	continue;",
1131*de2caf28SDavid du Colombier 	"			}",
1132*de2caf28SDavid du Colombier 	"			if (p == who_am_i)",
1133*de2caf28SDavid du Colombier 	"			{	shared_memory->head[dst][p][i] = x;",
1134*de2caf28SDavid du Colombier 	"			}",
1135*de2caf28SDavid du Colombier 	"	#ifdef BFS_CHECK",
1136*de2caf28SDavid du Colombier 	"			bfs_printf(\"input q [%%d][%%d][%%d] !empty\\n\",",
1137*de2caf28SDavid du Colombier 	"				dst, p, i);",
1138*de2caf28SDavid du Colombier 	"	#endif",
1139*de2caf28SDavid du Colombier 	"			return i;",
1140*de2caf28SDavid du Colombier 	"	}	}",
1141*de2caf28SDavid du Colombier 	"	#ifdef BFS_CHECK",
1142*de2caf28SDavid du Colombier 	"	 bfs_printf(\"all input qs [%%d][%%d][0..max] empty\\n\",",
1143*de2caf28SDavid du Colombier 	"		dst, p);",
1144*de2caf28SDavid du Colombier 	"	#endif		",
1145*de2caf28SDavid du Colombier 	"	return Cores;",
1146*de2caf28SDavid du Colombier 	"}",
1147*de2caf28SDavid du Colombier 	"#endif",
1148*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
1149*de2caf28SDavid du Colombier 	"void",
1150*de2caf28SDavid du Colombier 	"bfs_ewrite(int fd, const void *p, size_t count)",
1151*de2caf28SDavid du Colombier 	"{",
1152*de2caf28SDavid du Colombier 	"	if (write(fd, p, count) != count)",
1153*de2caf28SDavid du Colombier 	"	{	perror(\"diskwrite\");",
1154*de2caf28SDavid du Colombier 	"		Uerror(\"aborting\");",
1155*de2caf28SDavid du Colombier 	"	}",
1156*de2caf28SDavid du Colombier 	"}",
1157*de2caf28SDavid du Colombier 	"",
1158*de2caf28SDavid du Colombier 	"void",
1159*de2caf28SDavid du Colombier 	"bfs_eread(int fd, void *p, size_t count)",
1160*de2caf28SDavid du Colombier 	"{",
1161*de2caf28SDavid du Colombier 	"	if (read(fd, p, count) != count)",
1162*de2caf28SDavid du Colombier 	"	{	perror(\"diskread\");",
1163*de2caf28SDavid du Colombier 	"		Uerror(\"aborting\");",
1164*de2caf28SDavid du Colombier 	"	}",
1165*de2caf28SDavid du Colombier 	"}",
1166*de2caf28SDavid du Colombier 	"",
1167*de2caf28SDavid du Colombier 	"void",
1168*de2caf28SDavid du Colombier 	"bfs_sink_disk(int who_are_you, BFS_Slot *n)",
1169*de2caf28SDavid du Colombier 	"{	SV_Hold *x;",
1170*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1171*de2caf28SDavid du Colombier 	"	bfs_printf(\"sink_disk -> %%d\\n\", who_are_you);",
1172*de2caf28SDavid du Colombier 	"#endif",
1173*de2caf28SDavid du Colombier 	"	bfs_ewrite(bfs_out_fd[who_are_you], (const void *) n->s_data->t_info, sizeof(BFS_Trail));",
1174*de2caf28SDavid du Colombier 	"	bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &vsize, sizeof(ulong));",
1175*de2caf28SDavid du Colombier 	"	bfs_ewrite(bfs_out_fd[who_are_you], &now, vsize);",
1176*de2caf28SDavid du Colombier 	"",
1177*de2caf28SDavid du Colombier 	"	bfs_release_trail(n->s_data->t_info);",
1178*de2caf28SDavid du Colombier 	"	n->s_data->t_info = (BFS_Trail *) 0;",
1179*de2caf28SDavid du Colombier 	"",
1180*de2caf28SDavid du Colombier 	"#if NRUNS>0",
1181*de2caf28SDavid du Colombier 	"	bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &(n->s_data->omask), sizeof(EV_Hold *));",
1182*de2caf28SDavid du Colombier 	"#endif",
1183*de2caf28SDavid du Colombier 	"#ifdef Q_PROVISO",
1184*de2caf28SDavid du Colombier 	"	bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &(n->s_data->lstate), sizeof(H_el *));",
1185*de2caf28SDavid du Colombier 	"#endif",
1186*de2caf28SDavid du Colombier 	"#if SYNC>0",
1187*de2caf28SDavid du Colombier 	"	bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &(n->s_data->boq), sizeof(short));",
1188*de2caf28SDavid du Colombier 	"#endif",
1189*de2caf28SDavid du Colombier 	"#if VERBOSE",
1190*de2caf28SDavid du Colombier 	"	bfs_ewrite(bfs_out_fd[who_are_you], (const void *) &(n->s_data->nr), sizeof(ulong));",
1191*de2caf28SDavid du Colombier 	"#endif",
1192*de2caf28SDavid du Colombier 	"	shared_memory->bfs_out_cnt[who_am_i] = 1;", /* wrote at least one state */
1193*de2caf28SDavid du Colombier 	"}",
1194*de2caf28SDavid du Colombier 	"void",
1195*de2caf28SDavid du Colombier 	"bfs_source_disk(int fd, volatile BFS_Slot *n)",
1196*de2caf28SDavid du Colombier 	"{	ulong	  nb; /* local temporary */",
1197*de2caf28SDavid du Colombier 	"	SV_Hold  *x;",
1198*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1199*de2caf28SDavid du Colombier 	"	bfs_printf(\"source_disk <- %%d\\n\", who_am_i);",
1200*de2caf28SDavid du Colombier 	"#endif",
1201*de2caf28SDavid du Colombier 	"	n->s_data->t_info = bfs_grab_trail();",
1202*de2caf28SDavid du Colombier 	"	bfs_eread(fd, (void *) n->s_data->t_info, sizeof(BFS_Trail));",
1203*de2caf28SDavid du Colombier 	"	bfs_eread(fd, (void *) &nb, sizeof(ulong));",
1204*de2caf28SDavid du Colombier 	"",
1205*de2caf28SDavid du Colombier 	"	x = bfs_new_sv(nb);	/* space for osv isn't already allocated */",
1206*de2caf28SDavid du Colombier 	"	n->s_data->osv = x->sv;",
1207*de2caf28SDavid du Colombier 	"	x->sv = (State *) 0;",
1208*de2caf28SDavid du Colombier 	"	x->nxt = bfs_free_hold;",
1209*de2caf28SDavid du Colombier 	"	bfs_free_hold = x;",
1210*de2caf28SDavid du Colombier 	"",
1211*de2caf28SDavid du Colombier 	"	bfs_eread(fd, (void *) n->s_data->osv, (size_t) nb);",
1212*de2caf28SDavid du Colombier 	"#if NRUNS>0",
1213*de2caf28SDavid du Colombier 	"	bfs_eread(fd, (void *) &(n->s_data->omask), sizeof(EV_Hold *));",
1214*de2caf28SDavid du Colombier 	"#endif",
1215*de2caf28SDavid du Colombier 	"#ifdef Q_PROVISO",
1216*de2caf28SDavid du Colombier 	"	bfs_eread(fd, (void *) &(n->s_data->lstate), sizeof(H_el *));",
1217*de2caf28SDavid du Colombier 	"#endif",
1218*de2caf28SDavid du Colombier 	"#if SYNC>0",
1219*de2caf28SDavid du Colombier 	"	bfs_eread(fd, (void *) &(n->s_data->boq), sizeof(short));",
1220*de2caf28SDavid du Colombier 	"#endif",
1221*de2caf28SDavid du Colombier 	"#if VERBOSE",
1222*de2caf28SDavid du Colombier 	"	bfs_eread(fd, (void *) &(n->s_data->nr), sizeof(ulong));",
1223*de2caf28SDavid du Colombier 	"#endif",
1224*de2caf28SDavid du Colombier 	"}",
1225*de2caf28SDavid du Colombier 	"#endif",
1226*de2caf28SDavid du Colombier 	"",
1227*de2caf28SDavid du Colombier 	"#ifndef BFS_QSZ",
1228*de2caf28SDavid du Colombier 	" #ifdef BFS_STAGGER",
1229*de2caf28SDavid du Colombier 	"static BFS_Slot *bfs_stage[BFS_STAGGER];",
1230*de2caf28SDavid du Colombier 	"",
1231*de2caf28SDavid du Colombier 	"static void",
1232*de2caf28SDavid du Colombier 	"bfs_stagger_flush(void)",
1233*de2caf28SDavid du Colombier 	"{	int i, who_are_you;",
1234*de2caf28SDavid du Colombier 	"	int dst = 1 - bfs_toggle;",
1235*de2caf28SDavid du Colombier 	"	BFS_Slot *n;",
1236*de2caf28SDavid du Colombier 	"	who_are_you = (rand()%%Cores);", /* important: all to the same cpu, but reversed */
1237*de2caf28SDavid du Colombier 	"	for (i = bfs_stage_cnt-1; i >= 0; i--)",
1238*de2caf28SDavid du Colombier 	"	{	n = bfs_stage[i];",
1239*de2caf28SDavid du Colombier 	" #ifdef BFS_DISK",
1240*de2caf28SDavid du Colombier 	"		bfs_sink_disk(who_are_you, n);",
1241*de2caf28SDavid du Colombier 	"		bfs_stage[i] = (BFS_Slot *) 0;",
1242*de2caf28SDavid du Colombier 	" #endif",
1243*de2caf28SDavid du Colombier 	"		n->nxt = (BFS_Slot *) shared_memory->head[dst][who_are_you][who_am_i];",
1244*de2caf28SDavid du Colombier 	"		shared_memory->head[dst][who_are_you][who_am_i] = n;",
1245*de2caf28SDavid du Colombier 	"		/* bfs_sent++; */",
1246*de2caf28SDavid du Colombier 	"	}",
1247*de2caf28SDavid du Colombier 	"	#ifdef VERBOSE",
1248*de2caf28SDavid du Colombier 	"		bfs_printf(\"stagger flush %%d states to %%d\\n\",",
1249*de2caf28SDavid du Colombier 	"			bfs_stage_cnt, who_are_you);",
1250*de2caf28SDavid du Colombier 	"	#endif",
1251*de2caf28SDavid du Colombier 	"	bfs_stage_cnt = 0;",
1252*de2caf28SDavid du Colombier 	"}",
1253*de2caf28SDavid du Colombier 	"",
1254*de2caf28SDavid du Colombier 	"void",
1255*de2caf28SDavid du Colombier 	"bfs_stagger_add(BFS_Slot *n)",
1256*de2caf28SDavid du Colombier 	"{",
1257*de2caf28SDavid du Colombier 	"	if (bfs_stage_cnt == BFS_STAGGER)",
1258*de2caf28SDavid du Colombier 	"	{	bfs_stagger_flush();",
1259*de2caf28SDavid du Colombier 	"	}",
1260*de2caf28SDavid du Colombier 	"	bfs_stage[bfs_stage_cnt++] = n;",
1261*de2caf28SDavid du Colombier 	"}",
1262*de2caf28SDavid du Colombier 	" #endif",
1263*de2caf28SDavid du Colombier 	"#endif",
1264*de2caf28SDavid du Colombier 	"",
1265*de2caf28SDavid du Colombier 	"void",
1266*de2caf28SDavid du Colombier 	"bfs_push_state(Trail *x, BFS_Trail *y, int tt)",
1267*de2caf28SDavid du Colombier 	"{	int who_are_you;",
1268*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
1269*de2caf28SDavid du Colombier 	"	const int dst = 0;",
1270*de2caf28SDavid du Colombier 	"#else",
1271*de2caf28SDavid du Colombier 	"	int dst = 1 - bfs_toggle;",
1272*de2caf28SDavid du Colombier 	"#endif",
1273*de2caf28SDavid du Colombier 	"#ifdef BFS_QSZ",
1274*de2caf28SDavid du Colombier 	"	uint z;",
1275*de2caf28SDavid du Colombier 	"	if (bfs_keep_state > 0)",
1276*de2caf28SDavid du Colombier 	"	{	who_are_you = bfs_keep_state - 1;",
1277*de2caf28SDavid du Colombier 	"	} else",
1278*de2caf28SDavid du Colombier 	"	{	who_are_you = (rand()%%Cores);",
1279*de2caf28SDavid du Colombier 	"	}",
1280*de2caf28SDavid du Colombier 	"	z = shared_memory->bfs_ix[dst][who_are_you][who_am_i];",
1281*de2caf28SDavid du Colombier 	"	if (z >= BFS_QSZ)",
1282*de2caf28SDavid du Colombier 	"	{	static int warned_qloss = 0;",
1283*de2caf28SDavid du Colombier 	"		if (warned_qloss == 0 && who_am_i == 0)",
1284*de2caf28SDavid du Colombier 	"		{	warned_qloss++;",
1285*de2caf28SDavid du Colombier 	"			bfs_printf(\"BFS_QSZ too small - losing states\\n\");",
1286*de2caf28SDavid du Colombier 	"		}",
1287*de2caf28SDavid du Colombier 	"		bfs_punt++;",
1288*de2caf28SDavid du Colombier 	"		return;",
1289*de2caf28SDavid du Colombier 	"	}",
1290*de2caf28SDavid du Colombier 	"	shared_memory->bfs_ix[dst][who_are_you][who_am_i] = z+1;",
1291*de2caf28SDavid du Colombier 	"	BFS_Slot *n = bfs_pack_state(x, y, tt, bfs_prep_slot(y, ",
1292*de2caf28SDavid du Colombier 	"		(BFS_Slot *) &(shared_memory->bfsq[dst][who_are_you][who_am_i][z])));",
1293*de2caf28SDavid du Colombier 	"#else",
1294*de2caf28SDavid du Colombier 	"	BFS_Slot *n = bfs_pack_state(x, y, tt, bfs_new_slot(y));",
1295*de2caf28SDavid du Colombier 	"",
1296*de2caf28SDavid du Colombier 	" #ifdef BFS_GREEDY",
1297*de2caf28SDavid du Colombier 	"	who_are_you = who_am_i; /* for testing only */",
1298*de2caf28SDavid du Colombier 	" #else",
1299*de2caf28SDavid du Colombier 	"	if (bfs_keep_state > 0)",
1300*de2caf28SDavid du Colombier 	"	{	who_are_you = bfs_keep_state - 1;",
1301*de2caf28SDavid du Colombier 	"	} else",
1302*de2caf28SDavid du Colombier 	"	{",
1303*de2caf28SDavid du Colombier 	"	#ifdef BFS_STAGGER",
1304*de2caf28SDavid du Colombier 	"		who_are_you = -1;",
1305*de2caf28SDavid du Colombier 	"		bfs_stagger_add(n);",
1306*de2caf28SDavid du Colombier 	"		goto done;",
1307*de2caf28SDavid du Colombier 	"	#else",
1308*de2caf28SDavid du Colombier 	"		who_are_you = (rand()%%Cores);",
1309*de2caf28SDavid du Colombier 	"	#endif",
1310*de2caf28SDavid du Colombier 	"	}",
1311*de2caf28SDavid du Colombier 	" #endif",
1312*de2caf28SDavid du Colombier 	" #ifdef BFS_FIFO",
1313*de2caf28SDavid du Colombier 	"	  if (!shared_memory->tail[dst][who_are_you][who_am_i])",
1314*de2caf28SDavid du Colombier 	"	  {	shared_memory->dels[dst][who_are_you][who_am_i] =",
1315*de2caf28SDavid du Colombier 	"		shared_memory->tail[dst][who_are_you][who_am_i] =",
1316*de2caf28SDavid du Colombier 	"		shared_memory->head[dst][who_are_you][who_am_i] = n;",
1317*de2caf28SDavid du Colombier 	"	  } else",
1318*de2caf28SDavid du Colombier 	"	  {	shared_memory->tail[dst][who_are_you][who_am_i]->nxt = n;",
1319*de2caf28SDavid du Colombier 	"		shared_memory->tail[dst][who_are_you][who_am_i] = n;",
1320*de2caf28SDavid du Colombier 	"	  }",
1321*de2caf28SDavid du Colombier 	"	  shared_memory->bfs_idle[who_are_you] = 0;",
1322*de2caf28SDavid du Colombier 	" #else",
1323*de2caf28SDavid du Colombier 	"  #ifdef BFS_DISK",
1324*de2caf28SDavid du Colombier 	"	  bfs_sink_disk(who_are_you, n);",
1325*de2caf28SDavid du Colombier 	"  #endif",
1326*de2caf28SDavid du Colombier 	"	  n->nxt = (BFS_Slot *) shared_memory->head[dst][who_are_you][who_am_i];",
1327*de2caf28SDavid du Colombier 	"	  shared_memory->head[dst][who_are_you][who_am_i] = n;",
1328*de2caf28SDavid du Colombier 	" #endif",
1329*de2caf28SDavid du Colombier 	" #ifdef BFS_STAGGER",
1330*de2caf28SDavid du Colombier 	"done:",
1331*de2caf28SDavid du Colombier 	" #endif",
1332*de2caf28SDavid du Colombier 	"#endif", /* BFS_QSZ */
1333*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1334*de2caf28SDavid du Colombier 	"	bfs_printf(\"PUT STATE (depth %%ld, nr %%u) to %%d -- s_data: %%p\\n\",",
1335*de2caf28SDavid du Colombier 	"		tt, n->s_data->nr, who_are_you, n->s_data);",
1336*de2caf28SDavid du Colombier 	"#endif",
1337*de2caf28SDavid du Colombier 	"	bfs_sent++;",
1338*de2caf28SDavid du Colombier 	"}",
1339*de2caf28SDavid du Colombier 	"",
1340*de2caf28SDavid du Colombier 	"BFS_Slot *",
1341*de2caf28SDavid du Colombier 	"bfs_next(void)",
1342*de2caf28SDavid du Colombier 	"{	volatile BFS_Slot *n = &bfs_null;",
1343*de2caf28SDavid du Colombier 	" #ifdef BFS_FIFO",
1344*de2caf28SDavid du Colombier 	"	const int src = 0;",
1345*de2caf28SDavid du Colombier 	"	bfs_qscan = bfs_empty(who_am_i);",
1346*de2caf28SDavid du Colombier 	" #else",
1347*de2caf28SDavid du Colombier 	"	const int src = bfs_toggle;",
1348*de2caf28SDavid du Colombier 	"  #ifdef BFS_QSZ",
1349*de2caf28SDavid du Colombier 	"	while (bfs_qscan < Cores",
1350*de2caf28SDavid du Colombier 	"	&& shared_memory->bfs_ix[src][who_am_i][bfs_qscan] == 0)",
1351*de2caf28SDavid du Colombier 	"	{	bfs_qscan++;",
1352*de2caf28SDavid du Colombier 	"	}",
1353*de2caf28SDavid du Colombier 	"  #else",
1354*de2caf28SDavid du Colombier 	"	while (bfs_qscan < Cores",
1355*de2caf28SDavid du Colombier 	"	&& shared_memory->head[src][who_am_i][bfs_qscan] == (BFS_Slot *) 0)",
1356*de2caf28SDavid du Colombier 	"	{	bfs_qscan++;",
1357*de2caf28SDavid du Colombier 	"	}",
1358*de2caf28SDavid du Colombier 	"  #endif",
1359*de2caf28SDavid du Colombier 	" #endif",
1360*de2caf28SDavid du Colombier 	"	if (bfs_qscan < Cores)",
1361*de2caf28SDavid du Colombier 	"	{",
1362*de2caf28SDavid du Colombier 	" #ifdef BFS_FIFO",			/* no wait for toggles */
1363*de2caf28SDavid du Colombier 	"		shared_memory->bfs_idle[who_am_i] = 0;",
1364*de2caf28SDavid du Colombier 	"		for (n = shared_memory->head[src][who_am_i][bfs_qscan]; n; n = n->nxt)",
1365*de2caf28SDavid du Colombier 	"		{	if (n->type != DELETED)",
1366*de2caf28SDavid du Colombier 	"			{	break;",
1367*de2caf28SDavid du Colombier 	"		}	}",
1368*de2caf28SDavid du Colombier 	"	#ifdef BFS_CHECK",
1369*de2caf28SDavid du Colombier 	"		assert(n && n->type == STATE); /* q cannot be empty */",
1370*de2caf28SDavid du Colombier 	"	#endif",
1371*de2caf28SDavid du Colombier 	"		if (n->nxt)",
1372*de2caf28SDavid du Colombier 	"		{	shared_memory->head[src][who_am_i][bfs_qscan] = n->nxt;",
1373*de2caf28SDavid du Colombier 	"		}",	/* else, do not remove it - yet - avoid empty queues */
1374*de2caf28SDavid du Colombier 	"		n->type = DELETED;",
1375*de2caf28SDavid du Colombier 	" #else",
1376*de2caf28SDavid du Colombier 	"	#ifdef BFS_QSZ",
1377*de2caf28SDavid du Colombier 	"		uint x = --shared_memory->bfs_ix[src][who_am_i][bfs_qscan];",
1378*de2caf28SDavid du Colombier 	"		n = &(shared_memory->bfsq[src][who_am_i][bfs_qscan][x]);",
1379*de2caf28SDavid du Colombier 	"	#else",
1380*de2caf28SDavid du Colombier 	"		n = shared_memory->head[src][who_am_i][bfs_qscan];",
1381*de2caf28SDavid du Colombier 	"		shared_memory->head[src][who_am_i][bfs_qscan] = n->nxt;",
1382*de2caf28SDavid du Colombier 	"		#if defined(BFS_FIFO) && defined(BFS_CHECK)",
1383*de2caf28SDavid du Colombier 	"			assert(n->type == STATE);",
1384*de2caf28SDavid du Colombier 	"		#endif",
1385*de2caf28SDavid du Colombier 	"		n->nxt = (BFS_Slot *) 0;",
1386*de2caf28SDavid du Colombier 	"	#endif",
1387*de2caf28SDavid du Colombier 	"	#ifdef BFS_DISK",
1388*de2caf28SDavid du Colombier 	"		/* the states actually show up in reverse order (FIFO iso LIFO) here */",
1389*de2caf28SDavid du Colombier 	"		/* but that doesn't really matter as long as the count is right */",
1390*de2caf28SDavid du Colombier 	"		bfs_source_disk(bfs_inp_fd[bfs_qscan], n); /* get the data */",
1391*de2caf28SDavid du Colombier 	"	#endif",
1392*de2caf28SDavid du Colombier 
1393*de2caf28SDavid du Colombier 	" #endif",
1394*de2caf28SDavid du Colombier 	" #ifdef BFS_CHECK",
1395*de2caf28SDavid du Colombier 	"		bfs_printf(\"rcv STATE from [%%d][%%d][%%d]\\n\",",
1396*de2caf28SDavid du Colombier 	"			src, who_am_i, bfs_qscan);",
1397*de2caf28SDavid du Colombier 	" #endif",
1398*de2caf28SDavid du Colombier 	"		bfs_rcvd++;",
1399*de2caf28SDavid du Colombier 	"	} else",
1400*de2caf28SDavid du Colombier 	"	{",
1401*de2caf28SDavid du Colombier 	" #if defined(BFS_STAGGER) && !defined(BFS_QSZ)",
1402*de2caf28SDavid du Colombier 	"		if (bfs_stage_cnt > 0)",
1403*de2caf28SDavid du Colombier 	"		{	bfs_stagger_flush();",
1404*de2caf28SDavid du Colombier 	"		}",
1405*de2caf28SDavid du Colombier 	" #endif",
1406*de2caf28SDavid du Colombier 	"		shared_memory->bfs_idle[who_am_i] = 1;",
1407*de2caf28SDavid du Colombier 	" #if defined(BFS_FIFO) && defined(BFS_CHECK)",
1408*de2caf28SDavid du Colombier 	"		assert(n->type == EMPTY);",
1409*de2caf28SDavid du Colombier 	" #endif",
1410*de2caf28SDavid du Colombier 	"	}",
1411*de2caf28SDavid du Colombier 	"	return (BFS_Slot *) n;",
1412*de2caf28SDavid du Colombier 	"}",
1413*de2caf28SDavid du Colombier 	"",
1414*de2caf28SDavid du Colombier 	"int",
1415*de2caf28SDavid du Colombier 	"bfs_all_empty(void)",
1416*de2caf28SDavid du Colombier 	"{	int i;",
1417*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
1418*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
1419*de2caf28SDavid du Colombier 	"	{	if (shared_memory->bfs_out_cnt[i] != 0)",
1420*de2caf28SDavid du Colombier 	"		{",
1421*de2caf28SDavid du Colombier 	"  #ifdef VERBOSE",
1422*de2caf28SDavid du Colombier 	"			bfs_printf(\"bfs_all_empty %%d not empty\\n\", i);",
1423*de2caf28SDavid du Colombier 	"  #endif",
1424*de2caf28SDavid du Colombier 	"			return 0;",
1425*de2caf28SDavid du Colombier 	"	}	}",
1426*de2caf28SDavid du Colombier 	"#else",
1427*de2caf28SDavid du Colombier 	"	int p;",
1428*de2caf28SDavid du Colombier 	"  #ifdef BFS_FIFO",
1429*de2caf28SDavid du Colombier 	"	const int dst = 0;",
1430*de2caf28SDavid du Colombier 	"  #else",
1431*de2caf28SDavid du Colombier 	"	int dst = 1 - bfs_toggle; /* next generation */",
1432*de2caf28SDavid du Colombier 	"  #endif",
1433*de2caf28SDavid du Colombier 	"	for (p = 0; p < Cores; p++)",
1434*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
1435*de2caf28SDavid du Colombier 	"  #ifdef BFS_QSZ",
1436*de2caf28SDavid du Colombier 	"	{	if (shared_memory->bfs_ix[dst][p][i] > 0)",
1437*de2caf28SDavid du Colombier 	"  #else",
1438*de2caf28SDavid du Colombier 	"	{	if (shared_memory->head[dst][p][i] != (BFS_Slot *) 0)",
1439*de2caf28SDavid du Colombier 	"  #endif",
1440*de2caf28SDavid du Colombier 	"		{	return 0;",
1441*de2caf28SDavid du Colombier 	"	}	}",
1442*de2caf28SDavid du Colombier 	"#endif",
1443*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1444*de2caf28SDavid du Colombier 	"	bfs_printf(\"bfs_all_empty\\n\");",
1445*de2caf28SDavid du Colombier 	"#endif",
1446*de2caf28SDavid du Colombier 	"	return 1;",
1447*de2caf28SDavid du Colombier 	"}",
1448*de2caf28SDavid du Colombier 	"",
1449*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
1450*de2caf28SDavid du Colombier 	"BFS_Slot *",
1451*de2caf28SDavid du Colombier 	"bfs_sweep(void)",
1452*de2caf28SDavid du Colombier 	"{	BFS_Slot *n;",
1453*de2caf28SDavid du Colombier 	"	int i;",
1454*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
1455*de2caf28SDavid du Colombier 	"	for (n = (BFS_Slot *) shared_memory->dels[0][who_am_i][i];",
1456*de2caf28SDavid du Colombier 	"		n && n != shared_memory->head[0][who_am_i][i];",
1457*de2caf28SDavid du Colombier 	"		n = n->nxt)",
1458*de2caf28SDavid du Colombier 	"	{	if (n->type == DELETED && n->nxt)",
1459*de2caf28SDavid du Colombier 	"		{	shared_memory->dels[0][who_am_i][i] = n->nxt;",
1460*de2caf28SDavid du Colombier 	"			n->nxt = (BFS_Slot *) 0;",
1461*de2caf28SDavid du Colombier 	"			return n;",
1462*de2caf28SDavid du Colombier 	"	}	}",
1463*de2caf28SDavid du Colombier 	"	return (BFS_Slot *) sh_malloc((ulong) sizeof(BFS_Slot));",
1464*de2caf28SDavid du Colombier 	"}",
1465*de2caf28SDavid du Colombier 	"#endif",
1466*de2caf28SDavid du Colombier 	"",
1467*de2caf28SDavid du Colombier 	"typedef struct BFS_T_Hold BFS_T_Hold;",
1468*de2caf28SDavid du Colombier 	"struct BFS_T_Hold {",
1469*de2caf28SDavid du Colombier 	"	volatile BFS_Trail *t;",
1470*de2caf28SDavid du Colombier 	"	BFS_T_Hold *nxt;",
1471*de2caf28SDavid du Colombier 	"};",
1472*de2caf28SDavid du Colombier 	"BFS_T_Hold *bfs_t_held, *bfs_t_free;",
1473*de2caf28SDavid du Colombier 	"",
1474*de2caf28SDavid du Colombier 	"BFS_Trail *",
1475*de2caf28SDavid du Colombier 	"bfs_grab_trail(void)",			/* call in bfs_source_disk and bfs_new_slot */
1476*de2caf28SDavid du Colombier 	"{	BFS_Trail *t;",
1477*de2caf28SDavid du Colombier 	"	BFS_T_Hold *h;",
1478*de2caf28SDavid du Colombier 	"",
1479*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1480*de2caf28SDavid du Colombier 	"	bfs_printf(\"grab trail - bfs_t_held %%p\\n\", (void *) bfs_t_held);",
1481*de2caf28SDavid du Colombier 	"#endif",
1482*de2caf28SDavid du Colombier 	"	if (bfs_t_held)",
1483*de2caf28SDavid du Colombier 	"	{	h = bfs_t_held;",
1484*de2caf28SDavid du Colombier 	"		bfs_t_held = bfs_t_held->nxt;",
1485*de2caf28SDavid du Colombier 	"		t = (BFS_Trail *) h->t;",
1486*de2caf28SDavid du Colombier 	"		h->t = (BFS_Trail *) 0; /* make sure it cannot be reused */",
1487*de2caf28SDavid du Colombier 	"		h->nxt = bfs_t_free;",
1488*de2caf28SDavid du Colombier 	"		bfs_t_free = h;",
1489*de2caf28SDavid du Colombier 	"",
1490*de2caf28SDavid du Colombier 	"	} else",
1491*de2caf28SDavid du Colombier 	"	{	t = (BFS_Trail *) sh_malloc((ulong) sizeof(BFS_Trail));",
1492*de2caf28SDavid du Colombier 	"	}",
1493*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
1494*de2caf28SDavid du Colombier 	"	assert(t);",
1495*de2caf28SDavid du Colombier 	"#endif",
1496*de2caf28SDavid du Colombier 	"	t->ostate = (H_el *) 0;",
1497*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1498*de2caf28SDavid du Colombier 	"	bfs_printf(\"grab trail %%p\\n\", (void *) t);",
1499*de2caf28SDavid du Colombier 	"#endif",
1500*de2caf28SDavid du Colombier 	"	return t;",
1501*de2caf28SDavid du Colombier 	"}",
1502*de2caf28SDavid du Colombier 	"",
1503*de2caf28SDavid du Colombier 	"#if defined(BFS_DISK) || defined(BFS_NOTRAIL)",
1504*de2caf28SDavid du Colombier 	"void",
1505*de2caf28SDavid du Colombier 	"bfs_release_trail(BFS_Trail *t)",	/* call in bfs_sink_disk (not bfs_recycle) */
1506*de2caf28SDavid du Colombier 	"{	BFS_T_Hold *h;",
1507*de2caf28SDavid du Colombier 	" #ifdef BFS_CHECK",
1508*de2caf28SDavid du Colombier 	"	assert(t);",
1509*de2caf28SDavid du Colombier 	" #endif",
1510*de2caf28SDavid du Colombier 	" #ifdef VERBOSE",
1511*de2caf28SDavid du Colombier 	"	bfs_printf(\"release trail %%p\\n\", (void *) t);",
1512*de2caf28SDavid du Colombier 	"	#endif",
1513*de2caf28SDavid du Colombier 	"	if (bfs_t_free)",
1514*de2caf28SDavid du Colombier 	"	{	h = bfs_t_free;",
1515*de2caf28SDavid du Colombier 	"		bfs_t_free = bfs_t_free->nxt;",
1516*de2caf28SDavid du Colombier 	"	} else",
1517*de2caf28SDavid du Colombier 	"	{	h = (BFS_T_Hold *) emalloc(sizeof(BFS_T_Hold));",
1518*de2caf28SDavid du Colombier 	"	}",
1519*de2caf28SDavid du Colombier 	"	h->t = t;",
1520*de2caf28SDavid du Colombier 	"	h->nxt = bfs_t_held;",
1521*de2caf28SDavid du Colombier 	"	bfs_t_held = h;",
1522*de2caf28SDavid du Colombier 	" #ifdef VERBOSE",
1523*de2caf28SDavid du Colombier 	"	bfs_printf(\"release trail - bfs_t_held %%p\\n\", (void *) bfs_t_held);",
1524*de2caf28SDavid du Colombier 	" #endif",
1525*de2caf28SDavid du Colombier 	"}",
1526*de2caf28SDavid du Colombier 	"#endif",
1527*de2caf28SDavid du Colombier 	"",
1528*de2caf28SDavid du Colombier 	"#ifndef BFS_QSZ",
1529*de2caf28SDavid du Colombier 	"BFS_Slot *",
1530*de2caf28SDavid du Colombier 	"bfs_new_slot(BFS_Trail *f)",
1531*de2caf28SDavid du Colombier 	"{	BFS_Slot *t;",
1532*de2caf28SDavid du Colombier 	"",
1533*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
1534*de2caf28SDavid du Colombier 	"	t = bfs_sweep();",
1535*de2caf28SDavid du Colombier 	"#else",
1536*de2caf28SDavid du Colombier 	"	if (bfs_free_slot)	/* local */",
1537*de2caf28SDavid du Colombier 	"	{	t = bfs_free_slot;",
1538*de2caf28SDavid du Colombier 	"		bfs_free_slot = bfs_free_slot->nxt;",
1539*de2caf28SDavid du Colombier 	"		t->nxt = (BFS_Slot *) 0;",
1540*de2caf28SDavid du Colombier 	"	} else",
1541*de2caf28SDavid du Colombier 	"	{	t = (BFS_Slot *) sh_malloc((ulong) sizeof(BFS_Slot));",
1542*de2caf28SDavid du Colombier 	"	}",
1543*de2caf28SDavid du Colombier 	"#endif",
1544*de2caf28SDavid du Colombier 	"	if (t->s_data)",
1545*de2caf28SDavid du Colombier 	"	{	memset(t->s_data, 0, sizeof(BFS_State));",
1546*de2caf28SDavid du Colombier 	"	} else",
1547*de2caf28SDavid du Colombier 	"	{	t->s_data = (BFS_State *) sh_malloc((ulong) sizeof(BFS_State));",
1548*de2caf28SDavid du Colombier 	"	}",
1549*de2caf28SDavid du Colombier 	"",
1550*de2caf28SDavid du Colombier 	"	/* we keep a ptr to the frame of parent states, which is */",
1551*de2caf28SDavid du Colombier 	"	/* used for reconstructing path and recovering failed rvs etc */",
1552*de2caf28SDavid du Colombier 	"	/* we should not overwrite the data at this address with a memset */",
1553*de2caf28SDavid du Colombier 	"",
1554*de2caf28SDavid du Colombier 	"	if (f)",
1555*de2caf28SDavid du Colombier 	"	{	t->s_data->t_info = f;",
1556*de2caf28SDavid du Colombier 	"	} else",
1557*de2caf28SDavid du Colombier 	"	{	t->s_data->t_info = bfs_grab_trail();",
1558*de2caf28SDavid du Colombier 	"	}",
1559*de2caf28SDavid du Colombier 	"	return t;",
1560*de2caf28SDavid du Colombier 	"}",
1561*de2caf28SDavid du Colombier 	"#else",
1562*de2caf28SDavid du Colombier 	"BFS_Slot *",
1563*de2caf28SDavid du Colombier 	"bfs_prep_slot(BFS_Trail *f, BFS_Slot *t)",
1564*de2caf28SDavid du Colombier 	"{",
1565*de2caf28SDavid du Colombier 	"	if (t->s_data)",
1566*de2caf28SDavid du Colombier 	"	{	memset(t->s_data, 0, sizeof(BFS_State));",
1567*de2caf28SDavid du Colombier 	"	} else",
1568*de2caf28SDavid du Colombier 	"	{	t->s_data = (BFS_State *) sh_malloc((ulong) sizeof(BFS_State));",
1569*de2caf28SDavid du Colombier 	"	}",
1570*de2caf28SDavid du Colombier 	"	if (f)",
1571*de2caf28SDavid du Colombier 	"	{	t->s_data->t_info = f;",
1572*de2caf28SDavid du Colombier 	"	} else",
1573*de2caf28SDavid du Colombier 	"	{	t->s_data->t_info = bfs_grab_trail();",
1574*de2caf28SDavid du Colombier 	"	}",
1575*de2caf28SDavid du Colombier 	"	return t;",
1576*de2caf28SDavid du Colombier 	"}",
1577*de2caf28SDavid du Colombier 	"#endif",
1578*de2caf28SDavid du Colombier 	"",
1579*de2caf28SDavid du Colombier 	"SV_Hold *",
1580*de2caf28SDavid du Colombier 	"bfs_new_sv(int n)",
1581*de2caf28SDavid du Colombier 	"{	SV_Hold *h;",
1582*de2caf28SDavid du Colombier 	"",
1583*de2caf28SDavid du Colombier 	"	if (bfs_svfree[n])",
1584*de2caf28SDavid du Colombier 	"	{	h = bfs_svfree[n];",
1585*de2caf28SDavid du Colombier 	"		bfs_svfree[n] = h->nxt;",
1586*de2caf28SDavid du Colombier 	"		h->nxt = (SV_Hold *) 0;",
1587*de2caf28SDavid du Colombier 	"	} else",
1588*de2caf28SDavid du Colombier 	"	{	h = (SV_Hold *) sh_malloc((ulong) sizeof(SV_Hold));",
1589*de2caf28SDavid du Colombier 	"#if 0",
1590*de2caf28SDavid du Colombier 	"		h->sz = n;",
1591*de2caf28SDavid du Colombier 	"#endif",
1592*de2caf28SDavid du Colombier 	"		h->sv = (State *) sh_malloc((ulong)(sizeof(State) - VECTORSZ + n));",
1593*de2caf28SDavid du Colombier 	"	}",
1594*de2caf28SDavid du Colombier 	"	memcpy((char *)h->sv, (char *)&now, n);",
1595*de2caf28SDavid du Colombier 	"	return h;",
1596*de2caf28SDavid du Colombier 	"}",
1597*de2caf28SDavid du Colombier 	"#if NRUNS>0",
1598*de2caf28SDavid du Colombier 	"static EV_Hold *kept[VECTORSZ];	/* local */",
1599*de2caf28SDavid du Colombier 	"",
1600*de2caf28SDavid du Colombier 	"static void",
1601*de2caf28SDavid du Colombier 	"bfs_keep(EV_Hold *v)",
1602*de2caf28SDavid du Colombier 	"{	EV_Hold *h;",
1603*de2caf28SDavid du Colombier 	"",
1604*de2caf28SDavid du Colombier 	"	for (h = kept[v->sz]; h; h = h->nxt) /* check local list */",
1605*de2caf28SDavid du Colombier 	"	{	if (v->nrpr == h->nrpr",
1606*de2caf28SDavid du Colombier 	"		&&  v->nrqs == h->nrqs",
1607*de2caf28SDavid du Colombier 	"#if !defined(NOCOMP) && !defined(HC)",
1608*de2caf28SDavid du Colombier 	"		&&  (v->sv == h->sv || memcmp((char *) v->sv, (char *) h->sv, v->sz) == 0)",
1609*de2caf28SDavid du Colombier 	"#endif",
1610*de2caf28SDavid du Colombier 	"#ifdef TRIX",
1611*de2caf28SDavid du Colombier 	"		)",
1612*de2caf28SDavid du Colombier 	"#else",
1613*de2caf28SDavid du Colombier 	"	#if NRUNS>0",
1614*de2caf28SDavid du Colombier 	"		#if VECTORSZ>32000",
1615*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) v->po, (char *) h->po, v->nrpr * sizeof(int)) == 0)",
1616*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) v->qo, (char *) h->qo, v->nrqs * sizeof(int)) == 0)",
1617*de2caf28SDavid du Colombier 	"		#else",
1618*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) v->po, (char *) h->po, v->nrpr * sizeof(short)) == 0)",
1619*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) v->qo, (char *) h->qo, v->nrqs * sizeof(short)) == 0)",
1620*de2caf28SDavid du Colombier 	"		#endif",
1621*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) v->ps, (char *) h->ps, v->nrpr * sizeof(uchar)) == 0)",
1622*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) v->qs, (char *) h->qs, v->nrqs * sizeof(uchar)) == 0))",
1623*de2caf28SDavid du Colombier 	"	#else",
1624*de2caf28SDavid du Colombier 	"		)",
1625*de2caf28SDavid du Colombier 	"	#endif",
1626*de2caf28SDavid du Colombier 	"#endif",
1627*de2caf28SDavid du Colombier 	"		{	break;",
1628*de2caf28SDavid du Colombier 	"	}	}",
1629*de2caf28SDavid du Colombier 	"",
1630*de2caf28SDavid du Colombier 	"	if (!h)	/* we don't have one like it yet */",
1631*de2caf28SDavid du Colombier 	"	{	v->nxt = kept[v->sz];	/* keep the original owner field */",
1632*de2caf28SDavid du Colombier 	"		kept[v->sz] = v;",
1633*de2caf28SDavid du Colombier 	"		/* all ptrs inside are to shared memory, but nxt is local */",
1634*de2caf28SDavid du Colombier 	"	}",
1635*de2caf28SDavid du Colombier 	"}",
1636*de2caf28SDavid du Colombier 	"",
1637*de2caf28SDavid du Colombier 	"EV_Hold *",
1638*de2caf28SDavid du Colombier 	"bfs_new_sv_mask(int n)",
1639*de2caf28SDavid du Colombier 	"{	EV_Hold *h;",
1640*de2caf28SDavid du Colombier 	"",
1641*de2caf28SDavid du Colombier 	"	for (h = kept[n]; h; h = h->nxt)",
1642*de2caf28SDavid du Colombier 	"	{	if ((now._nr_pr == h->nrpr)",
1643*de2caf28SDavid du Colombier 	"		&&  (now._nr_qs == h->nrqs)",
1644*de2caf28SDavid du Colombier 	"#if !defined(NOCOMP) && !defined(HC) && NRUNS>0",
1645*de2caf28SDavid du Colombier 	"		&& ((char *) Mask == h->sv || (memcmp((char *) Mask, h->sv, n) == 0))",
1646*de2caf28SDavid du Colombier 	"#endif",
1647*de2caf28SDavid du Colombier 	"#ifdef TRIX",
1648*de2caf28SDavid du Colombier 	"		)",
1649*de2caf28SDavid du Colombier 	"#else",
1650*de2caf28SDavid du Colombier 	"	#if NRUNS>0",
1651*de2caf28SDavid du Colombier 	"		#if VECTORSZ>32000",
1652*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(int)) == 0)",
1653*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) q_offset,    (char *) h->qo, now._nr_qs * sizeof(int)) == 0)",
1654*de2caf28SDavid du Colombier 	"		#else",
1655*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) proc_offset, (char *) h->po, now._nr_pr * sizeof(short)) == 0)",
1656*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) q_offset,    (char *) h->qo, now._nr_qs * sizeof(short)) == 0)",
1657*de2caf28SDavid du Colombier 	"		#endif",
1658*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) proc_skip, (char *) h->ps, now._nr_pr * sizeof(uchar)) == 0)",
1659*de2caf28SDavid du Colombier 	"		&&  (memcmp((char *) q_skip,    (char *) h->qs, now._nr_qs * sizeof(uchar)) == 0))",
1660*de2caf28SDavid du Colombier 	"	#else",
1661*de2caf28SDavid du Colombier 	"		)",
1662*de2caf28SDavid du Colombier 	"	#endif",
1663*de2caf28SDavid du Colombier 	"#endif",
1664*de2caf28SDavid du Colombier 	"		{	break;",
1665*de2caf28SDavid du Colombier 	"	}	}",
1666*de2caf28SDavid du Colombier 	"",
1667*de2caf28SDavid du Colombier 	"	if (!h)",
1668*de2caf28SDavid du Colombier 	"	{	/* once created, the contents are never modified */",
1669*de2caf28SDavid du Colombier 	"		h = (EV_Hold *) sh_malloc((ulong)sizeof(EV_Hold));",
1670*de2caf28SDavid du Colombier 	"		h->owner = who_am_i;",
1671*de2caf28SDavid du Colombier 	"		h->sz = n;",
1672*de2caf28SDavid du Colombier 	"		h->nrpr = now._nr_pr;",
1673*de2caf28SDavid du Colombier 	"		h->nrqs = now._nr_qs;",
1674*de2caf28SDavid du Colombier 	"#if !defined(NOCOMP) && !defined(HC) && NRUNS>0",
1675*de2caf28SDavid du Colombier 	"		h->sv = (char *) Mask;	/* in shared memory, and never modified */",
1676*de2caf28SDavid du Colombier 	"#endif",
1677*de2caf28SDavid du Colombier 	"#if NRUNS>0 && !defined(TRIX)",
1678*de2caf28SDavid du Colombier 	"		if (now._nr_pr > 0)",
1679*de2caf28SDavid du Colombier 	"		{	h->ps = (char *) proc_skip;",
1680*de2caf28SDavid du Colombier 	"			h->po = (char *) proc_offset;",
1681*de2caf28SDavid du Colombier 	"		}",
1682*de2caf28SDavid du Colombier 	"		if (now._nr_qs > 0)",
1683*de2caf28SDavid du Colombier 	"		{	h->qs = (char *) q_skip;",
1684*de2caf28SDavid du Colombier 	"			h->qo = (char *) q_offset;",
1685*de2caf28SDavid du Colombier 	"		}",
1686*de2caf28SDavid du Colombier 	"#endif",
1687*de2caf28SDavid du Colombier 	"		h->nxt = kept[n];",
1688*de2caf28SDavid du Colombier 	"		kept[n] = h;",
1689*de2caf28SDavid du Colombier 	"	}",
1690*de2caf28SDavid du Colombier 	"	return h;",
1691*de2caf28SDavid du Colombier 	"}",
1692*de2caf28SDavid du Colombier 	"#endif", /* NRUNS>0 */
1693*de2caf28SDavid du Colombier 	"BFS_Slot *",
1694*de2caf28SDavid du Colombier 	"bfs_pack_state(Trail *f, BFS_Trail *g, int search_depth, BFS_Slot *t)",
1695*de2caf28SDavid du Colombier 	"{",
1696*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
1697*de2caf28SDavid du Colombier 	"	assert(t->s_data != NULL);",
1698*de2caf28SDavid du Colombier 	"	assert(t->s_data->t_info != NULL);",
1699*de2caf28SDavid du Colombier 	"	assert(f || g);",
1700*de2caf28SDavid du Colombier 	"#endif",
1701*de2caf28SDavid du Colombier 	"	if (!g)",
1702*de2caf28SDavid du Colombier 	"	{	t->s_data->t_info->ostate = f->ostate;",
1703*de2caf28SDavid du Colombier 	"		t->s_data->t_info->st   = f->st;",
1704*de2caf28SDavid du Colombier 	"		t->s_data->t_info->o_tt = search_depth;",
1705*de2caf28SDavid du Colombier 	"		t->s_data->t_info->pr   = f->pr;",
1706*de2caf28SDavid du Colombier 	"		t->s_data->t_info->tau  = f->tau;",
1707*de2caf28SDavid du Colombier 	"		t->s_data->t_info->o_pm = f->o_pm;",
1708*de2caf28SDavid du Colombier 	"		if (f->o_t)",
1709*de2caf28SDavid du Colombier 	"		{	t->s_data->t_info->t_id = f->o_t->t_id;",
1710*de2caf28SDavid du Colombier 	"		} else",
1711*de2caf28SDavid du Colombier 	"		{	t->s_data->t_info->t_id = -1;",
1712*de2caf28SDavid du Colombier 	"			t->s_data->t_info->ostate = NULL;",
1713*de2caf28SDavid du Colombier 	"		}",
1714*de2caf28SDavid du Colombier 	"	} /* else t->s_data->t_info == g */",
1715*de2caf28SDavid du Colombier 	"#if SYNC",
1716*de2caf28SDavid du Colombier 	"	t->s_data->boq = boq;",
1717*de2caf28SDavid du Colombier 	"#endif",
1718*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
1719*de2caf28SDavid du Colombier 	"	{	static ulong u_cnt;",
1720*de2caf28SDavid du Colombier 	"		t->s_data->nr = u_cnt++;",
1721*de2caf28SDavid du Colombier 	"	}",
1722*de2caf28SDavid du Colombier 	"#endif",
1723*de2caf28SDavid du Colombier 	"#ifdef TRIX",
1724*de2caf28SDavid du Colombier 	"	sv_populate(); /* make sure now is up to date */",
1725*de2caf28SDavid du Colombier 	"#endif",
1726*de2caf28SDavid du Colombier 	"#ifndef BFS_DISK",
1727*de2caf28SDavid du Colombier 	"	{ 	SV_Hold *x = bfs_new_sv(vsize);",
1728*de2caf28SDavid du Colombier 	"		t->s_data->osv = x->sv;",
1729*de2caf28SDavid du Colombier 	"		x->sv = (State *) 0;",
1730*de2caf28SDavid du Colombier 	"		x->nxt = bfs_free_hold;",
1731*de2caf28SDavid du Colombier 	"		bfs_free_hold = x;",
1732*de2caf28SDavid du Colombier 	"	}",
1733*de2caf28SDavid du Colombier 	"#endif",
1734*de2caf28SDavid du Colombier 	"#if NRUNS>0",
1735*de2caf28SDavid du Colombier 	"	t->s_data->omask = bfs_new_sv_mask(vsize);",
1736*de2caf28SDavid du Colombier 	"#endif",
1737*de2caf28SDavid du Colombier 	"",
1738*de2caf28SDavid du Colombier 	"#if defined(Q_PROVISO) && !defined(BITSTATE) && !defined(NOREDUCE)",
1739*de2caf28SDavid du Colombier 	"	t->s_data->lstate = Lstate;	/* Lstate is set in o_store or h_store */",
1740*de2caf28SDavid du Colombier 	"#endif",
1741*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
1742*de2caf28SDavid du Colombier 	"	t->type = STATE;",
1743*de2caf28SDavid du Colombier 	"#endif",
1744*de2caf28SDavid du Colombier 	"	return t;",
1745*de2caf28SDavid du Colombier 	"}",
1746*de2caf28SDavid du Colombier 	"",
1747*de2caf28SDavid du Colombier 	"void",
1748*de2caf28SDavid du Colombier 	"bfs_store_state(Trail *t, short oboq)",
1749*de2caf28SDavid du Colombier 	"{",
1750*de2caf28SDavid du Colombier 	"#ifdef TRIX",
1751*de2caf28SDavid du Colombier 	"	sv_populate();",
1752*de2caf28SDavid du Colombier 	"#endif",
1753*de2caf28SDavid du Colombier 	"#if defined(VERI) && defined(Q_PROVISO) && !defined(BITSTATE) && defined(FULLSTACK)",
1754*de2caf28SDavid du Colombier 	"	if (!(t->tau&4)",	/* prog move */
1755*de2caf28SDavid du Colombier 	"	&&    t->ostate)",	/* not initial state */
1756*de2caf28SDavid du Colombier 	"	{	t->tau |= ((BFS_Trail *) t->ostate)->tau&64;",
1757*de2caf28SDavid du Colombier 	"	}	/* lift 64 across claim moves */",
1758*de2caf28SDavid du Colombier 	"#endif",
1759*de2caf28SDavid du Colombier 	"",
1760*de2caf28SDavid du Colombier 	"#ifdef BFS_SEP_HASH",
1761*de2caf28SDavid du Colombier 	"	#if SYNC",
1762*de2caf28SDavid du Colombier 	"	if (boq == -1 && oboq != -1)	/* post-rv */",
1763*de2caf28SDavid du Colombier 	"	{	BFS_Trail *x =  (BFS_Trail *) trpt->ostate; /* pre-rv state */",
1764*de2caf28SDavid du Colombier 	"	 	if (x)",
1765*de2caf28SDavid du Colombier 	"		{	x->o_pm |= 4;	/* rv complete */",
1766*de2caf28SDavid du Colombier 	"	}	}",
1767*de2caf28SDavid du Colombier 	"	#endif",
1768*de2caf28SDavid du Colombier 	"	d_sfh((uchar *)&now, (int) vsize); /* sep-hash -- sets K1 -- overkill */",
1769*de2caf28SDavid du Colombier 	"	bfs_keep_state = K1%%Cores + 1;",
1770*de2caf28SDavid du Colombier 	"	bfs_push_state(t, NULL, trpt->o_tt+1);	/* bfs_store_state - sep_hash */",
1771*de2caf28SDavid du Colombier 	"	bfs_keep_state = 0;",
1772*de2caf28SDavid du Colombier 	"#else",
1773*de2caf28SDavid du Colombier 	"	#ifdef VERI",
1774*de2caf28SDavid du Colombier #if 0
1775*de2caf28SDavid du Colombier 		in VERI mode store the state when
1776*de2caf28SDavid du Colombier 		(!t->ostate || (t->tau&4)) in initial state and after each program move
1777*de2caf28SDavid du Colombier 
1778*de2caf28SDavid du Colombier 		i.e., dont store when !(!t->ostate || (t->tau&4)) = (t->ostate && !(t->tau&4))
1779*de2caf28SDavid du Colombier 		the *first* time that the tau flag is not set:
1780*de2caf28SDavid du Colombier 		possibly after a series of claim moves in an atomic sequence
1781*de2caf28SDavid du Colombier #endif
1782*de2caf28SDavid du Colombier 	"		if (!(t->tau&4) && t->ostate && (((BFS_Trail *)t->ostate)->tau&4))",
1783*de2caf28SDavid du Colombier 	"		{	/* do not store intermediate state */",
1784*de2caf28SDavid du Colombier 	"		#if defined(VERBOSE) && defined(L_BOUND)",
1785*de2caf28SDavid du Colombier 	"			bfs_printf(\"Un-Stored state bnd %%d -- sds %%p\\n\",",
1786*de2caf28SDavid du Colombier 	"				now._l_bnd, now._l_sds);",
1787*de2caf28SDavid du Colombier 	"		#endif",
1788*de2caf28SDavid du Colombier 	"			bfs_push_state(t, NULL, trpt->o_tt+1);	/* claim move */",
1789*de2caf28SDavid du Colombier 	"		} else",
1790*de2caf28SDavid du Colombier 	"	#endif",
1791*de2caf28SDavid du Colombier 	"		if (!bfs_do_store((char *)&now, vsize))	/* includes bfs_visited */",
1792*de2caf28SDavid du Colombier 	"		{	nstates++;			/* local count */",
1793*de2caf28SDavid du Colombier 	"			trpt->tau |= 64;		/* bfs: succ outside stack */",
1794*de2caf28SDavid du Colombier 	"	#if SYNC",
1795*de2caf28SDavid du Colombier 	"			if (boq == -1 && oboq != -1)	/* post-rv */",
1796*de2caf28SDavid du Colombier 	"			{	BFS_Trail *x = ",
1797*de2caf28SDavid du Colombier 	"			  	(BFS_Trail *) trpt->ostate; /* pre-rv state */",
1798*de2caf28SDavid du Colombier 	"			  	if (x)",
1799*de2caf28SDavid du Colombier 	"				{	x->o_pm |= 4;	/* rv complete */",
1800*de2caf28SDavid du Colombier 	"			}	}",
1801*de2caf28SDavid du Colombier 	"	#endif",
1802*de2caf28SDavid du Colombier 	"			bfs_push_state(t, NULL, trpt->o_tt+1);	/* successor */",
1803*de2caf28SDavid du Colombier 	"		} else",
1804*de2caf28SDavid du Colombier 	"		{	truncs++;",
1805*de2caf28SDavid du Colombier 	"	#ifdef BFS_CHECK",
1806*de2caf28SDavid du Colombier 	"			bfs_printf(\"seen before\\n\");",
1807*de2caf28SDavid du Colombier 	"	#endif",
1808*de2caf28SDavid du Colombier 	"	#if defined(Q_PROVISO) && !defined(BITSTATE) && defined(FULLSTACK)",
1809*de2caf28SDavid du Colombier 	"		#ifdef USE_TDH",
1810*de2caf28SDavid du Colombier 	"			if (Lstate)",	/* if BFS_INQ is set */
1811*de2caf28SDavid du Colombier 	"			{	trpt->tau |= 64;",
1812*de2caf28SDavid du Colombier 	"			}",
1813*de2caf28SDavid du Colombier 	"		#else",
1814*de2caf28SDavid du Colombier 	"			if (Lstate && Lstate->tagged)	/* bfs_store_state */",
1815*de2caf28SDavid du Colombier 	"			{	trpt->tau |= 64;",
1816*de2caf28SDavid du Colombier 	"			}",
1817*de2caf28SDavid du Colombier 	"		#endif",
1818*de2caf28SDavid du Colombier 	"	#endif",
1819*de2caf28SDavid du Colombier 	"		}",
1820*de2caf28SDavid du Colombier 	"#endif",
1821*de2caf28SDavid du Colombier 	"}",
1822*de2caf28SDavid du Colombier 	"",
1823*de2caf28SDavid du Colombier 	"/*** support routines ***/",
1824*de2caf28SDavid du Colombier 	"",
1825*de2caf28SDavid du Colombier 	"void",
1826*de2caf28SDavid du Colombier 	"bfs_clear_locks(void)",
1827*de2caf28SDavid du Colombier 	"{	int i;",
1828*de2caf28SDavid du Colombier 	"",
1829*de2caf28SDavid du Colombier 	"	/* clear any locks held by this process only */",
1830*de2caf28SDavid du Colombier 	"	if (shared_memory)",
1831*de2caf28SDavid du Colombier 	"	for (i = 0; i < BFS_MAXLOCKS; i++)",
1832*de2caf28SDavid du Colombier 	"	{	if (shared_memory->sh_owner[i] == who_am_i + 1)",
1833*de2caf28SDavid du Colombier 	"		{	shared_memory->sh_locks[i] = 0;",
1834*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
1835*de2caf28SDavid du Colombier 	"			shared_memory->in_count[i] = 0;",
1836*de2caf28SDavid du Colombier 	"#endif",
1837*de2caf28SDavid du Colombier 	"			shared_memory->sh_owner[i] = 0;",
1838*de2caf28SDavid du Colombier 	"	}	}",
1839*de2caf28SDavid du Colombier 	"}",
1840*de2caf28SDavid du Colombier 	"",
1841*de2caf28SDavid du Colombier 	"void",
1842*de2caf28SDavid du Colombier 	"e_critical(int which)",
1843*de2caf28SDavid du Colombier 	"{	int w;",
1844*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
1845*de2caf28SDavid du Colombier 	"	assert(which >= 0 && which < BFS_MAXLOCKS);",
1846*de2caf28SDavid du Colombier 	"#endif",
1847*de2caf28SDavid du Colombier 	"	if (shared_memory == NULL) return;",
1848*de2caf28SDavid du Colombier 	"	while (tas(&(shared_memory->sh_locks[which])) != 0)",
1849*de2caf28SDavid du Colombier 	"	{	w = shared_memory->sh_owner[which]; /* sh_locks[which] could be 0 by now */",
1850*de2caf28SDavid du Colombier 	"		assert(w >= 0 && w <= BFS_MAXPROCS);",
1851*de2caf28SDavid du Colombier 	"		if (w > 0 && shared_memory->bfs_flag[w-1] == 2)",
1852*de2caf28SDavid du Colombier 	"		{	/* multiple processes can get here; only one should do this: */",
1853*de2caf28SDavid du Colombier 	"			if (tas(&(shared_memory->bfs_data[w - 1].override)) == 0)",
1854*de2caf28SDavid du Colombier 	"			{	fprintf(stderr, \"cpu%%02d: override lock %%d - held by %%d\\n\",",
1855*de2caf28SDavid du Colombier 	"				who_am_i, which, shared_memory->sh_owner[which]);",
1856*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
1857*de2caf28SDavid du Colombier 	"				shared_memory->in_count[which] = 0;",
1858*de2caf28SDavid du Colombier 	"#endif",
1859*de2caf28SDavid du Colombier 	"				shared_memory->sh_locks[which] = 0;",
1860*de2caf28SDavid du Colombier 	"				shared_memory->sh_owner[which] = 0;",
1861*de2caf28SDavid du Colombier 	"		}	}",
1862*de2caf28SDavid du Colombier 	"		shared_memory->wait_count[which]++; /* not atomic of course */",
1863*de2caf28SDavid du Colombier 	"	}",
1864*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
1865*de2caf28SDavid du Colombier 	"	if (shared_memory->in_count[which] != 0)",
1866*de2caf28SDavid du Colombier 	"	{	fprintf(stderr, \"cpu%%02d: cannot happen lock %%d count %%d\\n\", who_am_i,",
1867*de2caf28SDavid du Colombier 	"			which, shared_memory->in_count[which]);",
1868*de2caf28SDavid du Colombier 	"	}",
1869*de2caf28SDavid du Colombier 	"	shared_memory->in_count[which]++;",
1870*de2caf28SDavid du Colombier 	"#endif",
1871*de2caf28SDavid du Colombier 	"	shared_memory->sh_owner[which] = who_am_i+1;",
1872*de2caf28SDavid du Colombier 	"}",
1873*de2caf28SDavid du Colombier 	"",
1874*de2caf28SDavid du Colombier 	"void",
1875*de2caf28SDavid du Colombier 	"x_critical(int which)",
1876*de2caf28SDavid du Colombier 	"{",
1877*de2caf28SDavid du Colombier 	"	if (shared_memory == NULL) return;",
1878*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
1879*de2caf28SDavid du Colombier 	"	assert(shared_memory->in_count[which] == 1);",
1880*de2caf28SDavid du Colombier 	"	shared_memory->in_count[which] = 0;",
1881*de2caf28SDavid du Colombier 	"#endif",
1882*de2caf28SDavid du Colombier 	"	shared_memory->sh_locks[which] = 0;",
1883*de2caf28SDavid du Colombier 	"	shared_memory->sh_owner[which] = 0;",
1884*de2caf28SDavid du Colombier 	"}",
1885*de2caf28SDavid du Colombier 	"",
1886*de2caf28SDavid du Colombier 	"void",
1887*de2caf28SDavid du Colombier 	"bfs_printf(const char *fmt, ...)",
1888*de2caf28SDavid du Colombier 	"{	va_list args;",
1889*de2caf28SDavid du Colombier 	"",
1890*de2caf28SDavid du Colombier 	"	e_critical(BFS_PRINT);",
1891*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
1892*de2caf28SDavid du Colombier 	"	if (1) { int i=who_am_i; while (i-- > 0) printf(\"  \"); }",
1893*de2caf28SDavid du Colombier 	"#endif",
1894*de2caf28SDavid du Colombier 	"	printf(\"cpu%%02d: \", who_am_i);",
1895*de2caf28SDavid du Colombier 	"	va_start(args, fmt);",
1896*de2caf28SDavid du Colombier 	"	vprintf(fmt, args);",
1897*de2caf28SDavid du Colombier 	"	va_end(args);",
1898*de2caf28SDavid du Colombier 	"	fflush(stdout);",
1899*de2caf28SDavid du Colombier 	"	x_critical(BFS_PRINT);",
1900*de2caf28SDavid du Colombier 	"}",
1901*de2caf28SDavid du Colombier 	"",
1902*de2caf28SDavid du Colombier 	"int",
1903*de2caf28SDavid du Colombier 	"bfs_all_idle(void)",
1904*de2caf28SDavid du Colombier 	"{	int i;",
1905*de2caf28SDavid du Colombier 	"",
1906*de2caf28SDavid du Colombier 	"	if (shared_memory)",
1907*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
1908*de2caf28SDavid du Colombier 	"	{	if (shared_memory->bfs_flag[i] == 0",
1909*de2caf28SDavid du Colombier 	"		&&  shared_memory->bfs_idle[i] == 0)",
1910*de2caf28SDavid du Colombier 	"		{	return 0;",
1911*de2caf28SDavid du Colombier 	"	}	}",
1912*de2caf28SDavid du Colombier 	"	return 1;",
1913*de2caf28SDavid du Colombier 	"}",
1914*de2caf28SDavid du Colombier 	"",
1915*de2caf28SDavid du Colombier 	"#ifdef BFS_FIFO",
1916*de2caf28SDavid du Colombier 	"int",
1917*de2caf28SDavid du Colombier 	"bfs_idle_and_empty(void)",
1918*de2caf28SDavid du Colombier 	"{	int p;	/* read-only */",
1919*de2caf28SDavid du Colombier 	"	for (p = 0; p < Cores; p++)",
1920*de2caf28SDavid du Colombier 	"	{	if (shared_memory->bfs_flag[p] == 0",
1921*de2caf28SDavid du Colombier 	"		&&  shared_memory->bfs_idle[p] == 0)",
1922*de2caf28SDavid du Colombier 	"		{	return 0;",
1923*de2caf28SDavid du Colombier 	"	}	}",
1924*de2caf28SDavid du Colombier 	"	for (p = 0; p < Cores; p++)",
1925*de2caf28SDavid du Colombier 	"	{	if (bfs_empty(p) < Cores)",
1926*de2caf28SDavid du Colombier 	"		{	return 0;",
1927*de2caf28SDavid du Colombier 	"	}	}",
1928*de2caf28SDavid du Colombier 	"	return 1;",
1929*de2caf28SDavid du Colombier 	"}",
1930*de2caf28SDavid du Colombier 	"#endif",
1931*de2caf28SDavid du Colombier 	"",
1932*de2caf28SDavid du Colombier 	"void",
1933*de2caf28SDavid du Colombier 	"bfs_set_toggle(void)	/* executed by root */",
1934*de2caf28SDavid du Colombier 	"{	int i;",
1935*de2caf28SDavid du Colombier 	"",
1936*de2caf28SDavid du Colombier 	"	if (shared_memory)",
1937*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
1938*de2caf28SDavid du Colombier 	"	{	shared_memory->bfs_idle[i] = 0;",
1939*de2caf28SDavid du Colombier 	"	}",
1940*de2caf28SDavid du Colombier 	"}",
1941*de2caf28SDavid du Colombier 	"",
1942*de2caf28SDavid du Colombier 	"int",
1943*de2caf28SDavid du Colombier 	"bfs_all_running(void)	/* crash detection */",
1944*de2caf28SDavid du Colombier 	"{	int i;",
1945*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
1946*de2caf28SDavid du Colombier 	"	{	if (!shared_memory || shared_memory->bfs_flag[i] > 1)",
1947*de2caf28SDavid du Colombier 	"		{	return 0;",
1948*de2caf28SDavid du Colombier 	"	}	}",
1949*de2caf28SDavid du Colombier 	"	return 1;",
1950*de2caf28SDavid du Colombier 	"}",
1951*de2caf28SDavid du Colombier 	"",
1952*de2caf28SDavid du Colombier 	"void",
1953*de2caf28SDavid du Colombier 	"bfs_mark_done(int code)",
1954*de2caf28SDavid du Colombier 	"{",
1955*de2caf28SDavid du Colombier 	"	if (shared_memory)",
1956*de2caf28SDavid du Colombier 	"	{	shared_memory->bfs_flag[who_am_i] = (int) code;",
1957*de2caf28SDavid du Colombier 	"		shared_memory->quit = 1;",
1958*de2caf28SDavid du Colombier 	"	}",
1959*de2caf28SDavid du Colombier 	"}",
1960*de2caf28SDavid du Colombier 	"",
1961*de2caf28SDavid du Colombier 	"static uchar *",
1962*de2caf28SDavid du Colombier 	"bfs_offset(int c)",
1963*de2caf28SDavid du Colombier 	"{	int   p, N;",
1964*de2caf28SDavid du Colombier 	"#ifdef COLLAPSE",
1965*de2caf28SDavid du Colombier 	"	uchar *q = (uchar *) ncomps; /* it is the first object allocated */",
1966*de2caf28SDavid du Colombier 	"	q += (256+2) * sizeof(ulong); /* preserve contents of ncomps */",
1967*de2caf28SDavid du Colombier 	"#else",
1968*de2caf28SDavid du Colombier 	"	uchar *q = (uchar *) &(shared_memory->allocator);",
1969*de2caf28SDavid du Colombier 	"#endif",
1970*de2caf28SDavid du Colombier 	"	/* _NP_+1 proctypes, reachability info:",
1971*de2caf28SDavid du Colombier 	"	 * reached[x : 0 .. _NP_+1][ 0 .. NrStates[x] ]",
1972*de2caf28SDavid du Colombier 	"	 */",
1973*de2caf28SDavid du Colombier 	"	for (p = N = 0; p <= _NP_; p++)",
1974*de2caf28SDavid du Colombier 	"	{	N += NrStates[p];	/* sum for all proctypes */",
1975*de2caf28SDavid du Colombier 	"	}",
1976*de2caf28SDavid du Colombier 	"",
1977*de2caf28SDavid du Colombier 	"	/* space needed per proctype: N bytes */",
1978*de2caf28SDavid du Colombier 	"	/* rounded up to a multiple of the word size */",
1979*de2caf28SDavid du Colombier 	"	if ((N%%sizeof(void *)) != 0)	/* aligned */",
1980*de2caf28SDavid du Colombier 	"	{	N += sizeof(void *) - (N%%sizeof(void *));",
1981*de2caf28SDavid du Colombier 	"	}",
1982*de2caf28SDavid du Colombier 	"",
1983*de2caf28SDavid du Colombier 	"	q += ((c - 1) * (_NP_ + 1) * N);",
1984*de2caf28SDavid du Colombier 	"	return q;",
1985*de2caf28SDavid du Colombier 	"}",
1986*de2caf28SDavid du Colombier 	"",
1987*de2caf28SDavid du Colombier 	"static void",
1988*de2caf28SDavid du Colombier 	"bfs_putreached(void)",
1989*de2caf28SDavid du Colombier 	"{	uchar *q;",
1990*de2caf28SDavid du Colombier 	"	int p;",
1991*de2caf28SDavid du Colombier 	"",
1992*de2caf28SDavid du Colombier 	"	assert(who_am_i > 0);",
1993*de2caf28SDavid du Colombier 	"",
1994*de2caf28SDavid du Colombier 	"	q = bfs_offset(who_am_i);",
1995*de2caf28SDavid du Colombier 	"	for (p = 0; p <= _NP_; p++)",
1996*de2caf28SDavid du Colombier 	"	{	memcpy((void *) q, (const void *) reached[p], (size_t) NrStates[p]);",
1997*de2caf28SDavid du Colombier 	"		q += NrStates[p];",
1998*de2caf28SDavid du Colombier 	"	}",
1999*de2caf28SDavid du Colombier 	"}",
2000*de2caf28SDavid du Colombier 	"",
2001*de2caf28SDavid du Colombier 	"static void",
2002*de2caf28SDavid du Colombier 	"bfs_getreached(int c)",
2003*de2caf28SDavid du Colombier 	"{	uchar *q;",
2004*de2caf28SDavid du Colombier 	"	int p, i;",
2005*de2caf28SDavid du Colombier 	"",
2006*de2caf28SDavid du Colombier 	"	assert(who_am_i == 0 && c >= 1 && c < Cores);",
2007*de2caf28SDavid du Colombier 	"",
2008*de2caf28SDavid du Colombier 	"	q = (uchar *) bfs_offset(c);",
2009*de2caf28SDavid du Colombier 	"	for (p = 0; p <= _NP_; p++)",
2010*de2caf28SDavid du Colombier 	"	for (i = 0; i < NrStates[p]; i++)",
2011*de2caf28SDavid du Colombier 	"	{	reached[p][i] += *q++; /* update local copy */",
2012*de2caf28SDavid du Colombier 	"	}",
2013*de2caf28SDavid du Colombier 	"}",
2014*de2caf28SDavid du Colombier 	"",
2015*de2caf28SDavid du Colombier 	"void",
2016*de2caf28SDavid du Colombier 	"bfs_update(void)",
2017*de2caf28SDavid du Colombier 	"{	int i;",
2018*de2caf28SDavid du Colombier 	"	volatile BFS_data *s;",
2019*de2caf28SDavid du Colombier 	"",
2020*de2caf28SDavid du Colombier 	"	if (!shared_memory) return;",
2021*de2caf28SDavid du Colombier 	"",
2022*de2caf28SDavid du Colombier 	"	s = &shared_memory->bfs_data[who_am_i];",
2023*de2caf28SDavid du Colombier 	"	if (who_am_i == 0)",
2024*de2caf28SDavid du Colombier 	"	{	shared_memory->bfs_flag[who_am_i] = 3; /* or else others don't stop */",
2025*de2caf28SDavid du Colombier 	"		bfs_gcount = 0;",
2026*de2caf28SDavid du Colombier 	"		for (i = 1; i < Cores; i++) /* start at 1 not 0 */",
2027*de2caf28SDavid du Colombier 	"		{	while (shared_memory->bfs_flag[i] == 0)",
2028*de2caf28SDavid du Colombier 	"			{	sleep(1);",
2029*de2caf28SDavid du Colombier 	"				if (bfs_gcount++ > WAIT_MAX)	/* excessively long wait */",
2030*de2caf28SDavid du Colombier 	"				{	printf(\"cpu00: give up waiting for cpu%%2d (%%d cores)\\n\", i, Cores);",
2031*de2caf28SDavid du Colombier 	"					bfs_gcount = 0;",
2032*de2caf28SDavid du Colombier 	"					break;",
2033*de2caf28SDavid du Colombier 	"			}	}",
2034*de2caf28SDavid du Colombier 	"			s = &shared_memory->bfs_data[i];",
2035*de2caf28SDavid du Colombier 	"			mreached     = Max(mreached, s->mreached);",
2036*de2caf28SDavid du Colombier 	"			hmax = vsize = Max(vsize,    s->vsize);",
2037*de2caf28SDavid du Colombier 	"			errors   += s->errors;",
2038*de2caf28SDavid du Colombier 	"			memcnt   += s->memcnt;",
2039*de2caf28SDavid du Colombier 	"			nstates  += s->nstates;",
2040*de2caf28SDavid du Colombier 	"			nlinks   += s->nlinks;",
2041*de2caf28SDavid du Colombier 	"			truncs   += s->truncs;",
2042*de2caf28SDavid du Colombier 	"			bfs_left += s->memory_left;",
2043*de2caf28SDavid du Colombier 	"			bfs_punt += s->punted;",
2044*de2caf28SDavid du Colombier 	"			bfs_getreached(i);",
2045*de2caf28SDavid du Colombier 	"		}",
2046*de2caf28SDavid du Colombier 	"	} else",
2047*de2caf28SDavid du Colombier 	"	{	s->mreached = (ulong) mreached;",
2048*de2caf28SDavid du Colombier 	"		s->vsize    = (ulong) vsize;",
2049*de2caf28SDavid du Colombier 	"		s->errors   = (int) errors;",
2050*de2caf28SDavid du Colombier 	"		s->memcnt   = (double) memcnt;",
2051*de2caf28SDavid du Colombier 	"		s->nstates  = (double) nstates;",
2052*de2caf28SDavid du Colombier 	"		s->nlinks   = (double) nlinks;",
2053*de2caf28SDavid du Colombier 	"		s->truncs   = (double) truncs;",
2054*de2caf28SDavid du Colombier 	"		s->memory_left = (ulong) bfs_left;",
2055*de2caf28SDavid du Colombier 	"		s->punted      = (ulong) bfs_punt;",
2056*de2caf28SDavid du Colombier 	"		bfs_putreached();",
2057*de2caf28SDavid du Colombier 	"	}",
2058*de2caf28SDavid du Colombier 	"}",
2059*de2caf28SDavid du Colombier 	"",
2060*de2caf28SDavid du Colombier 	"volatile uchar *",
2061*de2caf28SDavid du Colombier 	"sh_pre_malloc(ulong n)	/* used before the local heaps are populated */",
2062*de2caf28SDavid du Colombier 	"{	volatile uchar *ptr = NULL;",
2063*de2caf28SDavid du Colombier 	"",
2064*de2caf28SDavid du Colombier 	"	assert(!bfs_runs);",
2065*de2caf28SDavid du Colombier 	"	if ((n%%sizeof(void *)) != 0)",
2066*de2caf28SDavid du Colombier 	"	{	n += sizeof(void *) - (n%%sizeof(void *));",
2067*de2caf28SDavid du Colombier 	"		assert((n%%sizeof(void *)) == 0);",
2068*de2caf28SDavid du Colombier 	"	}",
2069*de2caf28SDavid du Colombier 	"",
2070*de2caf28SDavid du Colombier 	"	e_critical(BFS_MEM);	/* needed? */",
2071*de2caf28SDavid du Colombier 	"		if (shared_memory->mem_left < n + 7)", /* 7 for possible alignment */
2072*de2caf28SDavid du Colombier 	"		{	x_critical(BFS_MEM);",
2073*de2caf28SDavid du Colombier 	"			bfs_printf(\"want %%lu, have %%lu\\n\",",
2074*de2caf28SDavid du Colombier 	"				n, shared_memory->mem_left);",
2075*de2caf28SDavid du Colombier 	"			bfs_shutdown(\"out of shared memory\");",
2076*de2caf28SDavid du Colombier 	"			assert(0); /* should be unreachable */",
2077*de2caf28SDavid du Colombier 	"		}",
2078*de2caf28SDavid du Colombier 	"		ptr = shared_memory->allocator;",
2079*de2caf28SDavid du Colombier 	"#if WS>4", /* align to 8 byte boundary */
2080*de2caf28SDavid du Colombier 	"		{	int b = (int) ((uint64_t) ptr)&7;",
2081*de2caf28SDavid du Colombier 	"			if (b != 0)",
2082*de2caf28SDavid du Colombier 	"			{	ptr += (8-b);",
2083*de2caf28SDavid du Colombier 	"				shared_memory->allocator = ptr;",
2084*de2caf28SDavid du Colombier 	"		}	}",
2085*de2caf28SDavid du Colombier 	"#endif",
2086*de2caf28SDavid du Colombier 	"		shared_memory->allocator += n;",
2087*de2caf28SDavid du Colombier 	"		shared_memory->mem_left -= n;",
2088*de2caf28SDavid du Colombier 	"	x_critical(BFS_MEM);",
2089*de2caf28SDavid du Colombier 	"",
2090*de2caf28SDavid du Colombier 	"	bfs_pre_allocated += n;",
2091*de2caf28SDavid du Colombier 	"",
2092*de2caf28SDavid du Colombier 	"	return ptr;",
2093*de2caf28SDavid du Colombier 	"}",
2094*de2caf28SDavid du Colombier 	"",
2095*de2caf28SDavid du Colombier 	"volatile uchar *",
2096*de2caf28SDavid du Colombier 	"sh_malloc(ulong n)",
2097*de2caf28SDavid du Colombier 	"{	volatile uchar *ptr = NULL;",
2098*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
2099*de2caf28SDavid du Colombier 	"	assert(bfs_runs);",
2100*de2caf28SDavid du Colombier 	"#endif",
2101*de2caf28SDavid du Colombier 	"	if ((n%%sizeof(void *)) != 0)",
2102*de2caf28SDavid du Colombier 	"	{	n += sizeof(void *) - (n%%sizeof(void *));",
2103*de2caf28SDavid du Colombier 	"#ifdef BFS_CHECK",
2104*de2caf28SDavid du Colombier 	"		assert((n%%sizeof(void *)) == 0);",
2105*de2caf28SDavid du Colombier 	"#endif",
2106*de2caf28SDavid du Colombier 	"	}",
2107*de2caf28SDavid du Colombier 	"",
2108*de2caf28SDavid du Colombier 	"	/* local heap -- no locks needed */",
2109*de2caf28SDavid du Colombier 	"	if (bfs_left < n)",
2110*de2caf28SDavid du Colombier 	"	{	e_critical(BFS_MEM);",
2111*de2caf28SDavid du Colombier 	"		if (shared_memory->mem_left >= n)",
2112*de2caf28SDavid du Colombier 	"		{	ptr = (uchar *) shared_memory->allocator;",
2113*de2caf28SDavid du Colombier 	"			shared_memory->allocator += n;",
2114*de2caf28SDavid du Colombier 	"			shared_memory->mem_left  -= n;",
2115*de2caf28SDavid du Colombier 	"			x_critical(BFS_MEM);",
2116*de2caf28SDavid du Colombier 	"			return ptr;",
2117*de2caf28SDavid du Colombier 	"		}",
2118*de2caf28SDavid du Colombier 	"		x_critical(BFS_MEM);",
2119*de2caf28SDavid du Colombier 	"#ifdef BFS_LOGMEM",
2120*de2caf28SDavid du Colombier 	"		int i;",
2121*de2caf28SDavid du Colombier 	"		e_critical(BFS_MEM);",
2122*de2caf28SDavid du Colombier 	"		for (i = 0; i < 1024; i++)",
2123*de2caf28SDavid du Colombier 	"		{	if (shared_memory->logmem[i] > 0)",
2124*de2caf28SDavid du Colombier 	"			{	bfs_printf(\"\tlog[%%d]\t%%d\\n\", i, shared_memory->logmem[i]);",
2125*de2caf28SDavid du Colombier 	"		}	}",
2126*de2caf28SDavid du Colombier 	"		x_critical(BFS_MEM);",
2127*de2caf28SDavid du Colombier 	"#endif",
2128*de2caf28SDavid du Colombier 	"		bfs_shutdown(\"out of shared memory\"); /* no return */",
2129*de2caf28SDavid du Colombier 	"	}",
2130*de2caf28SDavid du Colombier 	"#ifdef BFS_LOGMEM",
2131*de2caf28SDavid du Colombier 	"	e_critical(BFS_MEM);",
2132*de2caf28SDavid du Colombier 	"	if (n < 1023)",
2133*de2caf28SDavid du Colombier 	"	{	shared_memory->logmem[n]++;",
2134*de2caf28SDavid du Colombier 	"	} else",
2135*de2caf28SDavid du Colombier 	"	{	shared_memory->logmem[1023]++;",
2136*de2caf28SDavid du Colombier 	"	}",
2137*de2caf28SDavid du Colombier 	"	x_critical(BFS_MEM);",
2138*de2caf28SDavid du Colombier 	"#endif",
2139*de2caf28SDavid du Colombier 	"	ptr = (uchar *) bfs_heap;",
2140*de2caf28SDavid du Colombier 	"	bfs_heap += n;",
2141*de2caf28SDavid du Colombier 	"	bfs_left -= n;",
2142*de2caf28SDavid du Colombier 	"",
2143*de2caf28SDavid du Colombier 	"	if (0) printf(\"sh_malloc %%ld\\n\", n);",
2144*de2caf28SDavid du Colombier 	"	return ptr;",
2145*de2caf28SDavid du Colombier 	"}",
2146*de2caf28SDavid du Colombier 	"",
2147*de2caf28SDavid du Colombier 	"volatile uchar *",
2148*de2caf28SDavid du Colombier 	"bfs_get_shared_mem(key_t key, size_t n)",
2149*de2caf28SDavid du Colombier 	"{	char *rval;",
2150*de2caf28SDavid du Colombier 	"",
2151*de2caf28SDavid du Colombier 	"	assert(who_am_i == 0);",
2152*de2caf28SDavid du Colombier 	"",
2153*de2caf28SDavid du Colombier 	"	shared_mem_id = shmget(key, n, 0600 | IPC_CREAT | IPC_EXCL);	/* create */",
2154*de2caf28SDavid du Colombier 	"	if (shared_mem_id == -1)",
2155*de2caf28SDavid du Colombier 	"	{	fprintf(stderr, \"cpu%%02d: tried to get %%d MB of shared memory\\n\",",
2156*de2caf28SDavid du Colombier 	"			who_am_i, (int) n/(1024*1024));",
2157*de2caf28SDavid du Colombier 	"		perror(\"shmget\");",
2158*de2caf28SDavid du Colombier 	"		exit(1);",
2159*de2caf28SDavid du Colombier 	"	}",
2160*de2caf28SDavid du Colombier 	"	if ((rval = (char *) shmat(shared_mem_id, (void *) 0, 0)) == (char *) -1) /* attach */",
2161*de2caf28SDavid du Colombier 	"	{	perror(\"shmat\");",
2162*de2caf28SDavid du Colombier 	"		exit(1);",
2163*de2caf28SDavid du Colombier 	"	}",
2164*de2caf28SDavid du Colombier 	"	return (uchar *) rval;",
2165*de2caf28SDavid du Colombier 	"}",
2166*de2caf28SDavid du Colombier 	"",
2167*de2caf28SDavid du Colombier 	"void",
2168*de2caf28SDavid du Colombier 	"bfs_drop_shared_memory(void)",
2169*de2caf28SDavid du Colombier 	"{",
2170*de2caf28SDavid du Colombier 	"	if (who_am_i == 0)",
2171*de2caf28SDavid du Colombier 	"	{	printf(\"pan: releasing shared memory...\");",
2172*de2caf28SDavid du Colombier 	"		fflush(stdout);",
2173*de2caf28SDavid du Colombier 	"	}",
2174*de2caf28SDavid du Colombier 	"	if (shared_memory)",
2175*de2caf28SDavid du Colombier 	"	{	shmdt(shared_memory);					/* detach */",
2176*de2caf28SDavid du Colombier 	"		if (who_am_i == 0)",
2177*de2caf28SDavid du Colombier 	"		{	shmctl(shared_mem_id, IPC_RMID, (void *) 0);	/* remove */",
2178*de2caf28SDavid du Colombier 	"	}	}",
2179*de2caf28SDavid du Colombier 	"	if (who_am_i == 0)",
2180*de2caf28SDavid du Colombier 	"	{	printf(\"done\\n\");",
2181*de2caf28SDavid du Colombier 	"		fflush(stdout);",
2182*de2caf28SDavid du Colombier 	"	}",
2183*de2caf28SDavid du Colombier 	"}",
2184*de2caf28SDavid du Colombier 	"",
2185*de2caf28SDavid du Colombier 	"size_t",
2186*de2caf28SDavid du Colombier 	"bfs_find_largest(key_t key)",
2187*de2caf28SDavid du Colombier 	"{	size_t n;",
2188*de2caf28SDavid du Colombier 	"	const size_t delta = 32*1024*1024;",
2189*de2caf28SDavid du Colombier 	"	int temp_id = -1;",
2190*de2caf28SDavid du Colombier 	"	int atleastonce = 0;",
2191*de2caf28SDavid du Colombier 	"",
2192*de2caf28SDavid du Colombier 	"	for (n = delta; ; n += delta)",
2193*de2caf28SDavid du Colombier 	"	{	if (WS <= 4 && n >= 1024*1024*1024)", /* was n >= INT_MAX */
2194*de2caf28SDavid du Colombier 	"		{	n = 1024*1024*1024;",
2195*de2caf28SDavid du Colombier 	"			break;",
2196*de2caf28SDavid du Colombier 	"		}",
2197*de2caf28SDavid du Colombier 	"#ifdef MEMLIM",
2198*de2caf28SDavid du Colombier 	"		if ((double) n > memlim)",
2199*de2caf28SDavid du Colombier 	"		{	n = (size_t) memlim;",
2200*de2caf28SDavid du Colombier 	"			break;",
2201*de2caf28SDavid du Colombier 	"		}",
2202*de2caf28SDavid du Colombier 	"#endif",
2203*de2caf28SDavid du Colombier 	"		temp_id = shmget(key, n, 0600);		/* check for stale copy */",
2204*de2caf28SDavid du Colombier 	"		if (temp_id != -1)",
2205*de2caf28SDavid du Colombier 	"		{	if (shmctl(temp_id, IPC_RMID, ((void *) 0)) < 0) /* remove */",
2206*de2caf28SDavid du Colombier 	"			{	perror(\"remove_segment_fails 2\");",
2207*de2caf28SDavid du Colombier 	"				exit(1);",
2208*de2caf28SDavid du Colombier 	"		}	}",
2209*de2caf28SDavid du Colombier 	"",
2210*de2caf28SDavid du Colombier 	"		temp_id = shmget(key, n, 0600 | IPC_CREAT | IPC_EXCL);	/* create new */",
2211*de2caf28SDavid du Colombier 	"		if (temp_id == -1)",
2212*de2caf28SDavid du Colombier 	"		{	n -= delta;",
2213*de2caf28SDavid du Colombier 	"			break;",
2214*de2caf28SDavid du Colombier 	"		} else",
2215*de2caf28SDavid du Colombier 	"		{	atleastonce++;",
2216*de2caf28SDavid du Colombier 	"			if (shmctl(temp_id, IPC_RMID, ((void *) 0)) < 0)",
2217*de2caf28SDavid du Colombier 	"			{	perror(\"remove_segment_fails 0\");",
2218*de2caf28SDavid du Colombier 	"				exit(1);",
2219*de2caf28SDavid du Colombier 	"	}	}	}",
2220*de2caf28SDavid du Colombier 	"",
2221*de2caf28SDavid du Colombier 	"	if (!atleastonce)",
2222*de2caf28SDavid du Colombier 	"	{	printf(\"cpu%%02d: no shared memory n=%%d\\n\", who_am_i, (int) n);",
2223*de2caf28SDavid du Colombier 	"		exit(1);",
2224*de2caf28SDavid du Colombier 	"	}",
2225*de2caf28SDavid du Colombier 	"",
2226*de2caf28SDavid du Colombier 	"	printf(\"cpu%%02d: largest shared memory segment: %%lu MB\\n\",",
2227*de2caf28SDavid du Colombier 	"		who_am_i, (ulong) n/(1024*1024));",
2228*de2caf28SDavid du Colombier 	"#if 0",
2229*de2caf28SDavid du Colombier 	"	#ifdef BFS_SEP_HASH",
2230*de2caf28SDavid du Colombier 	"	n /= 2;	/* not n /= Cores because the queues take most memory */",
2231*de2caf28SDavid du Colombier 	"	printf(\"cpu%%02d: using %%lu MB\\n\", who_am_i, (ulong) n/(1024*1024));",
2232*de2caf28SDavid du Colombier 	"	#endif",
2233*de2caf28SDavid du Colombier 	"#endif",
2234*de2caf28SDavid du Colombier 	"	fflush(stdout);",
2235*de2caf28SDavid du Colombier 	"",
2236*de2caf28SDavid du Colombier 	"	if ((n/(1024*1024)) == 32)",
2237*de2caf28SDavid du Colombier 	"	{ if (sizeof(void *) == 4) 	/* a 32 bit machine */",
2238*de2caf28SDavid du Colombier 	"	  { fprintf(stderr, \"\\t32MB is the default; increase it to 1 GB with:\\n\");",
2239*de2caf28SDavid du Colombier 	"	    fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmmax=%%d\\n\", (1<<30));",
2240*de2caf28SDavid du Colombier 	"	    fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmall=%%d\\n\", (1<<30)/8192);",
2241*de2caf28SDavid du Colombier 	"	  } else if (sizeof(void *) == 8)	/* a 64 bit machine */",
2242*de2caf28SDavid du Colombier 	"	  { fprintf(stderr, \"\\t32MB is the default; increase it to 30 GB with:\\n\");",
2243*de2caf28SDavid du Colombier 	"	    fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmmax=32212254720\\n\");",
2244*de2caf28SDavid du Colombier 	"	    fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmall=7864320\\n\");",
2245*de2caf28SDavid du Colombier 	"	    fprintf(stderr, \"\\tor for 60 GB:\\n\");",
2246*de2caf28SDavid du Colombier 	"	    fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmmax=60000000000\\n\");",
2247*de2caf28SDavid du Colombier 	"	    fprintf(stderr, \"\\tsudo /sbin/sysctl kernel.shmall=30000000\\n\");",
2248*de2caf28SDavid du Colombier 	"	  } else",
2249*de2caf28SDavid du Colombier 	"	  { fprintf(stderr, \"\\tweird wordsize %%d\\n\", (int) sizeof(void *));",
2250*de2caf28SDavid du Colombier 	"	} }",
2251*de2caf28SDavid du Colombier 	"",
2252*de2caf28SDavid du Colombier 	"	return n;",
2253*de2caf28SDavid du Colombier 	"}",
2254*de2caf28SDavid du Colombier 	"#ifdef BFS_DISK",
2255*de2caf28SDavid du Colombier 	"void",
2256*de2caf28SDavid du Colombier 	"bfs_disk_start(void)",	/* setup .spin*/
2257*de2caf28SDavid du Colombier 	"{	int unused = system(\"rm -fr .spin\");",
2258*de2caf28SDavid du Colombier 	"	if (mkdir(\".spin\", 0777) != 0)",
2259*de2caf28SDavid du Colombier 	"	{	perror(\"mkdir\");",
2260*de2caf28SDavid du Colombier 	"		Uerror(\"aborting\");",
2261*de2caf28SDavid du Colombier 	"	}",
2262*de2caf28SDavid du Colombier 	"}",
2263*de2caf28SDavid du Colombier 	"void",
2264*de2caf28SDavid du Colombier 	"bfs_disk_stop(void)",	/* remove .spin */
2265*de2caf28SDavid du Colombier 	"{",
2266*de2caf28SDavid du Colombier 	"	if (system(\"rm -fr .spin\") < 0)",
2267*de2caf28SDavid du Colombier 	"	{	perror(\"rm -fr .spin/\");",
2268*de2caf28SDavid du Colombier 	"	}",
2269*de2caf28SDavid du Colombier 	"}",
2270*de2caf28SDavid du Colombier 	"void",
2271*de2caf28SDavid du Colombier 	"bfs_disk_inp(void)", /* this core only */
2272*de2caf28SDavid du Colombier 	"{	int i; char fnm[16];",
2273*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
2274*de2caf28SDavid du Colombier 	"	bfs_printf(\"inp %%d %%d 0..%%d\\n\", bfs_toggle, who_am_i, Cores);",
2275*de2caf28SDavid du Colombier 	"#endif",
2276*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
2277*de2caf28SDavid du Colombier 	"	{	sprintf(fnm, \".spin/q%%d_%%d_%%d\", bfs_toggle, who_am_i, i);",
2278*de2caf28SDavid du Colombier 	"		if ((bfs_inp_fd[i] = open(fnm, 0444)) < 0)",
2279*de2caf28SDavid du Colombier 	"		{	perror(\"open\");",
2280*de2caf28SDavid du Colombier 	"			Uerror(fnm);",
2281*de2caf28SDavid du Colombier 	"	}	}",
2282*de2caf28SDavid du Colombier 	"}",
2283*de2caf28SDavid du Colombier 	"void",
2284*de2caf28SDavid du Colombier 	"bfs_disk_out(void)", /* this core only */
2285*de2caf28SDavid du Colombier 	"{	int i; char fnm[16];",
2286*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
2287*de2caf28SDavid du Colombier 	"	bfs_printf(\"out %%d 0..%%d %%d\\n\", 1-bfs_toggle, Cores, who_am_i);",
2288*de2caf28SDavid du Colombier 	"#endif",
2289*de2caf28SDavid du Colombier 	"	shared_memory->bfs_out_cnt[who_am_i] = 0;",
2290*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
2291*de2caf28SDavid du Colombier 	"	{	sprintf(fnm, \".spin/q%%d_%%d_%%d\", 1-bfs_toggle, i, who_am_i);",
2292*de2caf28SDavid du Colombier 	"		if ((bfs_out_fd[i] = creat(fnm, 0666)) < 0)",
2293*de2caf28SDavid du Colombier 	"		{	perror(\"creat\");",
2294*de2caf28SDavid du Colombier 	"			Uerror(fnm);",
2295*de2caf28SDavid du Colombier 	"	}	}",
2296*de2caf28SDavid du Colombier 	"}",
2297*de2caf28SDavid du Colombier 	"void",
2298*de2caf28SDavid du Colombier 	"bfs_disk_iclose(void)",
2299*de2caf28SDavid du Colombier 	"{	int i;",
2300*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
2301*de2caf28SDavid du Colombier 	"	bfs_printf(\"close_inp\\n\");",
2302*de2caf28SDavid du Colombier 	"#endif",
2303*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
2304*de2caf28SDavid du Colombier 	"	{	if (close(bfs_inp_fd[i]) < 0)",
2305*de2caf28SDavid du Colombier 	"		{	perror(\"iclose\");",
2306*de2caf28SDavid du Colombier 	"	}	}",
2307*de2caf28SDavid du Colombier 	"}",
2308*de2caf28SDavid du Colombier 	"void",
2309*de2caf28SDavid du Colombier 	"bfs_disk_oclose(void)",
2310*de2caf28SDavid du Colombier 	"{	int i;",
2311*de2caf28SDavid du Colombier 	"#ifdef VERBOSE",
2312*de2caf28SDavid du Colombier 	"	bfs_printf(\"close_out\\n\");",
2313*de2caf28SDavid du Colombier 	"#endif",
2314*de2caf28SDavid du Colombier 	"	for (i = 0; i < Cores; i++)",
2315*de2caf28SDavid du Colombier 	"	{	if (fsync(bfs_out_fd[i]) < 0)",
2316*de2caf28SDavid du Colombier 	"		{	perror(\"fsync\");",
2317*de2caf28SDavid du Colombier 	"		}",
2318*de2caf28SDavid du Colombier 	"		if (close(bfs_out_fd[i]) < 0)",
2319*de2caf28SDavid du Colombier 	"		{	perror(\"oclose\");",
2320*de2caf28SDavid du Colombier 	"	}	}",
2321*de2caf28SDavid du Colombier 	"}",
2322*de2caf28SDavid du Colombier 	"#endif",
2323*de2caf28SDavid du Colombier 	"void",
2324*de2caf28SDavid du Colombier 	"bfs_write_snap(int fd)",
2325*de2caf28SDavid du Colombier 	"{	if (write(fd, snap, strlen(snap)) != strlen(snap))",
2326*de2caf28SDavid du Colombier 	"	{       printf(\"pan: error writing %%s\\n\", fnm);",
2327*de2caf28SDavid du Colombier 	"		bfs_shutdown(\"file system error\");",
2328*de2caf28SDavid du Colombier 	"	}",
2329*de2caf28SDavid du Colombier 	"}",
2330*de2caf28SDavid du Colombier 	"",
2331*de2caf28SDavid du Colombier 	"void",
2332*de2caf28SDavid du Colombier 	"bfs_one_step(BFS_Trail *t, int fd)",
2333*de2caf28SDavid du Colombier 	"{	if (t && t->t_id != (T_ID) -1)",
2334*de2caf28SDavid du Colombier 	"	{	sprintf(snap, \"%%d:%%d:%%d\\n\",",
2335*de2caf28SDavid du Colombier 	"			trcnt++, t->pr, t->t_id);",
2336*de2caf28SDavid du Colombier 	"		bfs_write_snap(fd);",
2337*de2caf28SDavid du Colombier 	"	}",
2338*de2caf28SDavid du Colombier 	"}",
2339*de2caf28SDavid du Colombier 	"",
2340*de2caf28SDavid du Colombier 	"void",
2341*de2caf28SDavid du Colombier 	"bfs_putter(BFS_Trail *t, int fd)",
2342*de2caf28SDavid du Colombier 	"{	if (t && t != (BFS_Trail *) t->ostate)",
2343*de2caf28SDavid du Colombier 	"		bfs_putter((BFS_Trail *) t->ostate, fd);",
2344*de2caf28SDavid du Colombier 	"#ifdef L_BOUND",
2345*de2caf28SDavid du Colombier 	"	if (depthfound == trcnt)",
2346*de2caf28SDavid du Colombier 	"	{	strcpy(snap, \"-1:-1:-1\\n\");",
2347*de2caf28SDavid du Colombier 	"		bfs_write_snap(fd);",
2348*de2caf28SDavid du Colombier 	"		depthfound = -1;",
2349*de2caf28SDavid du Colombier 	"	}",
2350*de2caf28SDavid du Colombier 	"#endif",
2351*de2caf28SDavid du Colombier 	"	bfs_one_step(t, fd);",
2352*de2caf28SDavid du Colombier 	"}",
2353*de2caf28SDavid du Colombier 	"",
2354*de2caf28SDavid du Colombier 	"void",
2355*de2caf28SDavid du Colombier 	"bfs_nuerror(char *str)",
2356*de2caf28SDavid du Colombier 	"{	int fd = make_trail();",
2357*de2caf28SDavid du Colombier 	"",
2358*de2caf28SDavid du Colombier 	"	if (fd < 0) return;",
2359*de2caf28SDavid du Colombier 	"#ifdef VERI",
2360*de2caf28SDavid du Colombier 	"	sprintf(snap, \"-2:%%d:-2\\n\", (uchar) ((P0 *)pptr(0))->_t);",
2361*de2caf28SDavid du Colombier 	"	bfs_write_snap(fd);",
2362*de2caf28SDavid du Colombier 	"#endif",
2363*de2caf28SDavid du Colombier 	"#ifdef MERGED",
2364*de2caf28SDavid du Colombier 	"	sprintf(snap, \"-4:-4:-4\\n\");",
2365*de2caf28SDavid du Colombier 	"	bfs_write_snap(fd);",
2366*de2caf28SDavid du Colombier 	"#endif",
2367*de2caf28SDavid du Colombier 	"	trcnt = 1;",
2368*de2caf28SDavid du Colombier 	"	if (strstr(str, \"invalid\"))",
2369*de2caf28SDavid du Colombier 	"	{	bfs_putter((BFS_Trail *) trpt->ostate, fd);",
2370*de2caf28SDavid du Colombier 	"	} else",
2371*de2caf28SDavid du Colombier 	"	{	BFS_Trail x;",
2372*de2caf28SDavid du Colombier 	"		memset((char *) &x, 0, sizeof(BFS_Trail));",
2373*de2caf28SDavid du Colombier 	"		x.pr = trpt->pr;",
2374*de2caf28SDavid du Colombier 	"		x.t_id = (trpt->o_t)?trpt->o_t->t_id:0;",
2375*de2caf28SDavid du Colombier 	"		x.ostate = trpt->ostate;",
2376*de2caf28SDavid du Colombier 	"		bfs_putter(&x, fd);",
2377*de2caf28SDavid du Colombier 	"	}",
2378*de2caf28SDavid du Colombier 	"	close(fd);",
2379*de2caf28SDavid du Colombier 	"	if (errors >= upto && upto != 0)",
2380*de2caf28SDavid du Colombier 	"	{	bfs_shutdown(str);",
2381*de2caf28SDavid du Colombier 	"	}",
2382*de2caf28SDavid du Colombier 	"}",
2383*de2caf28SDavid du Colombier 	"",
2384*de2caf28SDavid du Colombier 	"void",
2385*de2caf28SDavid du Colombier 	"bfs_uerror(char *str)",
2386*de2caf28SDavid du Colombier 	"{	static char laststr[256];",
2387*de2caf28SDavid du Colombier 	"",
2388*de2caf28SDavid du Colombier 	"	errors++;",
2389*de2caf28SDavid du Colombier 	"	if (strncmp(str, laststr, 254) != 0)",
2390*de2caf28SDavid du Colombier 	"	{	bfs_printf(\"pan:%%lu: %%s (at depth %%ld)\\n\",",
2391*de2caf28SDavid du Colombier 	"			errors, str, ((depthfound == -1)?depth:depthfound));",
2392*de2caf28SDavid du Colombier 	"		strncpy(laststr, str, 254);",
2393*de2caf28SDavid du Colombier 	"	}",
2394*de2caf28SDavid du Colombier 	"#ifdef HAS_CODE",
2395*de2caf28SDavid du Colombier 	"	if (readtrail) { wrap_trail(); return; }",
2396*de2caf28SDavid du Colombier 	"#endif",
2397*de2caf28SDavid du Colombier 	"	if (every_error != 0 || errors == upto)",
2398*de2caf28SDavid du Colombier 	"	{	bfs_nuerror(str);",
2399*de2caf28SDavid du Colombier 	"	}",
2400*de2caf28SDavid du Colombier 	"	if (errors >= upto && upto != 0)",
2401*de2caf28SDavid du Colombier 	"	{	bfs_shutdown(\"bfs_uerror\");",
2402*de2caf28SDavid du Colombier 	"	}",
2403*de2caf28SDavid du Colombier 	"	depthfound = -1;",
2404*de2caf28SDavid du Colombier 	"}\n",
2405*de2caf28SDavid du Colombier 	"void",
2406*de2caf28SDavid du Colombier 	"bfs_Uerror(char *str)",
2407*de2caf28SDavid du Colombier 	"{	/* bfs_uerror(str); */",
2408*de2caf28SDavid du Colombier 	"	bfs_printf(\"pan:%%lu: %%s (at depth %%ld)\\n\", ++errors, str,",
2409*de2caf28SDavid du Colombier 	"		((depthfound == -1)?depth:depthfound));",
2410*de2caf28SDavid du Colombier 	"	bfs_shutdown(\"bfs_Uerror\");",
2411*de2caf28SDavid du Colombier 	"}",
2412*de2caf28SDavid du Colombier 	0,
2413*de2caf28SDavid du Colombier };
2414