-
Notifications
You must be signed in to change notification settings - Fork 3
/
ring.h
310 lines (244 loc) · 7.07 KB
/
ring.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#ifndef _ring_h_INCLUDED
#define _ring_h_INCLUDED
#include "average.h"
#include "clause.h"
#include "heap.h"
#include "logging.h"
#include "macros.h"
#include "options.h"
#include "profile.h"
#include "queue.h"
#include "stack.h"
#include "statistics.h"
#include "tagging.h"
#include "trace.h"
#include "variable.h"
#include "watches.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
struct ruler;
struct reluctant {
uint64_t u, v;
};
struct ring_limits {
uint64_t mode;
uint64_t randec;
uint64_t reduce;
uint64_t rephase;
uint64_t restart;
uint64_t simplify;
uint64_t tiers;
long long conflicts;
struct {
uint64_t conflicts;
uint64_t reductions;
} probe;
};
struct intervals {
uint64_t mode;
uint64_t tiers;
};
struct averages {
struct {
struct average fast;
struct average slow;
} glue;
struct average level;
struct average trail;
struct average decisions;
struct average size;
};
struct ring_last {
uint64_t decisions;
unsigned fixed;
uint64_t probing;
uint64_t walk;
#ifndef QUIET
struct mode {
uint64_t conflicts;
uint64_t ticks;
double time;
} mode;
#endif
};
struct ring_delay {
struct {
uint64_t count, current;
} bump_reason;
};
struct ring_trail {
unsigned *begin, *end;
unsigned *pos, *propagate;
};
struct ring_units {
unsigned *begin, *end;
unsigned *iterate, *export;
};
#define MAX_REDUNDANCY (~(uint64_t) 0)
#ifdef LOGGING
#define LOG_REDUNDANCY(R) (unsigned) ((R) >> 32), (unsigned) (R)
#endif
#define BINARY_BUCKET 0
#define SIZE_POOL 8
struct bucket {
uint64_t redundancy;
atomic_uintptr_t shared;
};
struct pool {
struct bucket bucket[SIZE_POOL];
};
struct ring;
struct rings {
struct ring **begin, **end, **allocated;
};
struct ring {
unsigned id;
unsigned threads;
struct pool *pool;
unsigned *ruler_units;
struct ruler *ruler;
volatile int status;
bool import_after_propagation_and_conflict;
bool inconsistent;
bool stable;
signed char iterating;
unsigned best;
unsigned context;
unsigned level;
unsigned probe;
unsigned size;
unsigned target;
unsigned unassigned;
unsigned tier1_glue_limit[2];
unsigned tier2_glue_limit[2];
signed char *marks;
signed char *values;
bool *inactive;
unsigned char *used;
struct unsigneds analyzed;
struct unsigneds clause;
struct unsigneds levels;
struct unsigneds minimize;
struct unsigneds sorter;
struct unsigneds outoforder;
struct unsigneds promote;
struct rings exports;
struct references *references;
struct ring_trail trail;
struct ring_units ring_units;
struct variable *variables;
struct heap heap;
struct phases *phases;
struct queue queue;
unsigned redundant;
struct watchers watchers;
unsigned last_learned[4];
struct saved_watchers saved;
struct trace trace;
struct averages averages[2];
struct intervals intervals;
struct ring_last last;
struct ring_delay delay;
struct ring_limits limits;
struct options options;
struct reluctant reluctant;
struct ring_profiles profiles;
struct ring_statistics statistics;
unsigned randec;
uint64_t random;
};
/*------------------------------------------------------------------------*/
#define VAR(LIT) (ring->variables + IDX (LIT))
#define REFERENCES(LIT) (ring->references[LIT])
/*------------------------------------------------------------------------*/
#define all_ring_indices(IDX) \
unsigned IDX = 0, END_##IDX = ring->size; \
IDX != END_##IDX; \
++IDX
#define all_ring_literals(LIT) \
unsigned LIT = 0, END_##LIT = 2 * ring->size; \
LIT != END_##LIT; \
++LIT
#define all_phases(PHASE) \
struct phases *PHASE = ring->phases, *END_##PHASE = PHASE + ring->size; \
(PHASE != END_##PHASE); \
++PHASE
#define all_averages(AVG) \
struct average *AVG = (struct average *) &ring->averages, \
*END_##AVG = (struct average *) ((char *) AVG + \
sizeof ring->averages); \
AVG != END_##AVG; \
++AVG
#define all_watchers(WATCHER) \
struct watcher *WATCHER = ring->watchers.begin + 1, \
*END_##WATCHER = ring->watchers.end; \
(WATCHER != END_##WATCHER); \
++WATCHER
#define all_redundant_watchers(WATCHER) \
struct watcher *WATCHER = ring->watchers.begin + ring->redundant, \
*END_##WATCHER = ring->watchers.end; \
(WATCHER != END_##WATCHER); \
++WATCHER
#define capacity_last_learned \
(sizeof ring->last_learned / sizeof *ring->last_learned)
#define real_end_last_learned (ring->last_learned + capacity_last_learned)
#define really_all_last_learned(IDX_PTR) \
unsigned *IDX_PTR = ring->last_learned, \
*IDX_PTR##_END = real_end_last_learned; \
IDX_PTR != IDX_PTR##_END; \
IDX_PTR++
/*------------------------------------------------------------------------*/
void init_ring (struct ring *);
void release_ring (struct ring *, bool keep_values);
struct ring *new_ring (struct ruler *);
void delete_ring (struct ring *);
void init_pool (struct ring *, unsigned threads);
void reset_last_learned (struct ring *);
void mark_satisfied_watchers_as_garbage (struct ring *);
void inc_clauses (struct ring *ring, bool redundant);
void dec_clauses (struct ring *ring, bool redundant);
void set_inconsistent (struct ring *, const char *msg);
void set_satisfied (struct ring *);
void print_ring_profiles (struct ring *);
unsigned *sorter_block (struct ring *, size_t size);
struct ring *random_other_ring (struct ring *);
/*------------------------------------------------------------------------*/
static inline unsigned watcher_to_index (struct ring *ring,
struct watcher *watcher) {
assert (ring->watchers.begin <= watcher);
assert (watcher < ring->watchers.end);
size_t idx = watcher - ring->watchers.begin;
assert (idx <= MAX_WATCHER_INDEX);
assert (idx <= UINT_MAX);
return idx;
}
static inline struct watcher *index_to_watcher (struct ring *ring,
unsigned idx) {
return &PEEK (ring->watchers, idx);
}
static inline struct watcher *get_watcher (struct ring *ring,
struct watch *watch) {
assert (!is_binary_pointer (watch));
size_t idx = index_pointer (watch);
return &PEEK (ring->watchers, idx);
}
static inline struct clause *get_clause (struct ring *ring,
struct watch *watch) {
assert (watch);
return get_watcher (ring, watch)->clause;
}
/*------------------------------------------------------------------------*/
static inline void push_watch (struct ring *ring, unsigned lit,
struct watch *watch) {
LOGWATCH (watch, "watching %s in", LOGLIT (lit));
PUSH (REFERENCES (lit), watch);
}
static inline void watch_literal (struct ring *ring, unsigned lit,
unsigned other, struct watcher *watcher) {
unsigned idx = watcher_to_index (ring, watcher);
struct watch *watch = tag_index (watcher->redundant, idx, other);
push_watch (ring, lit, watch);
}
/*------------------------------------------------------------------------*/
#endif