1 /* $Id: check.c,v 1.4 1994/06/24 11:55:12 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".
8 #ifdef CHECK /* otherwise this whole file is skipped */
10 /* ??? check these later */
11 private acquire_malout(void), check_ml_last(const char *s);
12 private dump_all_mallinks(void), dump_free_list(int i);
13 private dump_mallink(const char *s, mallink *ml), print_loop(mallink *ml);
14 private working_on(mallink *ml);
15 private size_type checksum(mallink *ml);
18 private mallink *free_list_entry(int i);
20 #define for_free_list(i,p) \
21 for (p = free_list_entry(i); p; p = log_next_of(p))
23 #define for_all_mallinks(ml) /* backwards! */ \
24 for (ml = ml_last; ml; \
25 ml = first_mallink(ml) ? MAL_NULL : phys_prev_of(ml))
29 static int pr_cnt = 0;
32 /* Dump pertinent info in pseudo-readable format;
33 abort afterwards if n != 0.
35 static int dumping = 0;
43 ">>>>>>>>>>>>>>>> DUMP OF ALL MALLINKS <<<<<<<<<<<<<<<<");
44 fprintf(malout, " ml_last = %p\n", ml_last);
45 if (++pr_cnt == 100) pr_cnt = 0;
48 ">>>>>>>>>>>>>>>> DUMP OF FREE_LISTS <<<<<<<<<<<<<<<<\n");
49 if (++pr_cnt == 100) pr_cnt = 0;
50 for (i = 0; i < MAX_FLIST; i++)
53 ">>>>>>>>>>>>>>>> END OF DUMP <<<<<<<<<<<<<<<<\n");
61 acquire_malout(void) {
62 static char buf[BUFSIZ];
65 malout = freopen("mal.out", "w", stderr);
71 dump_all_mallinks(void) {
74 for_all_mallinks (ml) {
77 dump_mallink((char *)0, ml);
82 dump_free_list(int i) {
83 mallink *ml = free_list_entry(i);
87 fprintf(malout, "%2d: ", i);
88 for_free_list(i, ml) {
91 fprintf(malout, "%p ", ml);
93 fprintf(malout, "<\n");
97 print_loop(mallink *ml) {
98 if (print_of(ml) == pr_cnt) {
99 fprintf(malout, "... PRINT LOOP\n");
102 set_print(ml, pr_cnt);
107 dump_mallink(const char *s, mallink *ml) {
110 fprintf(malout, "%s: ", s);
111 fprintf(malout, "@: %p;", ml);
112 if (ml && checksum_of(ml) != checksum(ml))
113 fprintf(malout, ">>>> CORRUPTED <<<<");
115 fprintf(malout, "\n");
119 fprintf(malout, " l_p: %p;", _log_prev_of(ml));
120 fprintf(malout, " l_n: %p;", _log_next_of(ml));
122 fprintf(malout, " p_s: %p;", prev_size_of(ml));
123 fprintf(malout, " t_s: %p;", _this_size_of(ml));
124 fprintf(malout, " sz: %lu;", (unsigned long) size_of(ml));
125 fprintf(malout, " fr: %d;", free_of(ml));
126 fprintf(malout, "\n");
129 /* Check_mallinks() checks the total data structure as accessible
130 through free_list[] and ml_last. All check_sums should be OK,
131 except those held in the small array off_colour. This is a
132 trick to allow to continue checking even when a few mallinks
133 are temporarily out of order.
134 Check_mallinks() tests for a lot of internal consistency.
137 /* Some arbitrary constants */
138 #define IN_ML_LAST 93
139 #define IN_FREE_LIST 57 /* and in ml_last */
146 check_mallinks(const char *s) {
154 for_all_mallinks(ml) {
155 if (checksum_of(ml) != checksum(ml))
156 Error("mallink info at %p corrupted", s, ml);
157 if (working_on(ml)) {
161 if ( !last_mallink(ml) &&
162 phys_prev_of(phys_next_of(ml)) != ml
164 Error("upward chain bad at %p", s, ml);
165 if ( !first_mallink(ml) &&
166 phys_next_of(phys_prev_of(ml)) != ml
168 Error("downward chain bad at %p", s, ml);
171 Error("free mallink at %p follows free mallink",
177 set_mark(ml, IN_ML_LAST);
180 for (i = 0, size = MIN_SIZE; i < MAX_FLIST; i++, size *= 2) {
181 for_free_list(i, ml) {
185 Error("occupied mallink %p occurs in free_list", s, ml);
186 switch (mark_of(ml)) {
188 set_mark(ml, IN_FREE_LIST);
191 Error("mallink %p occurs in 2 free_lists",
194 Error("unknown mallink %p in free_list",
197 if (size_of(ml) < size)
198 Error("size of mallink %p too small", s, ml);
199 if (size_of(ml) >= 2*size)
200 Error("size of mallink %p too large", s, ml);
203 for_all_mallinks (ml) {
206 if (free_of(ml) && mark_of(ml) != IN_FREE_LIST)
207 Error("free mallink %p is in no free_list", s, ml);
213 check_ml_last(const char *s) {
214 if (ml_last && _this_size_of(ml_last) == 0)
215 Error("size of ml_last == 0, at %p", s, ml_last);
219 checksum(mallink *ml) {
223 sum += (size_type)_log_prev_of(ml);
224 sum += (size_type)_log_next_of(ml);
226 sum += (size_type)prev_size_of(ml);
227 sum += (size_type)_this_size_of(ml);
232 calc_checksum(mallink *ml) {
233 set_checksum(ml, checksum(ml));
237 static mallink *off_colour[N_COLOUR];
240 started_working_on(mallink *ml) {
243 for (i = 0; i < N_COLOUR; i++)
244 if (off_colour[i] == MAL_NULL) {
248 Error("out of off_colour array at %p", "started_working_on", ml);
252 stopped_working_on(mallink *ml) {
255 for (i = 0; i < N_COLOUR; i++)
256 if (off_colour[i] == ml) {
257 off_colour[i] = MAL_NULL;
260 Error("stopped working on mallink %p", "stopped_working_on", ml);
264 working_on(mallink *ml) {
267 for (i = 0; i < N_COLOUR; i++)
268 if (off_colour[i] == ml)
274 check_work_empty(const char *s) {
278 for (i = 0; i < N_COLOUR; i++)
279 if (off_colour[i] != MAL_NULL)
282 Error("off_colour not empty", s, MAL_NULL);
286 Error(const char *fmt, const char *s, mallink *ml) {
287 static int already_called = 0;
289 if (already_called++) return 0;
290 setbuf(stdout, (char *) 0);
292 printf(fmt, (long)ml);
295 fprintf(malout, "%s: ", s);
296 fprintf(malout, fmt, (long)ml);
297 fprintf(malout, "\n");
300 return 0; /* to satisfy lint */