1 /* $Id: check.c,v 1.8 1994/06/24 11:17:37 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
13 #ifdef CHECK /* otherwise this whole file is skipped */
15 private acquire_malout(), check_ml_last();
16 private dump_all_mallinks(), dump_free_list(), dump_mallink(), print_loop();
18 private size_type checksum();
21 public mallink *free_list_entry();
23 #define for_free_list(i,p) \
24 for (p = free_list_entry(i); p; p = log_next_of(p))
26 #define for_all_mallinks(ml) /* backwards! */ \
27 for (ml = ml_last; ml; \
28 ml = first_mallink(ml) ? MAL_NULL : phys_prev_of(ml))
32 static int pr_cnt = 0;
35 /* Dump pertinent info in pseudo-readable format;
36 abort afterwards if n != 0.
38 static int dumping = 0;
46 ">>>>>>>>>>>>>>>> DUMP OF ALL MALLINKS <<<<<<<<<<<<<<<<");
47 fprintf(malout, " ml_last = %ld\n", (long)ml_last);
48 if (++pr_cnt == 100) pr_cnt = 0;
51 ">>>>>>>>>>>>>>>> DUMP OF FREE_LISTS <<<<<<<<<<<<<<<<\n");
52 if (++pr_cnt == 100) pr_cnt = 0;
53 for (i = 0; i < MAX_FLIST; i++)
56 ">>>>>>>>>>>>>>>> END OF DUMP <<<<<<<<<<<<<<<<\n");
65 static char buf[BUFSIZ];
68 malout = freopen("mal.out", "w", stderr);
77 for_all_mallinks (ml) {
80 dump_mallink((char *)0, ml);
86 mallink *ml = free_list_entry(i);
90 fprintf(malout, "%2d: ", i);
91 for_free_list(i, ml) {
94 fprintf(malout, "%ld ", (long) ml);
96 fprintf(malout, "<\n");
100 print_loop(ml) mallink *ml; {
101 if (print_of(ml) == pr_cnt) {
102 fprintf(malout, "... PRINT LOOP\n");
105 set_print(ml, pr_cnt);
110 dump_mallink(s, ml) char *s; mallink *ml; {
113 fprintf(malout, "%s: ", s);
114 fprintf(malout, "@: %ld;", (long)ml);
115 if (ml && checksum_of(ml) != checksum(ml))
116 fprintf(malout, ">>>> CORRUPTED <<<<");
118 fprintf(malout, "\n");
122 fprintf(malout, " l_p: %ld;", (long)_log_prev_of(ml));
123 fprintf(malout, " l_n: %ld;", (long)_log_next_of(ml));
125 fprintf(malout, " p_s: %ld;", (long)prev_size_of(ml));
126 fprintf(malout, " t_s: %ld;", (long)_this_size_of(ml));
127 fprintf(malout, " sz: %ld;", (long)size_of(ml));
128 fprintf(malout, " fr: %d;", free_of(ml));
129 fprintf(malout, "\n");
132 /* Check_mallinks() checks the total data structure as accessible
133 through free_list[] and ml_last. All check_sums should be OK,
134 except those held in the small array off_colour. This is a
135 trick to allow to continue checking even when a few mallinks
136 are temporarily out of order.
137 Check_mallinks() tests for a lot of internal consistency.
140 /* Some arbitrary constants */
141 #define IN_ML_LAST 93
142 #define IN_FREE_LIST 57 /* and in ml_last */
149 check_mallinks(s) char *s; {
157 for_all_mallinks(ml) {
158 if (checksum_of(ml) != checksum(ml))
159 Error("mallink info at %lx corrupted", s, (long)ml);
160 if (working_on(ml)) {
164 if ( !last_mallink(ml) &&
165 phys_prev_of(phys_next_of(ml)) != ml
167 Error("upward chain bad at %lx", s, (long)ml);
168 if ( !first_mallink(ml) &&
169 phys_next_of(phys_prev_of(ml)) != ml
171 Error("downward chain bad at %lx", s, (long)ml);
174 Error("free mallink at %lx follows free mallink",
180 set_mark(ml, IN_ML_LAST);
183 for (i = 0, size = MIN_SIZE; i < MAX_FLIST; i++, size *= 2) {
184 for_free_list(i, ml) {
188 Error("occupied mallink %lx occurs in free_list", s, (long)ml);
189 switch (mark_of(ml)) {
191 set_mark(ml, IN_FREE_LIST);
194 Error("mallink %lx occurs in 2 free_lists",
197 Error("unknown mallink %lx in free_list",
200 if (size_of(ml) < size)
201 Error("size of mallink %lx too small", s, (long)ml);
202 if (size_of(ml) >= 2*size)
203 Error("size of mallink %lx too large", s, (long)ml);
206 for_all_mallinks (ml) {
209 if (free_of(ml) && mark_of(ml) != IN_FREE_LIST)
210 Error("free mallink %lx is in no free_list", s, (long)ml);
216 check_ml_last(s) char *s; {
217 if (ml_last && _this_size_of(ml_last) == 0)
218 Error("size of ml_last == 0, at %ld", s, ml_last);
222 checksum(ml) mallink *ml; {
226 sum += (size_type)_log_prev_of(ml);
227 sum += (size_type)_log_next_of(ml);
229 sum += (size_type)prev_size_of(ml);
230 sum += (size_type)_this_size_of(ml);
235 calc_checksum(ml) mallink *ml; {
236 set_checksum(ml, checksum(ml));
240 static mallink *off_colour[N_COLOUR];
243 started_working_on(ml) mallink *ml; {
246 for (i = 0; i < N_COLOUR; i++)
247 if (off_colour[i] == MAL_NULL) {
251 Error("out of off_colour array at %ld", "started_working_on", ml);
255 stopped_working_on(ml) mallink *ml; {
258 for (i = 0; i < N_COLOUR; i++)
259 if (off_colour[i] == ml) {
260 off_colour[i] = MAL_NULL;
263 Error("stopped working on mallink %ld", "stopped_working_on", ml);
267 working_on(ml) mallink *ml; {
270 for (i = 0; i < N_COLOUR; i++)
271 if (off_colour[i] == ml)
277 check_work_empty(s) char *s; {
281 for (i = 0; i < N_COLOUR; i++)
282 if (off_colour[i] != MAL_NULL)
285 Error("off_colour not empty", s, MAL_NULL);
289 Error(fmt, s, ml) char *fmt, *s; mallink *ml; {
290 static int already_called = 0;
292 if (already_called++) return 0;
293 setbuf(stdout, (char *) 0);
295 printf(fmt, (long)ml);
298 fprintf(malout, "%s: ", s);
299 fprintf(malout, fmt, (long)ml);
300 fprintf(malout, "\n");
303 return 0; /* to satisfy lint */