vm-mix1-fork.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. /* This is creating a program that has
  6. * a few more text pages than the average
  7. * program we usually have.
  8. */
  9. // #define DEBUG
  10. // #define DEBUG_PARENT
  11. // #define DEBUG_CHILD
  12. extern void call_all();
  13. void write_data(unsigned int array[], unsigned int start);
  14. void read_data(unsigned int array[], unsigned int start, const char *array_name);
  15. void print_data(unsigned int array[]);
  16. void do_work(unsigned int start);
  17. #define PAGE_SIZE (4096)
  18. #define DATA_BYTES (3 * 1024 * 1024)
  19. #define PAGES (DATA_BYTES / PAGE_SIZE)
  20. #define ELEM_SIZE (sizeof(unsigned int))
  21. #define ELEMS ((PAGE_SIZE * PAGES / sizeof(unsigned int)) / 2)
  22. #define ELEMS_PER_PAGE (PAGE_SIZE / ELEM_SIZE)
  23. #define NUM_REFS (2)
  24. #define STACK_PAGES_USED (9)
  25. #define STACK_ARRAY_ELEMS (PAGE_SIZE * STACK_PAGES_USED / sizeof(unsigned int))
  26. unsigned int init[] = {
  27. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  28. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  29. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  30. 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  31. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  32. 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  33. };
  34. #define INIT_ARRAY_ELEMS (sizeof(init) / sizeof(int))
  35. unsigned int array1[ELEMS];
  36. unsigned int array2[ELEMS];
  37. void
  38. write_data(unsigned int array[], unsigned int start)
  39. {
  40. unsigned int ref = 0;
  41. unsigned int i = 0;
  42. for (ref = 0; ref < NUM_REFS-1; ref++) {
  43. for (i=0; i<ELEMS; i++) {
  44. array[i] = start + (i / ELEMS_PER_PAGE);
  45. }
  46. }
  47. }
  48. void
  49. read_data(unsigned int array[], unsigned int start, const char *array_name)
  50. {
  51. unsigned int ref = 0;
  52. unsigned int i = 0;
  53. for (ref = 0; ref < NUM_REFS-1; ref++) {
  54. for (i=0; i<ELEMS; i++) {
  55. if (array[i] != (start + (i / ELEMS_PER_PAGE))) {
  56. printf("FAILED in file %s at line %d %s[%d] = %u != %u ref = %d\n",
  57. __FILE__, __LINE__, array_name, i, array[i], i, ref+1);
  58. exit(1);
  59. }
  60. }
  61. }
  62. }
  63. void
  64. print_data(unsigned int array[])
  65. {
  66. unsigned int i = 0;
  67. unsigned int count = 0;
  68. for (i=0; i<ELEMS; i+= (ELEMS_PER_PAGE)) {
  69. printf("[%10u] = %10u ", i, array[i]);
  70. if (((count+1) % 4) == 0) {
  71. printf("\n");
  72. }
  73. count++;
  74. }
  75. printf("\n");
  76. }
  77. void
  78. do_work(unsigned int start)
  79. {
  80. unsigned int stack_array[STACK_ARRAY_ELEMS];
  81. unsigned int i = 0;
  82. unsigned int array1_start = start;
  83. unsigned int array2_start = start + (ELEMS / (ELEMS_PER_PAGE)) + 10;
  84. printf("Checking uninitialized array1 pid = %d\n", getpid());
  85. /* check the uninitialized array1 before initialization */
  86. for (i=0; i<ELEMS; i++) {
  87. if (array1[i] != 0) {
  88. printf("FAILED in file %s at line %d: array1[%d] = %u != %d\n", __FILE__, __LINE__, i, array1[i], 0);
  89. exit(1);
  90. }
  91. }
  92. printf("Checking uninitialized array2 pid = %d\n", getpid());
  93. /* check the uninitialized array2 before initialization */
  94. for (i=0; i<ELEMS; i++) {
  95. if (array2[i] != 0) {
  96. printf("FAILED in file %s at line %d: array2[%d] = %u != %d\n", __FILE__, __LINE__, i, array2[i], 0);
  97. exit(1);
  98. }
  99. }
  100. for (i=0; i<STACK_ARRAY_ELEMS; i++) {
  101. stack_array[i] = i * 1000;
  102. }
  103. for (i=0; i<2; i++) {
  104. call_all();
  105. write_data(array1, array1_start);
  106. call_all();
  107. printf("Checking initialized array1 pid = %d\n", getpid());
  108. read_data(array1, array1_start, "array1");
  109. }
  110. /* check the uninitialized array2 again before initialization */
  111. printf("Checking initialized array2 again pid = %d\n", getpid());
  112. for (i=0; i<ELEMS; i++) {
  113. if (array2[i] != 0) {
  114. printf("FAILED in file %s at line %d: array2[%d] = %u != %d\n", __FILE__, __LINE__, i, array2[i], 0);
  115. exit(1);
  116. }
  117. }
  118. printf("Checking initialized stack_array pid = %d\n", getpid());
  119. for (i=0; i<STACK_ARRAY_ELEMS; i++) {
  120. if (stack_array[i] != i * 1000) {
  121. printf("FAILED in file %s at line %d: stack_array[%d] = %u != %d\n", __FILE__, __LINE__, i, stack_array[i], i);
  122. exit(1);
  123. }
  124. }
  125. printf("Checking initialized init pid = %d\n", getpid());
  126. /* check the initialized array */
  127. for (i=0; i<INIT_ARRAY_ELEMS; i++) {
  128. if (init[i] != i) {
  129. printf("FAILED in file %s at line %d: init[%d] = %u != %d\n", __FILE__, __LINE__, i, init[i], i);
  130. exit(1);
  131. }
  132. }
  133. for (i=0; i<2; i++) {
  134. call_all();
  135. write_data(array2, array2_start);
  136. call_all();
  137. printf("Checking initialized array2 pid = %d\n", getpid());
  138. read_data(array2, array2_start, "array2");
  139. }
  140. printf("Checking initialized stack_array pid = %d\n", getpid());
  141. for (i=0; i<STACK_ARRAY_ELEMS; i++) {
  142. if (stack_array[i] != i * 1000) {
  143. printf("FAILED in file %s at line %d: stack_array[%d] = %u != %d\n", __FILE__, __LINE__, i, stack_array[i], i);
  144. exit(1);
  145. }
  146. }
  147. /* check the initialized array */
  148. printf("Checking initialized init pid = %d\n", getpid());
  149. for (i=0; i<INIT_ARRAY_ELEMS; i++) {
  150. if (init[i] != i) {
  151. printf("FAILED in file %s at line %d: init[%d] = %u != %d\n", __FILE__, __LINE__, i, init[i], i);
  152. exit(1);
  153. }
  154. }
  155. printf("Checking initialized array1 for the last time pid = %d\n", getpid());
  156. read_data(array1, array1_start, "array1");
  157. printf("Checking initialized array2 for the last time pid = %d\n", getpid());
  158. read_data(array2, array2_start, "array2");
  159. printf("Pid = %d SUCCEEDED\n", getpid());
  160. }
  161. int
  162. main()
  163. {
  164. int pid = 0;
  165. int rc = 0;
  166. int status = 0;
  167. #ifdef DEBUG
  168. printf("PAGE_SIZE = %d\n", PAGE_SIZE);
  169. printf("DATA_BYTES = %d\n", DATA_BYTES);
  170. printf("ELEMS = %d\n", ELEMS);
  171. printf("ELEMS_PER_PAGE = %d\n", ELEMS_PER_PAGE);
  172. printf("PAGES = %d\n", PAGES);
  173. printf("Array elements = %d\n", ELEMS);
  174. printf("Pages per array = %d\n", ((ELEMS * sizeof(unsigned int)) / PAGE_SIZE));
  175. #endif
  176. pid = fork();
  177. if (pid < 0) {
  178. printf("Unable to fork\n");
  179. exit(1);
  180. }
  181. if (pid == 0) {
  182. printf("Child pid = %d calling do_work\n", getpid());
  183. do_work(20);
  184. #ifdef DEBUG_CHILD
  185. printf("array 1\n");
  186. print_data(array1);
  187. printf("array 2\n");
  188. print_data(array2);
  189. #endif
  190. exit(0);
  191. }
  192. printf("Parent pid = %d calling do_work\n", getpid());
  193. do_work(1);
  194. #ifdef DEBUG_PARENT
  195. printf("array 1\n");
  196. print_data(array1);
  197. printf("array 2\n");
  198. print_data(array2);
  199. #endif
  200. rc = waitpid(pid, &status, 0);
  201. exit(0);
  202. }