Unify process_alloc() and process_realloc() with PROCESS_ALLOC_MODE_REALLOC bit
[moveable_pool.git] / process_test_run.c
1 #include <assert.h>
2 #include <stdbool.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #ifdef __FUZIX__
7 #include <unistd.h>
8 #endif
9 #include "core.h"
10 #include "process.h"
11 #include "process_test.h"
12 #include "rassert.h"
13
14 #include "swap.h"
15
16 #define TRANSFER_SIZE 0x8000
17
18 int *core_block_mem;
19 int *swap_block_mem;
20
21 void core_hash_init(int process, int base, int paras, int offset) {
22   int i, addr;
23
24  //printf("core_hash_init %d %d(%d) %d(%d) %d(%d)\n", process, base, base >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT, offset, offset >> BLOCK_PARAS_SHIFT);
25   for (i = 0; i < paras; ++i) {
26     addr = base + i;
27 #ifdef INDIRECT_CORE
28     addr =
29       (core_table_mem[addr >> BLOCK_PARAS_SHIFT] << BLOCK_PARAS_SHIFT) |
30       (addr & (BLOCK_PARAS - 1));
31 #endif /* INDIRECT_CORE */
32     rassert(core_block_mem[addr] == 0xaaaaaaaa);
33     core_block_mem[addr] = process * 17 + (i + offset) * 29;
34   }
35 }
36
37 void core_hash_verify(int process, int base, int paras, int offset) {
38   int i, addr;
39
40  //printf("core_hash_verify %d %d(%d) %d(%d) %d(%d)\n", process, base, base >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT, offset, offset >> BLOCK_PARAS_SHIFT);
41   for (i = 0; i < paras; ++i) {
42     addr = base + i;
43 #ifdef INDIRECT_CORE
44     addr =
45       (core_table_mem[addr >> BLOCK_PARAS_SHIFT] << BLOCK_PARAS_SHIFT) |
46       (addr & (BLOCK_PARAS - 1));
47 #endif /* INDIRECT_CORE */
48     rassert(core_block_mem[addr] == process * 17 + (i + offset) * 29);
49     core_block_mem[addr] = 0xaaaaaaaa;
50   }
51 }
52
53 void swap_hash_verify(int process, int base, int paras, int offset) {
54   int i, addr;
55
56  //printf("swap_hash_verify %d %d(%d) %d(%d) %d(%d)\n", process, base, base >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT, offset, offset >> BLOCK_PARAS_SHIFT);
57   for (i = 0; i < paras; ++i) {
58     addr = base + i;
59 #ifdef INDIRECT_SWAP
60     addr =
61       (swap_table_mem[addr >> BLOCK_PARAS_SHIFT] << BLOCK_PARAS_SHIFT) |
62       (addr & (BLOCK_PARAS - 1));
63 #endif /* INDIRECT_SWAP */
64     rassert(swap_block_mem[addr] == process * 17 + (i + offset) * 29);
65     swap_block_mem[addr] = 0xaaaaaaaa;
66   }
67 }
68
69 #ifndef INDIRECT_CORE
70 void core_copy(int src_base, int dest_base, int paras) {
71   int i;
72
73  //printf("core_copy %d(%d) %d(%d) %d(%d)\n", src_base, src_base >> BLOCK_PARAS_SHIFT, dest_base, dest_base >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
74   for (i = 0; i < paras; ++i) {
75     core_block_mem[dest_base + i] = core_block_mem[src_base + i];
76     core_block_mem[src_base + i] = 0xaaaaaaaa;
77   }
78 }
79
80 void core_copy_up(int src_limit, int dest_limit, int paras) {
81   int i;
82
83  //printf("core_copy_up %d(%d) %d(%d) %d(%d)\n", src_limit, src_limit >> BLOCK_PARAS_SHIFT, dest_limit, dest_limit >> BLOCK_PARAS_SHIFT, paras, (paras + (BLOCK_PARAS - 1)) >> BLOCK_PARAS_SHIFT);
84   paras = -paras;
85   for (i = -1; i >= paras; --i) {
86     core_block_mem[dest_limit + i] = core_block_mem[src_limit + i];
87     core_block_mem[src_limit + i] = 0xaaaaaaaa;
88   }
89 }
90 #endif /* ! INDIRECT_CORE */
91
92 // dir == false for read, true for write
93 void swap_read_write(int core_block, int swap_block, int blocks, bool dir) {
94   int i;
95
96  //printf("swap_read_write core [%d,%d) %s swap [%d,%d)\n", core_block, core_block + blocks, dir ? "->" : "<-", swap_block, swap_block + blocks);
97   core_block <<= BLOCK_PARAS_SHIFT;
98   swap_block <<= BLOCK_PARAS_SHIFT;
99   blocks <<= BLOCK_PARAS_SHIFT;
100 #define paras blocks
101   if (dir) {
102     for (i = 0; i < paras; ++i)
103       rassert(swap_block_mem[swap_block + i] == 0xaaaaaaaa);
104     memcpy(
105       swap_block_mem + swap_block,
106       core_block_mem + core_block,
107       paras * sizeof(int)
108     );
109     memset(core_block_mem + core_block, 0xaa, paras * sizeof(int));
110   }
111   else {
112     for (i = 0; i < paras; ++i)
113       rassert(core_block_mem[core_block + i] == 0xaaaaaaaa);
114     memcpy(
115       core_block_mem + core_block,
116       swap_block_mem + swap_block,
117       paras * sizeof(int)
118     );
119     memset(swap_block_mem + swap_block, 0xaa, paras * sizeof(int));
120   }
121 #undef paras
122 }
123
124 int main(int argc, char **argv) {
125   int n_processes;
126   int n_core_blocks;
127   int n_swap_blocks;
128   int spare;
129 #ifndef INDIRECT_CORE
130 #ifndef INDIRECT_SWAP
131   int i, j;
132 #else /* INDIRECT_SWAP */
133   int swap_table_blocks;
134   int i, j, k;
135 #endif /* INDIRECT_SWAP */
136 #else /* INDIRECT_CORE */
137   int core_table_blocks;
138 #ifdef INDIRECT_SWAP
139   int swap_table_blocks;
140 #endif /* INDIRECT_SWAP */
141   int i, j, k;
142 #endif /* INDIRECT_CORE */
143   struct process_test test;
144 #ifndef __FUZIX__
145   char buf[256];
146 #endif
147   struct process *process;
148   bool result;
149   int old_para_base, old_para_limit;
150   struct process_calc calc;
151   int in_core_para;
152
153   if (argc < 5) {
154     printf(
155       "usage: %s n_processes n_core_blocks "
156       "n_swap_blocks "
157       "spare"
158 #ifndef INDIRECT_CORE
159 #ifdef INDIRECT_SWAP
160       "[swap_table_blocks]"
161 #endif /* INDIRECT_SWAP */
162 #else /* INDIRECT_CORE */
163 #ifndef INDIRECT_SWAP
164       "[core_table_blocks]"
165 #else /* INDIRECT_SWAP */
166       "[core_table_blocks [swap_table_blocks]]"
167 #endif /* INDIRECT_SWAP */
168 #endif /* INDIRECT_CORE */
169       "\n",
170       argv[0]
171     );
172     exit(EXIT_FAILURE);
173   }
174   n_processes = atoi(argv[1]);
175   n_core_blocks = atoi(argv[2]);
176   n_swap_blocks = atoi(argv[3]);
177   spare = atoi(argv[4]);
178 #ifndef INDIRECT_CORE
179 #ifdef INDIRECT_SWAP
180   swap_table_blocks = argc >= 6 ? atoi(argv[5]) : n_swap_blocks;
181 #endif /* INDIRECT_SWAP */
182 #else /* INDIRECT_CORE */
183   core_table_blocks = argc >= 6 ? atoi(argv[5]) : n_core_blocks;
184 #ifdef INDIRECT_SWAP
185   swap_table_blocks = argc >= 7 ? atoi(argv[6]) : n_swap_blocks;
186 #endif /* INDIRECT_SWAP */
187 #endif /* INDIRECT_CORE */
188
189 #ifndef INDIRECT_CORE
190   core_init(n_core_blocks);
191 #else /* INDIRECT_CORE */
192   core_init(n_core_blocks, core_table_blocks);
193 #endif /* INDIRECT_CORE */
194   core_block_mem = malloc(n_core_blocks * (BLOCK_PARAS * sizeof(int)));
195   rassert(core_block_mem);
196   memset(core_block_mem, 0xaa, n_core_blocks * (BLOCK_PARAS * sizeof(int)));
197
198 #ifndef INDIRECT_SWAP
199   swap_init(n_swap_blocks);
200 #else /* INDIRECT_SWAP */
201   swap_init(n_swap_blocks, swap_table_blocks);
202 #endif /* INDIRECT_SWAP */
203   swap_block_mem = malloc(n_swap_blocks * (BLOCK_PARAS * sizeof(int)));
204   rassert(swap_block_mem);
205   memset(swap_block_mem, 0xaa, n_swap_blocks * (BLOCK_PARAS * sizeof(int)));
206
207   process_init(n_processes, spare);
208
209   while (true) {
210  //printf("avail %d %d(%d) %d(%d)\n", process_avail, CORE_AVAIL, core_table.avail, SWAP_AVAIL, swap_table.avail);
211 #ifdef __FUZIX__
212     if (read(0, &test, sizeof(test)) != sizeof(test))
213       break;
214 #else
215     switch ((unsigned int)scanf("%s", buf)) { // cast because of ACK bug
216     case -1:
217       goto done;
218     case 1:
219       break;
220     default:
221       rassert(false);
222     }
223     if (strcmp(buf, "alloc") == 0) {
224       test.type = PROCESS_TEST_TYPE_ALLOC;
225       rassert(
226         scanf(
227           "%d %d %d %s",
228           &test.process,
229           &test.para_base,
230           &test.para_limit,
231           buf
232         ) == 4
233       );
234       rassert(test.process >= 0 && test.process < n_processes);
235       rassert(test.para_limit >= test.para_base);
236       if (strcmp(buf, "false") == 0)
237         test.success = false;
238       else if (strcmp(buf, "true") == 0)
239         test.success = true;
240       else
241         rassert(false);
242     }
243     else if (strcmp(buf, "realloc") == 0) {
244       test.type = PROCESS_TEST_TYPE_REALLOC;
245       rassert(
246         scanf(
247           "%d %d %d %s",
248           &test.process,
249           &test.old_para_limit,
250           &test.para_limit,
251           buf
252         ) == 4
253       );
254       rassert(test.process >= 0 && test.process < n_processes);
255       if (strcmp(buf, "false") == 0)
256         test.success = false;
257       else if (strcmp(buf, "true") == 0)
258         test.success = true;
259       else
260         rassert(false);
261     }
262     else if (strcmp(buf, "realloc_base") == 0) {
263       test.type = PROCESS_TEST_TYPE_REALLOC_BASE;
264       rassert(
265         scanf(
266           "%d %d %d %s",
267           &test.process,
268           &test.old_para_base,
269           &test.para_base,
270           buf
271         ) == 4
272       );
273       rassert(test.process >= 0 && test.process < n_processes);
274       if (strcmp(buf, "false") == 0)
275         test.success = false;
276       else if (strcmp(buf, "true") == 0)
277         test.success = true;
278       else
279         rassert(false);
280     }
281     else if (strcmp(buf, "run") == 0) {
282       test.type = PROCESS_TEST_TYPE_RUN;
283       rassert(scanf("%d", &test.process) == 1);
284       rassert(test.process >= 0 && test.process < n_processes);
285     }
286     else if (strcmp(buf, "free") == 0) {
287       test.type = PROCESS_TEST_TYPE_FREE;
288       rassert(
289         scanf(
290           "%d %d %d",
291           &test.process,
292           &test.old_para_base,
293           &test.old_para_limit
294         ) == 3
295       );
296       rassert(test.process >= 0 && test.process < n_processes);
297       rassert(test.old_para_limit >= test.old_para_base);
298     }
299     else
300       rassert(false);
301 #endif
302     process = processes + test.process;
303     switch (test.type) {
304     case PROCESS_TEST_TYPE_ALLOC:
305       printf(
306         "alloc %d %d %d %s\n",
307         test.process,
308         test.para_base,
309         test.para_limit,
310         test.success ? "true" : "false"
311       );
312       rassert((process->flags & PROCESS_FLAGS_ACTIVE) == 0);
313       result = process_alloc(process, test.para_base, test.para_limit, 0);
314       printf(
315         "... %s\n",
316         result == test.success ?
317           "ok" :
318           result ? "succeeded, should fail" : "failed, should succeed"
319       );
320       if (result) {
321         if (!test.success) {
322           printf("... undo\n");
323           process_free(process);
324         }
325         else {
326           process_calc(process, &calc);
327  printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
328           core_hash_init(
329             test.process,
330             (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
331             test.para_limit - test.para_base,
332             0
333           );
334         }
335       }
336       break;
337     case PROCESS_TEST_TYPE_REALLOC:
338       printf(
339         "realloc %d %d %d %s\n",
340         test.process,
341         test.old_para_limit,
342         test.para_limit,
343         test.success ? "true" : "false"
344       );
345       if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
346         printf("... not allocated, ignore\n");
347       else if (test.para_limit < process->para_base)
348         printf("... new limit < base, ignore\n");
349       else {
350         old_para_limit = process->para_limit;
351         if (old_para_limit != test.old_para_limit)
352           printf(
353             "... old para limit %d, should be %d\n",
354             old_para_limit,
355             test.para_limit
356           );
357         process_calc(process, &calc);
358  printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
359         core_hash_verify(
360           test.process,
361           (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_limit,
362           old_para_limit - test.para_limit,
363           test.para_limit - process->para_base
364         );
365         result = process_alloc(
366           process,
367           process->para_base,
368           test.para_limit,
369           PROCESS_ALLOC_MODE_REALLOC
370         );
371         printf(
372           "... %s\n",
373           result == test.success ?
374             "ok" :
375             result ? "succeeded, should fail" : "failed, should succeed"
376         );
377         if (result) {
378           if (!test.success) {
379             printf("... undo\n");
380             rassert(
381               process_alloc(
382                 process,
383                 process->para_base,
384                 old_para_limit,
385                 PROCESS_ALLOC_MODE_REALLOC
386               )
387             );
388           }
389           else {
390             process_calc(process, &calc);
391  printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
392             core_hash_init(
393               test.process,
394               (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_limit,
395               test.para_limit - old_para_limit,
396               old_para_limit - process->para_base
397             );
398           }
399         }
400       }
401       break;
402     case PROCESS_TEST_TYPE_REALLOC_BASE:
403       printf(
404         "realloc_base %d %d %d %s\n",
405         test.process,
406         test.old_para_base,
407         test.para_base,
408         test.success ? "true" : "false"
409       );
410       if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
411         printf("... not allocated, ignore\n");
412       else if (test.para_base > process->para_limit)
413         printf("... new base > limit, ignore\n");
414       else {
415         old_para_base = process->para_base;
416         if (old_para_base != test.old_para_base)
417           printf(
418             "... old para base %d, should be %d\n",
419             old_para_base,
420             test.para_base
421           );
422         process_calc(process, &calc);
423  printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
424         core_hash_verify(
425           test.process,
426           (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_base,
427           test.para_base - old_para_base,
428           0
429         );
430         result = process_alloc(
431           process,
432           test.para_base,
433           process->para_limit,
434           PROCESS_ALLOC_MODE_REALLOC | PROCESS_ALLOC_MODE_LAST_FIT
435         );
436         printf(
437           "... %s\n",
438           result == test.success ?
439             "ok" :
440             result ? "succeeded, should fail" : "failed, should succeed"
441         );
442         if (result) {
443           if (!test.success) {
444             printf("... undo\n");
445             rassert(
446               process_alloc(
447                 process,
448                 old_para_base,
449                 process->para_limit,
450                 PROCESS_ALLOC_MODE_REALLOC | PROCESS_ALLOC_MODE_LAST_FIT
451               )
452             );
453           }
454           else {
455             process_calc(process, &calc);
456  printf("new core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
457             if (test.para_base < test.old_para_base)
458               core_hash_verify(
459                 test.process,
460                 (calc.core_origin << BLOCK_PARAS_SHIFT) + old_para_base,
461                 process->para_limit - old_para_base,
462                 0
463               );
464             else
465               core_hash_verify(
466                 test.process,
467                 (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
468                 process->para_limit - test.para_base,
469                 test.para_base - old_para_base
470               );
471             core_hash_init(
472               test.process,
473               (calc.core_origin << BLOCK_PARAS_SHIFT) + test.para_base,
474               process->para_limit - test.para_base,
475               0
476             );
477           }
478         }
479       }
480       break;
481     case PROCESS_TEST_TYPE_RUN:
482       printf("run %d\n", test.process);
483       if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
484         printf("... not allocated, ignore\n");
485       else {
486         process_run(process);
487         printf("... ok\n");
488       }
489       break;
490     case PROCESS_TEST_TYPE_FREE:
491       printf(
492         "free %d %d %d\n",
493         test.process,
494         test.old_para_base,
495         test.old_para_limit
496       );
497       if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
498         printf("... not allocated, ignore\n");
499       else {
500         old_para_base = process->para_base;
501         if (old_para_base != test.old_para_base)
502           printf(
503             "... old para base %d, should be %d\n",
504             old_para_base,
505             test.para_base
506           );
507         old_para_limit = process->para_limit;
508         if (old_para_limit != test.old_para_limit)
509           printf(
510             "... old para limit %d, should be %d\n",
511             old_para_limit,
512             test.para_limit
513           );
514         process_calc(process, &calc);
515  printf("old core [%d,%d) swap [%d,%d)\n", calc.block_base + calc.core_origin, calc.in_core_block + calc.core_origin, calc.in_core_block + calc.swap_origin, calc.block_limit + calc.swap_origin);
516         in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
517         if (in_core_para < process->para_base)
518           in_core_para = process->para_base;
519         else if (in_core_para > process->para_limit)
520           in_core_para = process->para_limit;
521         core_hash_verify(
522           test.process,
523           (calc.core_origin << BLOCK_PARAS_SHIFT) + process->para_base,
524           in_core_para - process->para_base,
525           0 
526         );
527         swap_hash_verify(
528           test.process,
529           (calc.swap_origin << BLOCK_PARAS_SHIFT) + in_core_para,
530           process->para_limit - in_core_para,
531           in_core_para - process->para_base
532         );
533         process_free(process);
534         printf("... ok\n");
535       }
536       break;
537     }
538   }
539
540 #ifndef __FUZIX__
541 done:
542 #endif
543   printf("final state:\n");
544   for (i = 0; i < n_processes; ++i) {
545     process = processes + i;
546     if ((process->flags & PROCESS_FLAGS_ACTIVE) == 0)
547       printf("process %d: not allocated\n", i);
548     else {
549       process_calc(process, &calc);
550       printf(
551         "process %d: core [%d,%d) swap [%d,%d)\n",
552         i,
553         calc.block_base + calc.core_origin,
554         calc.in_core_block + calc.core_origin,
555         calc.in_core_block + calc.swap_origin,
556         calc.block_limit + calc.swap_origin
557       );
558       in_core_para = calc.in_core_block << BLOCK_PARAS_SHIFT;
559       if (in_core_para < process->para_base)
560         in_core_para = process->para_base;
561       else if (in_core_para > process->para_limit)
562         in_core_para = process->para_limit;
563       core_hash_verify(
564         i,
565         (calc.core_origin << BLOCK_PARAS_SHIFT) + process->para_base,
566         in_core_para - process->para_base,
567         0 
568       );
569       swap_hash_verify(
570         i,
571         (calc.swap_origin << BLOCK_PARAS_SHIFT) + in_core_para,
572         process->para_limit - in_core_para,
573         in_core_para - process->para_base
574       );
575       process_free(process);
576     }
577   }
578
579 #ifdef INDIRECT_CORE
580   for (i = 0; i < core_table_blocks; ++i)
581     rassert(core_table_mem[i] == 0x55555555);
582   {
583     k = core_block_pool.n_blocks >> 3;
584     for (j = 0; j < k; ++j)
585       rassert(core_block_pool.bitmap[j] == 0xff);
586     k = core_block_pool.n_blocks & 7;
587     if (k)
588       rassert(core_block_pool.bitmap[j] == (uint8_t)~(-1 << k));
589   }
590 #endif /* INDIRECT_CORE */
591   j = n_core_blocks << BLOCK_PARAS_SHIFT;
592   for (i = 0; i < j; ++i)
593     rassert(core_block_mem[i] == 0xaaaaaaaa);
594 #ifdef INDIRECT_SWAP
595   for (i = 0; i < swap_table_blocks; ++i)
596     rassert(swap_table_mem[i] == 0x55555555);
597   {
598     k = swap_block_pool.n_blocks >> 3;
599     for (j = 0; j < k; ++j)
600       rassert(swap_block_pool.bitmap[j] == 0xff);
601     k = swap_block_pool.n_blocks & 7;
602     if (k)
603       rassert(swap_block_pool.bitmap[j] == (uint8_t)~(-1 << k));
604   }
605 #endif /* INDIRECT_SWAP */
606   j = n_swap_blocks << BLOCK_PARAS_SHIFT;
607   for (i = 0; i < j; ++i)
608     rassert(swap_block_mem[i] == 0xaaaaaaaa);
609
610   return 0;
611 }