os161-1.99
 All Data Structures
vm-mix1-fork.c
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <unistd.h>
00005 
00006 /* This is creating a program that has
00007  * a few more text pages than the average
00008  * program we usually have.
00009  */
00010 
00011 // #define DEBUG
00012 // #define DEBUG_PARENT
00013 // #define DEBUG_CHILD
00014 
00015 extern void     call_all();
00016 void write_data(unsigned int array[], unsigned int start);
00017 void read_data(unsigned int array[], unsigned int start, const char *array_name);
00018 void print_data(unsigned int array[]);
00019 void do_work(unsigned int start);
00020 
00021 #define PAGE_SIZE           (4096)
00022 #define DATA_BYTES          (3 * 1024 * 1024)
00023 #define PAGES               (DATA_BYTES / PAGE_SIZE)
00024 #define ELEM_SIZE           (sizeof(unsigned int))
00025 #define ELEMS               ((PAGE_SIZE * PAGES / sizeof(unsigned int)) / 2)
00026 #define ELEMS_PER_PAGE      (PAGE_SIZE / ELEM_SIZE)
00027 #define NUM_REFS            (2)
00028 
00029 #define STACK_PAGES_USED    (9)
00030 #define STACK_ARRAY_ELEMS   (PAGE_SIZE * STACK_PAGES_USED / sizeof(unsigned int))
00031 
00032 unsigned int init[] = {
00033   0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
00034  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
00035  20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
00036  30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
00037  40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
00038  50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
00039 };
00040 
00041 #define INIT_ARRAY_ELEMS     (sizeof(init) / sizeof(int))
00042 
00043 unsigned int array1[ELEMS];
00044 unsigned int array2[ELEMS];
00045 
00046 void
00047 write_data(unsigned int array[], unsigned int start)
00048 {
00049         unsigned int ref = 0;
00050         unsigned int i = 0;
00051 
00052         for (ref = 0; ref < NUM_REFS-1; ref++) {
00053                 for (i=0; i<ELEMS; i++) {
00054       array[i] = start + (i / ELEMS_PER_PAGE);
00055                 }
00056         }
00057 }
00058 
00059 void
00060 read_data(unsigned int array[], unsigned int start, const char *array_name)
00061 {
00062   unsigned int ref = 0;
00063         unsigned int i = 0;
00064 
00065         for (ref = 0; ref < NUM_REFS-1; ref++) {
00066                 for (i=0; i<ELEMS; i++) {
00067                         if (array[i] != (start + (i / ELEMS_PER_PAGE))) {
00068                                 printf("FAILED in file %s at line %d %s[%d] = %u != %u ref = %d\n", 
00069                 __FILE__, __LINE__, array_name, i, array[i], i, ref+1);
00070                                 exit(1);
00071                         }
00072                 }
00073   }
00074 }
00075 
00076 void
00077 print_data(unsigned int array[])
00078 {
00079         unsigned int i = 0;
00080   unsigned int count = 0;
00081 
00082         for (i=0; i<ELEMS; i+= (ELEMS_PER_PAGE)) {
00083                 printf("[%10u] = %10u ", i, array[i]);
00084     if (((count+1) % 4) == 0) {
00085       printf("\n");
00086     }
00087     count++;
00088         }
00089   printf("\n");
00090 }
00091 
00092 void
00093 do_work(unsigned int start)
00094 {
00095         unsigned int stack_array[STACK_ARRAY_ELEMS];
00096         unsigned int i = 0;
00097   unsigned int array1_start = start;
00098   unsigned int array2_start = start + (ELEMS / (ELEMS_PER_PAGE)) + 10;
00099 
00100   printf("Checking uninitialized array1 pid = %d\n", getpid());
00101         /* check the uninitialized array1 before initialization */
00102         for (i=0; i<ELEMS; i++) {
00103                 if (array1[i] != 0) {
00104                         printf("FAILED in file %s at line %d: array1[%d] = %u != %d\n", __FILE__, __LINE__, i, array1[i], 0);
00105                         exit(1);
00106                 }
00107         }
00108 
00109   printf("Checking uninitialized array2 pid = %d\n", getpid());
00110         /* check the uninitialized array2 before initialization */
00111         for (i=0; i<ELEMS; i++) {
00112                 if (array2[i] != 0) {
00113                         printf("FAILED in file %s at line %d: array2[%d] = %u != %d\n", __FILE__, __LINE__, i, array2[i], 0);
00114                         exit(1);
00115                 }
00116         }
00117 
00118         for (i=0; i<STACK_ARRAY_ELEMS; i++) {
00119                 stack_array[i] = i * 1000;
00120         }
00121 
00122         for (i=0; i<2; i++) {
00123           call_all();
00124           write_data(array1, array1_start);
00125           call_all();
00126     printf("Checking initialized array1 pid = %d\n", getpid());
00127           read_data(array1, array1_start, "array1");
00128         }
00129 
00130         /* check the uninitialized array2 again before initialization */
00131   printf("Checking initialized array2 again pid = %d\n", getpid());
00132         for (i=0; i<ELEMS; i++) {
00133                 if (array2[i] != 0) {
00134                         printf("FAILED in file %s at line %d: array2[%d] = %u != %d\n", __FILE__, __LINE__, i, array2[i], 0);
00135                         exit(1);
00136                 }
00137         }
00138 
00139   printf("Checking initialized stack_array pid = %d\n", getpid());
00140         for (i=0; i<STACK_ARRAY_ELEMS; i++) {
00141                 if (stack_array[i] != i * 1000) {
00142                         printf("FAILED in file %s at line %d: stack_array[%d] = %u != %d\n", __FILE__, __LINE__, i, stack_array[i], i);
00143                         exit(1);
00144                 }
00145         }
00146 
00147   printf("Checking initialized init pid = %d\n", getpid());
00148         /* check the initialized array */
00149         for (i=0; i<INIT_ARRAY_ELEMS; i++) {
00150                 if (init[i] != i) {
00151                         printf("FAILED in file %s at line %d: init[%d] = %u != %d\n", __FILE__, __LINE__, i, init[i], i);
00152                         exit(1);
00153                 }
00154         }
00155 
00156         for (i=0; i<2; i++) {
00157           call_all();
00158           write_data(array2, array2_start);
00159           call_all();
00160     printf("Checking initialized array2 pid = %d\n", getpid());
00161           read_data(array2, array2_start, "array2");
00162         }
00163 
00164   printf("Checking initialized stack_array pid = %d\n", getpid());
00165         for (i=0; i<STACK_ARRAY_ELEMS; i++) {
00166                 if (stack_array[i] != i * 1000) {
00167                         printf("FAILED in file %s at line %d: stack_array[%d] = %u != %d\n", __FILE__, __LINE__, i, stack_array[i], i);
00168                         exit(1);
00169                 }
00170         }
00171 
00172         /* check the initialized array */
00173   printf("Checking initialized init pid = %d\n", getpid());
00174         for (i=0; i<INIT_ARRAY_ELEMS; i++) {
00175                 if (init[i] != i) {
00176                         printf("FAILED in file %s at line %d: init[%d] = %u != %d\n", __FILE__, __LINE__, i, init[i], i);
00177                         exit(1);
00178                 }
00179         }
00180 
00181 
00182   printf("Checking initialized array1 for the last time pid = %d\n", getpid());
00183         read_data(array1, array1_start, "array1");
00184   printf("Checking initialized array2 for the last time pid = %d\n", getpid());
00185         read_data(array2, array2_start, "array2");
00186 
00187 
00188         printf("Pid = %d SUCCEEDED\n", getpid());
00189 }
00190 
00191 int
00192 main()
00193 {
00194   int pid = 0;
00195   int rc = 0;
00196   int status = 0;
00197 
00198 #ifdef DEBUG
00199   printf("PAGE_SIZE = %d\n", PAGE_SIZE);
00200   printf("DATA_BYTES = %d\n", DATA_BYTES);
00201   printf("ELEMS = %d\n", ELEMS);
00202   printf("ELEMS_PER_PAGE = %d\n", ELEMS_PER_PAGE);
00203   printf("PAGES = %d\n", PAGES);
00204   printf("Array elements = %d\n", ELEMS);
00205   printf("Pages per array = %d\n", ((ELEMS * sizeof(unsigned int)) / PAGE_SIZE));
00206 #endif
00207 
00208   pid = fork();
00209   if (pid < 0) {
00210     printf("Unable to fork\n");
00211     exit(1);
00212   }
00213 
00214   if (pid == 0) {
00215                 printf("Child pid = %d calling do_work\n", getpid());
00216                 do_work(20);
00217 #ifdef DEBUG_CHILD
00218                 printf("array 1\n");
00219                 print_data(array1);
00220                 printf("array 2\n");
00221                 print_data(array2);
00222 #endif
00223     exit(0);
00224   }
00225 
00226   printf("Parent pid = %d calling do_work\n", getpid());
00227   do_work(1);
00228 #ifdef DEBUG_PARENT
00229         printf("array 1\n");
00230         print_data(array1);
00231         printf("array 2\n");
00232         print_data(array2);
00233 #endif
00234   rc = waitpid(pid, &status, 0);
00235   exit(0);
00236 }
00237 
 All Data Structures