PageRenderTime 67ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/test.c

https://bitbucket.org/tyc1031/cs502
C | 2743 lines | 1588 code | 491 blank | 664 comment | 158 complexity | 275cb323385a166f20cd2dae60cb3916 MD5 | raw file
  1. /************************************************************************
  2. test.c
  3. These programs are designed to test the OS502 functionality
  4. Read Appendix B about test programs and Appendix C concerning
  5. system calls when attempting to understand these programs.
  6. Revision History:
  7. 1.0 August 1990
  8. 1.1 December 1990: Tests cleaned up; 1b, 1e - 1k added
  9. Portability attempted.
  10. 1.2 December 1991: Still working on portabililty.
  11. 1.3 July 1992: tests1i/1j made re-entrant.
  12. 1.4 December 1992: Minor changes - portability
  13. tests2c/2d added. 2f/2g rewritten
  14. 1.5 August 1993: Produced new test2g to replace old
  15. 2g that did a swapping test.
  16. 1.6 June 1995: Test Cleanup.
  17. 1.7 June 1999: Add test0, minor fixes.
  18. 2.0 January 2000: Lots of small changes & bug fixes
  19. 2.1 March 2001: Minor Bugfixes.
  20. Rewrote get_skewed_random_number
  21. 2.2 July 2002: Make appropriate for undergrads
  22. 3.0 August 2004: Modified to support memory mapped IO
  23. 3.1 August 2004: hardware interrupt runs on separate thread
  24. 3.11 August 2004: Support for OS level locking
  25. 3.13 November 2004: Minor fix defining USER
  26. 3.41 August 2009: Additional work for multiprocessor + 64 bit
  27. 3.53 November 2011: Changed test2c so data structure used
  28. ints (4 bytes) rather than longs.
  29. ************************************************************************/
  30. #define USER
  31. #include "global.h"
  32. #include "syscalls.h"
  33. #include "z502.h"
  34. #include "protos.h"
  35. #include "stdio.h"
  36. #include "string.h"
  37. #include "stdlib.h"
  38. #include "math.h"
  39. extern INT16 Z502_PROGRAM_COUNTER;
  40. extern INT32 SYS_CALL_CALL_TYPE;
  41. extern Z502_ARG Z502_ARG1;
  42. extern Z502_ARG Z502_ARG2;
  43. extern Z502_ARG Z502_ARG3;
  44. extern Z502_ARG Z502_ARG4;
  45. extern Z502_ARG Z502_ARG5;
  46. extern Z502_ARG Z502_ARG6;
  47. extern long Z502_REG_1;
  48. extern long Z502_REG_2;
  49. extern long Z502_REG_3;
  50. extern long Z502_REG_4;
  51. extern long Z502_REG_5;
  52. extern long Z502_REG_6;
  53. extern long Z502_REG_7;
  54. extern long Z502_REG_8;
  55. extern long Z502_REG_9;
  56. extern INT16 Z502_MODE;
  57. /* Prototypes for internally called routines. */
  58. void test1x( void );
  59. void test1j_echo( void );
  60. void test2gx( void );
  61. void error_expected( INT32, char[] );
  62. void success_expected( INT32, char[] );
  63. /**************************************************************************
  64. Test0
  65. Exercises GET_TIME_OF_DAY and TERMINATE_PROCESS
  66. Z502_REG_1 Time returned from call
  67. Z502_REG_9 Error returned
  68. **************************************************************************/
  69. void test0( void ) {
  70. SELECT_STEP {
  71. STEP( 0 )
  72. printf( "This is Release %s: Test 0\n", CURRENT_REL );
  73. GET_TIME_OF_DAY( &Z502_REG_1 );
  74. STEP( 1 )
  75. printf( "Time of day is %ld\n", Z502_REG_1 );
  76. TERMINATE_PROCESS( -1, &Z502_REG_9 );
  77. STEP( 2 )
  78. printf( "ERROR: Test should be terminated but isn't.\n");
  79. break;
  80. } // End of SELECT
  81. } // End of test0
  82. /**************************************************************************
  83. Test1a
  84. Exercises GET_TIME_OF_DAY and SLEEP and TERMINATE_PROCESS
  85. Z502_REG_9 Error returned
  86. **************************************************************************/
  87. void test1a( void ) {
  88. static INT32 sleep_time = 100;
  89. static INT32 time1, time2;
  90. SELECT_STEP {
  91. STEP( 0 )
  92. printf( "This is Release %s: Test 1a\n", CURRENT_REL );
  93. GET_TIME_OF_DAY( &time1 );
  94. STEP( 1 )
  95. SLEEP ( sleep_time );
  96. STEP( 2 )
  97. GET_TIME_OF_DAY( &time2 );
  98. STEP( 3 )
  99. printf( "sleep time= %d, elapsed time= %d\n",
  100. sleep_time, time2 - time1 );
  101. TERMINATE_PROCESS( -1, &Z502_REG_9 );
  102. STEP( 4 )
  103. printf( "ERROR: Test should be terminated but isn't.\n");
  104. break;
  105. } /* End of SELECT */
  106. } /* End of test1a */
  107. /**************************************************************************
  108. Test1b
  109. Exercises the CREATE_PROCESS and GET_PROCESS_ID commands.
  110. This test tries lots of different inputs for create_process.
  111. In particular, there are tests for each of the following:
  112. 1. use of illegal priorities
  113. 2. use of a process name of an already existing process.
  114. 3. creation of a LARGE number of processes, showing that
  115. there is a limit somewhere ( you run out of some
  116. resource ) in which case you take appropriate action.
  117. Test the following items for get_process_id:
  118. 1. Various legal process id inputs.
  119. 2. An illegal/non-existant name.
  120. Z502_REG_1, _2 Used as return of process id's.
  121. Z502_REG_3 Cntr of # of processes created.
  122. Z502_REG_9 Used as return of error code.
  123. **************************************************************************/
  124. #define ILLEGAL_PRIORITY -3
  125. #define LEGAL_PRIORITY 10
  126. void test1b( void) {
  127. static char process_name[16];
  128. while (1) {
  129. SELECT_STEP {
  130. /* Try to create a process with an illegal priority. */
  131. STEP( 0 )
  132. printf( "This is Release %s: Test 1b\n", CURRENT_REL );
  133. CREATE_PROCESS( "test1b_a", test1x, ILLEGAL_PRIORITY,
  134. &Z502_REG_1, &Z502_REG_9 );
  135. STEP( 1 )
  136. error_expected( Z502_REG_9, "CREATE_PROCESS" );
  137. /* Create two processes with same name - 1st succeeds, 2nd fails */
  138. CREATE_PROCESS( "two_the_same", test1x, LEGAL_PRIORITY,
  139. &Z502_REG_2, &Z502_REG_9 );
  140. STEP( 2 )
  141. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  142. CREATE_PROCESS( "two_the_same", test1x, LEGAL_PRIORITY,
  143. &Z502_REG_1, &Z502_REG_9 );
  144. STEP( 3 )
  145. error_expected( Z502_REG_9, "CREATE_PROCESS" );
  146. TERMINATE_PROCESS( Z502_REG_2, &Z502_REG_9 );
  147. STEP( 4 )
  148. success_expected( Z502_REG_9, "TERMINATE_PROCESS" );
  149. break;
  150. /* Loop until an error is found on the create_process.
  151. Since the call itself is legal, we must get an error
  152. because we exceed some limit. */
  153. STEP( 5 )
  154. Z502_REG_3++; /* Generate next prog name*/
  155. sprintf( process_name, "Test1b_%ld", Z502_REG_3 );
  156. printf( "Creating process \"%s\"\n", process_name );
  157. CREATE_PROCESS( process_name, test1x, LEGAL_PRIORITY,
  158. &Z502_REG_1, &Z502_REG_9 );
  159. STEP( 6 )
  160. if ( Z502_REG_9 == ERR_SUCCESS )
  161. {
  162. GO_NEXT_TO( 5 ) /* LOOP BACK */
  163. }
  164. break;
  165. /* When we get here, we've created all the processes we can.*/
  166. STEP( 7 )
  167. error_expected( Z502_REG_9, "CREATE_PROCESS" );
  168. printf( "%ld processes were created in all.\n", Z502_REG_3 );
  169. /* Now test the call GET_PROCESS_ID */
  170. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 ); /* Legal */
  171. STEP( 8 )
  172. success_expected( Z502_REG_9, "GET_PROCESS_ID" );
  173. printf( "The PID of this process is %ld\n", Z502_REG_2 );
  174. strcpy( process_name, "Test1b_1" );
  175. GET_PROCESS_ID( process_name, &Z502_REG_1,
  176. &Z502_REG_9 ); /* Legal */
  177. STEP( 9 )
  178. success_expected( Z502_REG_9, "GET_PROCESS_ID" );
  179. printf( "The PID of target process is %ld\n", Z502_REG_1 );
  180. GET_PROCESS_ID( "bogus_name", &Z502_REG_1,
  181. &Z502_REG_9 ); /* Illegal */
  182. STEP( 10 )
  183. error_expected( Z502_REG_9, "GET_PROCESS_ID" );
  184. GET_TIME_OF_DAY( &Z502_REG_4 );
  185. STEP( 11 )
  186. printf( "Test1b, PID %ld, Ends at Time %ld\n",
  187. Z502_REG_2, Z502_REG_4);
  188. TERMINATE_PROCESS( -2, &Z502_REG_9 )
  189. } /* End of SELECT */
  190. } /* End of while */
  191. } /* End of test1b */
  192. /**************************************************************************
  193. Test1c
  194. Tests multiple copies of test1x running simultaneously.
  195. Test1c runs these with the same priority in order to show
  196. FCFS scheduling behavior; Test1d uses different priorities
  197. in order to show priority scheduling.
  198. WARNING: This test assumes tests 1a - 1b run successfully
  199. Z502_REG_1, 2, 3, 4, 5 Used as return of process id's.
  200. Z502_REG_6 Return of PID on GET_PROCESS_ID
  201. Z502_REG_9 Used as return of error code.
  202. **************************************************************************/
  203. #define PRIORITY1C 10
  204. void test1c( void)
  205. {
  206. static INT32 sleep_time = 1000;
  207. while( 1 )
  208. {
  209. SELECT_STEP
  210. {
  211. STEP( 0 )
  212. printf( "This is Release %s: Test 1c\n", CURRENT_REL );
  213. CREATE_PROCESS( "test1c_a", test1x, PRIORITY1C,
  214. &Z502_REG_1, &Z502_REG_9 );
  215. STEP( 1 )
  216. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  217. CREATE_PROCESS( "test1c_b", test1x, PRIORITY1C,
  218. &Z502_REG_2, &Z502_REG_9 );
  219. STEP( 2 )
  220. CREATE_PROCESS( "test1c_c", test1x, PRIORITY1C,
  221. &Z502_REG_3, &Z502_REG_9 );
  222. STEP( 3 )
  223. CREATE_PROCESS( "test1c_d", test1x, PRIORITY1C,
  224. &Z502_REG_4, &Z502_REG_9 );
  225. STEP( 4 )
  226. CREATE_PROCESS( "test1c_e", test1x, PRIORITY1C,
  227. &Z502_REG_5, &Z502_REG_9 );
  228. /* In these next three cases, we will loop until the target
  229. process ( test1c_e ) has terminated. We know it
  230. terminated because for a while we get success on the call
  231. GET_PROCESS_ID, and then we get failure when the process
  232. no longer exists. */
  233. STEP( 5 )
  234. SLEEP ( sleep_time );
  235. STEP( 6 )
  236. GET_PROCESS_ID( "test1c_e", &Z502_REG_6, &Z502_REG_9 );
  237. STEP( 7 )
  238. if ( Z502_REG_9 == ERR_SUCCESS )
  239. GO_NEXT_TO( 5 ) /* Loop back */
  240. break;
  241. STEP( 8 )
  242. TERMINATE_PROCESS( -2, &Z502_REG_9 ); /* Terminate all */
  243. } /* End switch */
  244. } /* End while */
  245. } /* End test1c */
  246. /**************************************************************************
  247. Test 1d
  248. Tests multiple copies of test1x running simultaneously.
  249. Test1c runs these with the same priority in order to show
  250. FCFS scheduling behavior; Test1d uses different priorities
  251. in order to show priority scheduling.
  252. WARNING: This test assumes tests 1a - 1b run successfully
  253. Z502_REG_1, 2, 3, 4, 5 Used as return of process id's.
  254. Z502_REG_6 Return of PID on GET_PROCESS_ID
  255. Z502_REG_9 Used as return of error code.
  256. **************************************************************************/
  257. #define PRIORITY1 10
  258. #define PRIORITY2 11
  259. #define PRIORITY3 11
  260. #define PRIORITY4 90
  261. #define PRIORITY5 40
  262. void test1d( void)
  263. {
  264. static INT32 sleep_time = 1000;
  265. while( 1 )
  266. {
  267. SELECT_STEP
  268. {
  269. STEP( 0 )
  270. printf( "This is Release %s: Test 1d\n", CURRENT_REL );
  271. CREATE_PROCESS( "test1d_1", test1x, PRIORITY1,
  272. &Z502_REG_1, &Z502_REG_9 );
  273. STEP( 1 )
  274. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  275. CREATE_PROCESS( "test1d_2", test1x, PRIORITY2,
  276. &Z502_REG_2, &Z502_REG_9 );
  277. STEP( 2 )
  278. CREATE_PROCESS( "test1d_3", test1x, PRIORITY3,
  279. &Z502_REG_3, &Z502_REG_9 );
  280. STEP( 3 )
  281. CREATE_PROCESS( "test1d_4", test1x, PRIORITY4,
  282. &Z502_REG_4, &Z502_REG_9 );
  283. STEP( 4 )
  284. CREATE_PROCESS( "test1d_5", test1x, PRIORITY5,
  285. &Z502_REG_5, &Z502_REG_9 );
  286. /* We will loop until the target process ( test1d_4 ) has terminated.
  287. We know it terminated because for a while we get success on the call
  288. GET_PROCESS_ID, and then failure when the process no longer exists. */
  289. STEP( 5 )
  290. SLEEP ( sleep_time );
  291. STEP( 6 )
  292. GET_PROCESS_ID( "test1d_4", &Z502_REG_6, &Z502_REG_9 );
  293. STEP( 7 )
  294. if ( Z502_REG_9 == ERR_SUCCESS )
  295. GO_NEXT_TO( 5 ) /* Loop back */
  296. break;
  297. STEP( 8 )
  298. TERMINATE_PROCESS( -2, &Z502_REG_9 );
  299. } /* End switch */
  300. } /* End while */
  301. } /* End test1d */
  302. /**************************************************************************
  303. Test 1e exercises the SUSPEND_PROCESS and RESUME_PROCESS commands
  304. This test should try lots of different inputs for suspend and resume.
  305. In particular, there should be tests for each of the following:
  306. 1. use of illegal process id.
  307. 2. what happens when you suspend yourself - is it legal? The answer
  308. to this depends on the OS architecture and is up to the developer.
  309. 3. suspending an already suspended process.
  310. 4. resuming a process that's not suspended.
  311. there are probably lots of other conditions possible.
  312. Z502_REG_1 Target process ID
  313. Z502_REG_2 OUR process ID
  314. Z502_REG_9 Error returned
  315. **************************************************************************/
  316. #define LEGAL_PRIORITY_1E 10
  317. void test1e( void)
  318. {
  319. SELECT_STEP
  320. {
  321. STEP( 0 ) /* Get OUR PID */
  322. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  323. STEP( 1 ) /* Make legal target */
  324. printf( "Release %s:Test 1e: Pid %ld\n", CURRENT_REL, Z502_REG_2 );
  325. CREATE_PROCESS( "test1e_a", test1x, LEGAL_PRIORITY_1E,
  326. &Z502_REG_1, &Z502_REG_9);
  327. STEP( 2 )
  328. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  329. /* Suspend Illegal PID */
  330. SUSPEND_PROCESS( (INT32)9999, &Z502_REG_9);
  331. STEP( 3 )
  332. error_expected( Z502_REG_9, "SUSPEND_PROCESS" );
  333. /* Resume Illegal PID */
  334. RESUME_PROCESS( (INT32)9999, &Z502_REG_9);
  335. STEP( 4 )
  336. error_expected( Z502_REG_9, "RESUME_PROCESS" );
  337. /* Suspend legal PID */
  338. SUSPEND_PROCESS(Z502_REG_1, &Z502_REG_9);
  339. STEP( 5 )
  340. success_expected( Z502_REG_9, "SUSPEND_PROCESS" );
  341. /* Suspend already suspended PID */
  342. SUSPEND_PROCESS(Z502_REG_1, &Z502_REG_9);
  343. STEP( 6 )
  344. error_expected( Z502_REG_9, "SUSPEND_PROCESS" );
  345. /* Do a legal resume */
  346. RESUME_PROCESS(Z502_REG_1, &Z502_REG_9);
  347. STEP( 7 )
  348. success_expected( Z502_REG_9, "RESUME_PROCESS" );
  349. /* Resume an already resumed process */
  350. RESUME_PROCESS(Z502_REG_1, &Z502_REG_9);
  351. STEP( 8 )
  352. error_expected( Z502_REG_9, "RESUME_PROCESS" );
  353. /* Try to resume ourselves */
  354. RESUME_PROCESS(Z502_REG_2, &Z502_REG_9);
  355. STEP( 9 )
  356. error_expected( Z502_REG_9, "RESUME_PROCESS" );
  357. /* It may or may not be legal to suspend ourselves;
  358. architectural decision. */
  359. SUSPEND_PROCESS(-1, &Z502_REG_9);
  360. STEP( 10 )
  361. /* If we returned "SUCCESS" here, then there is an inconsistancy;
  362. * success implies that the process was suspended. But if we
  363. * get here, then we obviously weren't suspended. Therefore
  364. * this must be an error. */
  365. error_expected( Z502_REG_9, "SUSPEND_PROCESS" );
  366. GET_TIME_OF_DAY( &Z502_REG_4 );
  367. STEP( 11 )
  368. printf( "Test1e, PID %ld, Ends at Time %ld\n", Z502_REG_2, Z502_REG_4);
  369. TERMINATE_PROCESS(-2, &Z502_REG_9);
  370. } /* End of SELECT */
  371. } /* End of test1e */
  372. /**************************************************************************
  373. Test1f Successfully suspend and resume processes.
  374. In particular, show what happens to scheduling when processes
  375. are temporarily suspended.
  376. This test works by starting up a number of processes at different
  377. priorities. Then some of them are suspended. Then some are resumed.
  378. Z502_REG_1 Loop counter
  379. Z502_REG_2 OUR process ID
  380. Z502_REG_3,4,5,6,7 Target process ID
  381. Z502_REG_9 Error returned
  382. **************************************************************************/
  383. #define PRIORITY_1F1 5
  384. #define PRIORITY_1F2 10
  385. #define PRIORITY_1F3 15
  386. #define PRIORITY_1F4 20
  387. #define PRIORITY_1F5 25
  388. void test1f( void)
  389. {
  390. static INT32 sleep_time = 300;
  391. SELECT_STEP
  392. {
  393. STEP( 0 ) /* Get OUR PID */
  394. Z502_REG_1 = 0; /* Initialize */
  395. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  396. STEP( 1 ) /* Make legal target */
  397. printf( "Release %s:Test 1f: Pid %ld\n",
  398. CURRENT_REL, Z502_REG_2 );
  399. CREATE_PROCESS( "test1f_a", test1x, PRIORITY_1F1,
  400. &Z502_REG_3, &Z502_REG_9);
  401. STEP( 2 ) /* Make legal target */
  402. CREATE_PROCESS( "test1f_b", test1x, PRIORITY_1F2,
  403. &Z502_REG_4, &Z502_REG_9);
  404. STEP( 3 ) /* Make legal target */
  405. CREATE_PROCESS( "test1f_c", test1x, PRIORITY_1F3,
  406. &Z502_REG_5, &Z502_REG_9);
  407. STEP( 4 ) /* Make legal target */
  408. CREATE_PROCESS( "test1f_d", test1x, PRIORITY_1F4,
  409. &Z502_REG_6, &Z502_REG_9);
  410. STEP( 5 ) /* Make legal target */
  411. CREATE_PROCESS( "test1f_e", test1x, PRIORITY_1F5,
  412. &Z502_REG_7, &Z502_REG_9);
  413. /* Let the 5 pids go for a bit */
  414. STEP( 6 )
  415. SLEEP ( sleep_time );
  416. /* Suspend 3 of the pids and see what happens - we
  417. should see scheduling behavior where the processes
  418. are yanked out of the ready and the waiting states,
  419. and placed into the suspended state. */
  420. STEP( 7 )
  421. SUSPEND_PROCESS(Z502_REG_3, &Z502_REG_9);
  422. STEP( 8 )
  423. SUSPEND_PROCESS(Z502_REG_5, &Z502_REG_9);
  424. STEP( 9 )
  425. SUSPEND_PROCESS(Z502_REG_7, &Z502_REG_9);
  426. STEP( 10 )
  427. SLEEP ( sleep_time );
  428. STEP( 11 )
  429. RESUME_PROCESS(Z502_REG_3, &Z502_REG_9);
  430. STEP( 12 )
  431. RESUME_PROCESS(Z502_REG_5, &Z502_REG_9);
  432. STEP( 13 )
  433. if ( Z502_REG_1 < 4 )
  434. GO_NEXT_TO( 6 )
  435. Z502_REG_1++; /* Inc the loop counter */
  436. RESUME_PROCESS(Z502_REG_7, &Z502_REG_9);
  437. /* Wait for children to finish, then quit */
  438. STEP( 14 )
  439. SLEEP ( (INT32)10000 );
  440. STEP( 15 )
  441. TERMINATE_PROCESS(-1, &Z502_REG_9);
  442. } /* End of SELECT */
  443. } /* End of test1f */
  444. /**************************************************************************
  445. Test1g Generate lots of errors for CHANGE_PRIORITY
  446. Try lots of different inputs: In particular, some of the possible
  447. inputs include:
  448. 1. use of illegal priorities
  449. 2. use of an illegal process id.
  450. Z502_REG_1 Target process ID
  451. Z502_REG_2 OUR process ID
  452. Z502_REG_9 Error returned
  453. **************************************************************************/
  454. #define LEGAL_PRIORITY_1G 10
  455. #define ILLEGAL_PRIORITY_1G 999
  456. void test1g( void)
  457. {
  458. SELECT_STEP
  459. {
  460. STEP( 0 ) /* Get OUR PID */
  461. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  462. STEP( 1 ) /* Make legal target */
  463. printf( "Release %s:Test 1g: Pid %ld\n", CURRENT_REL, Z502_REG_2 );
  464. CREATE_PROCESS( "test1g_a", test1x, LEGAL_PRIORITY_1G,
  465. &Z502_REG_1, &Z502_REG_9);
  466. STEP( 2 )
  467. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  468. /* Target Illegal PID */
  469. CHANGE_PRIORITY( (INT32)9999, LEGAL_PRIORITY_1G, &Z502_REG_9);
  470. STEP( 3 )
  471. error_expected( Z502_REG_9, "CHANGE_PRIORITY" );
  472. /* Use illegal priority */
  473. CHANGE_PRIORITY( Z502_REG_1, ILLEGAL_PRIORITY_1G, &Z502_REG_9);
  474. STEP( 4 )
  475. error_expected( Z502_REG_9, "CHANGE_PRIORITY" );
  476. // Change made - I assume both proce
  477. TERMINATE_PROCESS(-2, &Z502_REG_9);
  478. } /* End of SELECT */
  479. } /* End of test1g */
  480. /**************************************************************************
  481. Test1h Successfully change the priority of a process
  482. When you change the priority, it should be possible to see
  483. the scheduling behaviour of the system change; processes
  484. that used to be scheduled first are no longer first.
  485. Z502_REG_2 OUR process ID
  486. Z502_REG_3 - 5 Target process IDs
  487. Z502_REG_9 Error returned
  488. **************************************************************************/
  489. #define MOST_FAVORABLE_PRIORITY 1
  490. #define FAVORABLE_PRIORITY 10
  491. #define NORMAL_PRIORITY 20
  492. #define LEAST_FAVORABLE_PRIORITY 30
  493. void test1h( void)
  494. {
  495. INT32 ourself;
  496. SELECT_STEP
  497. {
  498. STEP( 0 ) /* Get OUR PID */
  499. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  500. STEP( 1 ) /* Make our priority high */
  501. printf( "Release %s:Test 1h: Pid %ld\n",
  502. CURRENT_REL, Z502_REG_2 );
  503. ourself = -1;
  504. CHANGE_PRIORITY( ourself, MOST_FAVORABLE_PRIORITY,
  505. &Z502_REG_9);
  506. STEP( 2 ) /* Make legal targets */
  507. CREATE_PROCESS( "test1h_a", test1x, NORMAL_PRIORITY,
  508. &Z502_REG_3, &Z502_REG_9);
  509. STEP( 3 ) /* Make legal targets */
  510. CREATE_PROCESS( "test1h_b", test1x, NORMAL_PRIORITY,
  511. &Z502_REG_4, &Z502_REG_9);
  512. STEP( 4 ) /* Make legal targets */
  513. CREATE_PROCESS( "test1h_c", test1x, NORMAL_PRIORITY,
  514. &Z502_REG_5, &Z502_REG_9);
  515. /* Sleep awhile to watch the scheduling */
  516. STEP( 5 )
  517. SLEEP( 200 );
  518. /* Now change the priority - it should be possible to see
  519. that the priorities have been changed for processes that
  520. are ready and for processes that are sleeping. */
  521. STEP( 6 )
  522. CHANGE_PRIORITY( Z502_REG_3, FAVORABLE_PRIORITY,
  523. &Z502_REG_9);
  524. STEP( 7 )
  525. CHANGE_PRIORITY( Z502_REG_5, LEAST_FAVORABLE_PRIORITY,
  526. &Z502_REG_9);
  527. /* Sleep awhile to watch the scheduling */
  528. STEP( 8 )
  529. SLEEP( 200 );
  530. /* Now change the priority - it should be possible to see
  531. that the priorities have been changed for processes that
  532. are ready and for processes that are sleeping. */
  533. STEP( 9 )
  534. CHANGE_PRIORITY( Z502_REG_3, LEAST_FAVORABLE_PRIORITY,
  535. &Z502_REG_9);
  536. STEP( 10 )
  537. CHANGE_PRIORITY( Z502_REG_4, FAVORABLE_PRIORITY,
  538. &Z502_REG_9);
  539. /* Sleep awhile to watch the scheduling */
  540. STEP( 11 )
  541. SLEEP( 600 );
  542. STEP( 12 )
  543. TERMINATE_PROCESS(-2, &Z502_REG_9);
  544. } /* End of SELECT */
  545. } /* End of test1h */
  546. /**************************************************************************
  547. Test1i SEND_MESSAGE and RECEIVE_MESSAGE with errors.
  548. This has the same kind of error conditions that previous tests did;
  549. bad PIDs, bad message lengths, illegal buffer addresses, etc.
  550. Your imagination can go WILD on this one.
  551. This is a good time to mention os_switch_context_complete:::::
  552. As you know, after doing a switch_context, the hardware passes
  553. control to the code in this test. What hasn't been obvious thus
  554. far, is that control passes from swich_context, THEN to routine,
  555. os_switch_context_complete, and THEN to this test code.
  556. What it does: This function allows you to gain control in the
  557. OS of a scheduled-in process before it goes to test.
  558. Where to find it: The code is in base.c - right now it does nothing.
  559. Why use it: Suppose process A has sent a message to
  560. process B. It so happens that you may well want
  561. to do some preparation in process B once it's
  562. registers are in memory, but BEFORE it executes
  563. the test. In other words, it allows you to
  564. complete the work for the send to process B.
  565. Z502_REG_1 Pointer to data private to each process
  566. running this routine.
  567. Z502_REG_2 OUR process ID
  568. Z502_REG_3 Target process IDs
  569. Z502_REG_9 Error returned
  570. **************************************************************************/
  571. #define LEGAL_MESSAGE_LENGTH (INT16)64
  572. #define ILLEGAL_MESSAGE_LENGTH (INT16)1000
  573. #define MOST_FAVORABLE_PRIORITY 1
  574. #define NORMAL_PRIORITY 20
  575. typedef struct
  576. {
  577. INT32 target_pid;
  578. INT32 source_pid;
  579. INT32 actual_source_pid;
  580. INT32 send_length;
  581. INT32 receive_length;
  582. INT32 actual_send_length;
  583. INT32 loop_count;
  584. char msg_buffer[LEGAL_MESSAGE_LENGTH];
  585. } TEST1I_DATA;
  586. void test1i( void)
  587. {
  588. TEST1I_DATA *td; /* Use as ptr to data */
  589. /* Here we maintain the data to be used by this process when running
  590. on this routine. This code should be re-entrant. */
  591. if ( Z502_REG_1 == 0 )
  592. {
  593. Z502_REG_1 = (long)calloc( 1, sizeof ( TEST1I_DATA ));
  594. if ( Z502_REG_1 == 0 )
  595. {
  596. printf( "Something screwed up allocating space in test1i\n" );
  597. }
  598. td = ( TEST1I_DATA *)Z502_REG_1;
  599. td->loop_count = 0;
  600. }
  601. td = ( TEST1I_DATA *)Z502_REG_1;
  602. while ( 1 )
  603. {
  604. SELECT_STEP
  605. {
  606. STEP( 0 ) /* Get OUR PID */
  607. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  608. STEP( 1 ) /* Make our prior high */
  609. printf( "Release %s:Test 1i: Pid %ld\n", CURRENT_REL, Z502_REG_2 );
  610. CHANGE_PRIORITY( -1, MOST_FAVORABLE_PRIORITY, &Z502_REG_9);
  611. STEP( 2 ) /* Make legal targets */
  612. CREATE_PROCESS( "test1i_a", test1x, NORMAL_PRIORITY,
  613. &Z502_REG_3, &Z502_REG_9);
  614. STEP( 3 ) /* Send to illegal process */
  615. td->target_pid = 9999;
  616. td->send_length= 8;
  617. SEND_MESSAGE( td->target_pid, "message", td->send_length, &Z502_REG_9 );
  618. STEP( 4 )
  619. error_expected( Z502_REG_9, "SEND_MESSAGE" );
  620. /* Try an illegal message length */
  621. td->target_pid = Z502_REG_3;
  622. td->send_length= ILLEGAL_MESSAGE_LENGTH;
  623. SEND_MESSAGE( td->target_pid, "message", td->send_length, &Z502_REG_9 );
  624. STEP( 5 )
  625. error_expected( Z502_REG_9, "SEND_MESSAGE" );
  626. /* Receive from illegal process */
  627. td->source_pid = 9999;
  628. td->receive_length = LEGAL_MESSAGE_LENGTH;
  629. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  630. td->receive_length, &(td->actual_send_length),
  631. &(td->actual_source_pid), &Z502_REG_9 );
  632. STEP( 6 )
  633. error_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  634. /* Receive with illegal buffer size */
  635. td->source_pid = Z502_REG_3;
  636. td->receive_length = ILLEGAL_MESSAGE_LENGTH;
  637. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  638. td->receive_length, &(td->actual_send_length),
  639. &(td->actual_source_pid), &Z502_REG_9 );
  640. STEP( 7 )
  641. error_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  642. /* Send a legal ( but long ) message to self */
  643. td->target_pid = Z502_REG_2;
  644. td->send_length= LEGAL_MESSAGE_LENGTH;
  645. SEND_MESSAGE( td->target_pid, "a long but legal message",
  646. td->send_length, &Z502_REG_9 );
  647. STEP( 8 )
  648. success_expected( Z502_REG_9, "SEND_MESSAGE" );
  649. td->loop_count++;
  650. /* Receive this long message, which should error
  651. because the receive buffer is too small */
  652. td->source_pid = Z502_REG_2;
  653. td->receive_length = 10;
  654. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  655. td->receive_length, &(td->actual_send_length),
  656. &(td->actual_source_pid), &Z502_REG_9 );
  657. STEP( 9 )
  658. error_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  659. break;
  660. /* Keep sending legal messages until the architectural
  661. limit for buffer space is exhausted. In order to pass
  662. the test1j, this number should be at least EIGHT */
  663. STEP( 10 )
  664. td->target_pid = Z502_REG_3;
  665. td->send_length= LEGAL_MESSAGE_LENGTH;
  666. SEND_MESSAGE( td->target_pid, "message", td->send_length, &Z502_REG_9 );
  667. STEP( 11 )
  668. if (Z502_REG_9 == ERR_SUCCESS)
  669. GO_NEXT_TO( 10 ) /* Loop back */
  670. td->loop_count++;
  671. break;
  672. STEP( 12 )
  673. printf( "A total of %d messages were enqueued.\n", td->loop_count - 1 );
  674. TERMINATE_PROCESS(-2, &Z502_REG_9);
  675. } /* End of SELECT */
  676. } /* End of while */
  677. } /* End of test1i */
  678. /**************************************************************************
  679. Test1j SEND_MESSAGE and RECEIVE_MESSAGE Successfully.
  680. Creates three other processes, each running their own code.
  681. RECEIVE and SEND messages are winged back and forth at them.
  682. Z502_REG_1 Pointer to data private to each process
  683. running this routine.
  684. Z502_REG_2 OUR process ID
  685. Z502_REG_3 - 5 Target process IDs
  686. Z502_REG_9 Error returned
  687. Again, as mentioned in detail on Test1i, use of the code in
  688. os_switch_context_complete could be beneficial here. In fact
  689. it will be difficult to make the test work successfully UNLESS
  690. you use the os_switch_context_complete().
  691. The SEND and RECEIVE system calls as implemented by this test
  692. imply the following behavior:
  693. SENDER = PID A RECEIVER = PID B,
  694. Designates source_pid =
  695. target_pid = A C -1
  696. ----------------+------------+------------+--------------+
  697. | | | |
  698. B | Message | X | Message |
  699. |Transmitted | | Transmitted |
  700. ----------------+------------+------------+--------------+
  701. | | | |
  702. C | X | X | X |
  703. | | | |
  704. ----------------+------------+------------+--------------+
  705. | | | |
  706. -1 | Message | X | Message |
  707. | Transmitted| | Transmitted |
  708. ----------------+------------+------------+--------------+
  709. A broadcast ( target_pid = -1 ) means send to everyone BUT yourself.
  710. ANY of the receiving processes can handle a broadcast message.
  711. A receive ( source_pid = -1 ) means receive from anyone.
  712. **************************************************************************/
  713. #define LEGAL_MESSAGE_LENGTH (INT16)64
  714. #define ILLEGAL_MESSAGE_LENGTH (INT16)1000
  715. #define MOST_FAVORABLE_PRIORITY 1
  716. #define NORMAL_PRIORITY 20
  717. typedef struct
  718. {
  719. INT32 target_pid;
  720. INT32 source_pid;
  721. INT32 actual_source_pid;
  722. INT32 send_length;
  723. INT32 receive_length;
  724. INT32 actual_send_length;
  725. INT32 send_loop_count;
  726. INT32 receive_loop_count;
  727. char msg_buffer[LEGAL_MESSAGE_LENGTH];
  728. char msg_sent[LEGAL_MESSAGE_LENGTH];
  729. } TEST1J_DATA;
  730. void test1j( void)
  731. {
  732. TEST1J_DATA *td; /* Use as ptr to data */
  733. /* Here we maintain the data to be used by this process when running
  734. on this routine. This code should be re-entrant. */
  735. if ( Z502_REG_1 == 0 )
  736. {
  737. Z502_REG_1 = (long)calloc( 1, sizeof ( TEST1J_DATA ));
  738. if ( Z502_REG_1 == 0 )
  739. {
  740. printf( "Something screwed up allocating space in test1j\n" );
  741. }
  742. td = ( TEST1J_DATA *)Z502_REG_1;
  743. td->send_loop_count = 0;
  744. td->receive_loop_count = 0;
  745. }
  746. td = ( TEST1J_DATA *)Z502_REG_1;
  747. while ( 1 )
  748. {
  749. SELECT_STEP
  750. {
  751. STEP( 0 ) /* Get OUR PID */
  752. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  753. STEP( 1 ) /* Make our prior high */
  754. printf( "Release %s:Test 1j: Pid %ld\n",
  755. CURRENT_REL, Z502_REG_2 );
  756. CHANGE_PRIORITY( -1, MOST_FAVORABLE_PRIORITY,
  757. &Z502_REG_9);
  758. STEP( 2 ) /* Make legal targets */
  759. success_expected( Z502_REG_9, "CHANGE_PRIORITY" );
  760. CREATE_PROCESS( "test1j_1", test1j_echo, NORMAL_PRIORITY,
  761. &Z502_REG_3, &Z502_REG_9);
  762. STEP( 3 ) /* Make legal targets */
  763. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  764. CREATE_PROCESS( "test1j_2", test1j_echo, NORMAL_PRIORITY,
  765. &Z502_REG_4, &Z502_REG_9);
  766. STEP( 4 ) /* Make legal targets */
  767. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  768. CREATE_PROCESS( "test1j_3", test1j_echo, NORMAL_PRIORITY,
  769. &Z502_REG_5, &Z502_REG_9);
  770. STEP( 5 )
  771. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  772. /* Send/receive a legal message to each child */
  773. td->target_pid = Z502_REG_3;
  774. td->send_length= 20;
  775. strcpy( td->msg_sent, "message to #3" );
  776. SEND_MESSAGE( td->target_pid, td->msg_sent,
  777. td->send_length, &Z502_REG_9 );
  778. STEP( 6 )
  779. success_expected( Z502_REG_9, "SEND_MESSAGE" );
  780. td->source_pid = -1;
  781. td->receive_length = LEGAL_MESSAGE_LENGTH;
  782. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  783. td->receive_length, &(td->actual_send_length),
  784. &(td->actual_source_pid), &Z502_REG_9 );
  785. STEP( 7 )
  786. success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  787. if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
  788. printf("ERROR - msg sent != msg received.\n");
  789. if ( td->actual_source_pid != Z502_REG_3 )
  790. printf( "ERROR - source PID not correct.\n" );
  791. if ( td->actual_send_length != td->send_length )
  792. printf( "ERROR - send length not sent correctly.\n" );
  793. td->target_pid = Z502_REG_4;
  794. td->send_length= 20;
  795. strcpy( td->msg_sent, "message to #4" );
  796. SEND_MESSAGE( td->target_pid, td->msg_sent,
  797. td->send_length, &Z502_REG_9 );
  798. STEP( 8 )
  799. success_expected( Z502_REG_9, "SEND_MESSAGE" );
  800. td->source_pid = -1;
  801. td->receive_length = LEGAL_MESSAGE_LENGTH;
  802. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  803. td->receive_length, &(td->actual_send_length),
  804. &(td->actual_source_pid), &Z502_REG_9 );
  805. STEP( 9 )
  806. success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  807. if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
  808. printf("ERROR - msg sent != msg received.\n");
  809. if ( td->actual_source_pid != Z502_REG_4 )
  810. printf( "ERROR - source PID not correct.\n" );
  811. if ( td->actual_send_length != td->send_length )
  812. printf( "ERROR - send length not sent correctly.\n" );
  813. td->target_pid = Z502_REG_5;
  814. td->send_length= 20;
  815. strcpy( td->msg_sent, "message to #5" );
  816. SEND_MESSAGE( td->target_pid, td->msg_sent,
  817. td->send_length, &Z502_REG_9 );
  818. STEP( 10 )
  819. success_expected( Z502_REG_9, "SEND_MESSAGE" );
  820. td->source_pid = -1;
  821. td->receive_length = LEGAL_MESSAGE_LENGTH;
  822. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  823. td->receive_length, &(td->actual_send_length),
  824. &(td->actual_source_pid), &Z502_REG_9 );
  825. STEP( 11 )
  826. success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  827. if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
  828. printf("ERROR - msg sent != msg received.\n");
  829. if ( td->actual_source_pid != Z502_REG_5 )
  830. printf( "ERROR - source PID not correct.\n" );
  831. if ( td->actual_send_length != td->send_length )
  832. printf( "ERROR - send length not sent correctly.\n" );
  833. break; // Bugfix 08/2012 - Rel 3.60 so we explicitly
  834. // go to the next step
  835. /* Keep sending legal messages until the architectural (OS)
  836. limit for buffer space is exhausted. */
  837. STEP( 12 )
  838. td->target_pid = -1;
  839. sprintf( td->msg_sent, "This is message %d",
  840. td->send_loop_count );
  841. td->send_length= 20;
  842. SEND_MESSAGE( td->target_pid, td->msg_sent,
  843. td->send_length, &Z502_REG_9 );
  844. STEP( 13 )
  845. if (Z502_REG_9 == ERR_SUCCESS)
  846. GO_NEXT_TO( 12 ) /* Loop back */
  847. td->send_loop_count++;
  848. break;
  849. STEP( 14 )
  850. td->send_loop_count--;
  851. printf( "A total of %d messages were enqueued.\n",
  852. td->send_loop_count );
  853. break;
  854. STEP( 15 )
  855. td->source_pid = -1;
  856. td->receive_length = LEGAL_MESSAGE_LENGTH;
  857. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  858. td->receive_length, &(td->actual_send_length),
  859. &(td->actual_source_pid), &Z502_REG_9 );
  860. STEP( 16 )
  861. success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  862. printf( "Receive from PID = %d: length = %d: msg = %s:\n",
  863. td->actual_source_pid, td->actual_send_length,
  864. td->msg_buffer );
  865. td->receive_loop_count++;
  866. if ( td->receive_loop_count < td->send_loop_count )
  867. GO_NEXT_TO( 15 ) /* Loop back */
  868. break;
  869. STEP( 17 )
  870. printf( "A total of %d messages were received.\n",
  871. td->receive_loop_count - 1 );
  872. TERMINATE_PROCESS(-2, &Z502_REG_9);
  873. } /* End of SELECT */
  874. } /* End of while */
  875. } /* End of test1j */
  876. /**************************************************************************
  877. Test1k Test other oddities in your system.
  878. There are many other strange effects, not taken into account
  879. by the previous tests. One of these is:
  880. 1. Executing a privileged instruction from a user program
  881. Registers Used:
  882. Z502_REG_2 OUR process ID
  883. Z502_REG_9 Error returned
  884. **************************************************************************/
  885. void test1k( void)
  886. {
  887. INT32 Result;
  888. SELECT_STEP
  889. {
  890. STEP( 0 )
  891. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  892. STEP( 1 )
  893. printf( "Release %s:Test 1k: Pid %ld\n", CURRENT_REL, Z502_REG_2 );
  894. /* Do an illegal hardware instruction - we will
  895. not return from this. */
  896. MEM_READ( Z502TimerStatus, &Result);
  897. } /* End of SELECT */
  898. } /* End of test1k */
  899. /**************************************************************************
  900. Test1l SEND_MESSAGE and RECEIVE_MESSAGE with SUSPEND/RESUME
  901. Explores how message handling is done in the midst of SUSPEND/RESUME
  902. system calls,
  903. The SEND and RECEIVE system calls as implemented by this test
  904. imply the following behavior:
  905. Case 1:
  906. - a process waiting to recieve a message can be suspended
  907. - a process waiting to recieve a message can be resumed
  908. - after being resumed, it can receive a message
  909. Case 2:
  910. - when a process waiting for a message is suspended, it is out of
  911. circulation and cannot recieve any message
  912. - once it is unsuspended, it may recieve a message and go on the ready
  913. queue
  914. Case 3:
  915. - a process that waited for and found a message is now the ready queue
  916. - this process can be suspended before handling the message
  917. - the message and process remain paired up, no other process can have
  918. that message
  919. - when resumed, the process will handle the message
  920. **************************************************************************/
  921. #define LEGAL_MESSAGE_LENGTH (INT16)64
  922. #define MOST_FAVORABLE_PRIORITY 1
  923. #define NORMAL_PRIORITY 20
  924. typedef struct
  925. {
  926. INT32 target_pid;
  927. INT32 source_pid;
  928. INT32 actual_source_pid;
  929. INT32 send_length;
  930. INT32 receive_length;
  931. INT32 actual_send_length;
  932. INT32 send_loop_count;
  933. INT32 receive_loop_count;
  934. char msg_buffer[LEGAL_MESSAGE_LENGTH];
  935. char msg_sent[LEGAL_MESSAGE_LENGTH];
  936. } TEST1L_DATA;
  937. void test1l( void)
  938. {
  939. TEST1L_DATA *td; /* Use as ptr to data */
  940. /* Here we maintain the data to be used by this process when running
  941. on this routine. This code should be re-entrant. */
  942. if ( Z502_REG_1 == 0 )
  943. {
  944. Z502_REG_1 = (long)calloc( 1, sizeof ( TEST1L_DATA ));
  945. if ( Z502_REG_1 == 0 )
  946. {
  947. printf( "Something screwed up allocating space in test1j\n" );
  948. }
  949. td = ( TEST1L_DATA *)Z502_REG_1;
  950. td->send_loop_count = 0;
  951. td->receive_loop_count = 0;
  952. }
  953. td = ( TEST1L_DATA *)Z502_REG_1;
  954. while ( 1 )
  955. {
  956. SELECT_STEP
  957. {
  958. STEP( 0 ) /* Get OUR PID */
  959. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  960. STEP( 1 ) /* Make our prior high */
  961. printf( "Release %s:Test 1l: Pid %ld\n",
  962. CURRENT_REL, Z502_REG_2 );
  963. CHANGE_PRIORITY( -1, MOST_FAVORABLE_PRIORITY,
  964. &Z502_REG_9);
  965. STEP( 2 ) /* Make process to test with */
  966. success_expected( Z502_REG_9, "CHANGE_PRIORITY" );
  967. CREATE_PROCESS( "test1l_1", test1j_echo, NORMAL_PRIORITY,
  968. &Z502_REG_3, &Z502_REG_9);
  969. STEP( 3 )
  970. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  971. /* BEGIN CASE 1 ------------------------------------------*/
  972. printf("\n\nBegin Case 1:\n\n");
  973. /* Sleep so that first process will wake and receive */
  974. SLEEP ( 200 );
  975. STEP( 4 )
  976. GET_PROCESS_ID( "test1l_1", &Z502_REG_4, &Z502_REG_9 );
  977. STEP( 5 )
  978. success_expected( Z502_REG_9, "Get Receiving Process ID" );
  979. if ( Z502_REG_3 != Z502_REG_4 )
  980. printf("ERROR! The process ids should match! New process ID is: %ld", Z502_REG_4);
  981. /* Suspend the receiving process */
  982. SUSPEND_PROCESS(Z502_REG_3, &Z502_REG_9);
  983. STEP( 6 )
  984. success_expected( Z502_REG_9, "SUSPEND" );
  985. /* Resume the recieving process */
  986. RESUME_PROCESS(Z502_REG_3, &Z502_REG_9);
  987. STEP( 7 )
  988. success_expected( Z502_REG_9, "RESUME" );
  989. /* Send it a message */
  990. td->target_pid = Z502_REG_3;
  991. td->send_length= 30;
  992. strcpy( td->msg_sent, "Resume first echo" );
  993. SEND_MESSAGE( td->target_pid, td->msg_sent,
  994. td->send_length, &Z502_REG_9 );
  995. STEP( 8 )
  996. success_expected( Z502_REG_9, "SEND_MESSAGE" );
  997. /* Receive it's response (process is now back in recieving mode) */
  998. td->source_pid = -1;
  999. td->receive_length = LEGAL_MESSAGE_LENGTH;
  1000. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  1001. td->receive_length, &(td->actual_send_length),
  1002. &(td->actual_source_pid), &Z502_REG_9 );
  1003. STEP( 9 )
  1004. success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  1005. if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
  1006. printf("ERROR - msg sent != msg received.\n");
  1007. if ( td->actual_source_pid != Z502_REG_3 )
  1008. printf( "ERROR - source PID not correct.\n" );
  1009. if ( td->actual_send_length != td->send_length )
  1010. printf( "ERROR - send length not sent correctly.\n" );
  1011. /* BEGIN CASE 2 ------------------------------------------*/
  1012. printf("\n\nBegin Case 2:\n\n");
  1013. /* create a competitor to show suspend works with incoming messages */
  1014. CREATE_PROCESS( "test1l_2", test1j_echo, NORMAL_PRIORITY,
  1015. &Z502_REG_5, &Z502_REG_9);
  1016. STEP( 10 )
  1017. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  1018. /* Sleep so that the new process will wake and receive */
  1019. SLEEP ( 200 );
  1020. STEP( 11 )
  1021. GET_PROCESS_ID( "test1l_2", &Z502_REG_6, &Z502_REG_9 );
  1022. STEP( 12 )
  1023. success_expected( Z502_REG_9, "Get Receiving Process ID" );
  1024. if ( Z502_REG_5 != Z502_REG_6 )
  1025. printf("ERROR! The process ids should match! New process ID is: %ld", Z502_REG_4);
  1026. /* Suspend the first process */
  1027. SUSPEND_PROCESS(Z502_REG_3, &Z502_REG_9);
  1028. STEP( 13 )
  1029. success_expected( Z502_REG_9, "SUSPEND" );
  1030. /* Send anyone a message */
  1031. td->target_pid = -1;
  1032. td->send_length= 30;
  1033. strcpy( td->msg_sent, "Going to second process" );
  1034. SEND_MESSAGE( td->target_pid, td->msg_sent,
  1035. td->send_length, &Z502_REG_9 );
  1036. STEP( 14 )
  1037. success_expected( Z502_REG_9, "SEND_MESSAGE" );
  1038. /* Resume the first process */
  1039. RESUME_PROCESS(Z502_REG_3, &Z502_REG_9);
  1040. STEP( 15 )
  1041. success_expected( Z502_REG_9, "RESUME" );
  1042. /* Receive the second process' response */
  1043. td->source_pid = Z502_REG_5;
  1044. td->receive_length = LEGAL_MESSAGE_LENGTH;
  1045. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  1046. td->receive_length, &(td->actual_send_length),
  1047. &(td->actual_source_pid), &Z502_REG_9 );
  1048. STEP( 16 )
  1049. success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  1050. if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
  1051. printf("ERROR - msg sent != msg received.\n");
  1052. if ( td->actual_source_pid != Z502_REG_5 )
  1053. printf( "ERROR - source PID not correct.\n" );
  1054. if ( td->actual_send_length != td->send_length )
  1055. printf( "ERROR - send length not sent correctly.\n" );
  1056. /* BEGIN CASE 3 ------------------------------------------*/
  1057. printf("\n\nBegin Case 3:\n\n");
  1058. /* Suspend the first process */
  1059. SUSPEND_PROCESS(Z502_REG_3, &Z502_REG_9);
  1060. STEP( 17 )
  1061. success_expected( Z502_REG_9, "SUSPEND" );
  1062. /* Send it, specifically, a message */
  1063. td->target_pid = Z502_REG_3;
  1064. td->send_length= 30;
  1065. strcpy( td->msg_sent, "Going to suspended" );
  1066. SEND_MESSAGE( td->target_pid, td->msg_sent,
  1067. td->send_length, &Z502_REG_9 );
  1068. STEP( 18 )
  1069. success_expected( Z502_REG_9, "SEND_MESSAGE" );
  1070. /* Resume the first process */
  1071. RESUME_PROCESS(Z502_REG_3, &Z502_REG_9);
  1072. STEP( 19 )
  1073. success_expected( Z502_REG_9, "RESUME" );
  1074. /* Receive the process' response */
  1075. td->source_pid = Z502_REG_3;
  1076. td->receive_length = LEGAL_MESSAGE_LENGTH;
  1077. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  1078. td->receive_length, &(td->actual_send_length),
  1079. &(td->actual_source_pid), &Z502_REG_9 );
  1080. STEP( 20 )
  1081. success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  1082. if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
  1083. printf("ERROR - msg sent != msg received.\n");
  1084. if ( td->actual_source_pid != Z502_REG_3 )
  1085. printf( "ERROR - source PID not correct.\n" );
  1086. if ( td->actual_send_length != td->send_length )
  1087. printf( "ERROR - send length not sent correctly.\n" );
  1088. TERMINATE_PROCESS(-2, &Z502_REG_9);
  1089. } // End of SELECT
  1090. } // End of while
  1091. } // End of test1l
  1092. /**************************************************************************
  1093. Test 1m
  1094. Simulates starvation by running multiple copies of test1x simultaneously.
  1095. Test1c runs these with the same priority in order to show
  1096. FCFS scheduling behavior; Test1d uses different priorities
  1097. in order to show priority scheduling. Test 1m, by comparison, uses
  1098. more processes of low priority to show the rising needs of processes 9 and 10
  1099. Z502_REG_1, 2, 3, 4, 5 Used as return of process id's.
  1100. Z502_REG_6 Return of PID on GET_PROCESS_ID
  1101. Z502_REG_9 Used as return of error code.
  1102. **************************************************************************/
  1103. #define PRIORITY1 10
  1104. #define PRIORITY2 11
  1105. #define PRIORITY3 11
  1106. #define PRIORITY4 90
  1107. #define PRIORITY5 40
  1108. void test1m( void)
  1109. {
  1110. static INT32 sleep_time = 1000;
  1111. while( 1 )
  1112. {
  1113. SELECT_STEP
  1114. {
  1115. STEP( 0 )
  1116. printf( "This is Release %s: Test 1m\n", CURRENT_REL );
  1117. CREATE_PROCESS( "test1m_1", test1x, PRIORITY1,
  1118. &Z502_REG_1, &Z502_REG_9 );
  1119. STEP( 1 )
  1120. success_expected( Z502_REG_9, "CREATE_PROCESS" );
  1121. CREATE_PROCESS( "test1m_2", test1x, PRIORITY1,
  1122. &Z502_REG_2, &Z502_REG_9 );
  1123. STEP( 2 )
  1124. CREATE_PROCESS( "test1m_3", test1x, PRIORITY2,
  1125. &Z502_REG_3, &Z502_REG_9 );
  1126. STEP( 3 )
  1127. CREATE_PROCESS( "test1m_4", test1x, PRIORITY2,
  1128. &Z502_REG_4, &Z502_REG_9 );
  1129. STEP( 4 )
  1130. CREATE_PROCESS( "test1m_5", test1x, PRIORITY3,
  1131. &Z502_REG_2, &Z502_REG_9 );
  1132. STEP( 5 )
  1133. CREATE_PROCESS( "test1m_6", test1x, PRIORITY3,
  1134. &Z502_REG_3, &Z502_REG_9 );
  1135. STEP( 6 )
  1136. CREATE_PROCESS( "test1m_7", test1x, PRIORITY4,
  1137. &Z502_REG_4, &Z502_REG_9 );
  1138. /* We will loop until the target process ( test1m_9 ) has terminated.
  1139. We know it terminated because for a while we get success on the call
  1140. GET_PROCESS_ID, and then failure when the process no longer exists. */
  1141. STEP( 7 )
  1142. SLEEP ( sleep_time );
  1143. STEP( 8 )
  1144. GET_PROCESS_ID( "test1m_9", &Z502_REG_6, &Z502_REG_9 );
  1145. STEP( 9 )
  1146. if ( Z502_REG_9 == ERR_SUCCESS )
  1147. GO_NEXT_TO( 5 ) /* Loop back */
  1148. break;
  1149. STEP( 10 )
  1150. TERMINATE_PROCESS( -1, &Z502_REG_9 );
  1151. } // End switch
  1152. } // End while
  1153. } // End test1m
  1154. /**************************************************************************
  1155. Test1x
  1156. is used as a target by the process creation programs.
  1157. It has the virtue of causing lots of rescheduling activity in
  1158. a relatively random way.
  1159. Z502_REG_1 Loop counter
  1160. Z502_REG_2 OUR process ID
  1161. Z502_REG_3 Starting time
  1162. Z502_REG_4 Ending time
  1163. Z502_REG_9 Error returned
  1164. **************************************************************************/
  1165. #define NUMBER_OF_TEST1X_ITERATIONS 10
  1166. void test1x( void )
  1167. {
  1168. static INT32 sleep_time = 17;
  1169. while( 1 )
  1170. {
  1171. SELECT_STEP
  1172. {
  1173. STEP( 0 )
  1174. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  1175. STEP( 1 )
  1176. printf( "Release %s:Test 1x: Pid %ld\n",
  1177. CURRENT_REL, Z502_REG_2 );
  1178. break;
  1179. STEP( 2 )
  1180. GET_TIME_OF_DAY( &Z502_REG_3 );
  1181. STEP( 3 )
  1182. SLEEP ( ( sleep_time * Z502_REG_3 ) % 143 ); /* random*/
  1183. //SLEEP ( 10000 ); /* random*/
  1184. STEP( 4 )
  1185. GET_TIME_OF_DAY( &Z502_REG_4 );
  1186. STEP( 5 )
  1187. if ( Z502_REG_1 <= NUMBER_OF_TEST1X_ITERATIONS )
  1188. GO_NEXT_TO( 2 )
  1189. else
  1190. {
  1191. printf( "Test1x, PID %ld, Ends at Time %ld\n",
  1192. Z502_REG_2, Z502_REG_4 );
  1193. TERMINATE_PROCESS( -1, &Z502_REG_9 );
  1194. }
  1195. Z502_REG_1++; /* Inc loop cntr */
  1196. break;
  1197. STEP( 6 )
  1198. printf( "ERROR: Test should be terminated but isn't.\n");
  1199. break;
  1200. } /* End of while */
  1201. } /* End of SELECT */
  1202. } /* End of test1x */
  1203. /**************************************************************************
  1204. Test1j_echo
  1205. is used as a target by the message send/receive programs.
  1206. All it does is send back the same message it received to the
  1207. same sender.
  1208. Z502_REG_1 Pointer to data private to each process
  1209. running this routine.
  1210. Z502_REG_2 OUR process ID
  1211. Z502_REG_3 Starting time
  1212. Z502_REG_4 Ending time
  1213. Z502_REG_9 Error returned
  1214. **************************************************************************/
  1215. typedef struct
  1216. {
  1217. INT32 target_pid;
  1218. INT32 source_pid;
  1219. INT32 actual_source_pid;
  1220. INT32 send_length;
  1221. INT32 receive_length;
  1222. INT32 actual_senders_length;
  1223. char msg_buffer[LEGAL_MESSAGE_LENGTH];
  1224. char msg_sent[LEGAL_MESSAGE_LENGTH];
  1225. } TEST1J_ECHO_DATA;
  1226. void test1j_echo( void)
  1227. {
  1228. TEST1J_ECHO_DATA *td; /* Use as ptr to data */
  1229. /* Here we maintain the data to be used by this process when running
  1230. on this routine. This code should be re-entrant. */
  1231. if ( Z502_REG_1 == 0 )
  1232. {
  1233. Z502_REG_1 = (long)calloc( 1, sizeof ( TEST1J_ECHO_DATA ));
  1234. if ( Z502_REG_1 == 0 )
  1235. {
  1236. printf( "Something screwed up allocating space in test1j_echo\n" );
  1237. }
  1238. }
  1239. td = ( TEST1J_ECHO_DATA *)Z502_REG_1;
  1240. while( 1 )
  1241. {
  1242. SELECT_STEP
  1243. {
  1244. STEP( 0 )
  1245. GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
  1246. STEP( 1 )
  1247. success_expected( Z502_REG_9, "GET_PROCESS_ID" );
  1248. printf( "Release %s:Test 1j_echo: Pid %ld\n",
  1249. CURRENT_REL, Z502_REG_2 );
  1250. STEP( 2 )
  1251. td->source_pid = -1;
  1252. td->receive_length = LEGAL_MESSAGE_LENGTH;
  1253. RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
  1254. td->receive_length, &(td->actual_senders_length),
  1255. &(td->actual_source_pid), &Z502_REG_9 );
  1256. STEP( 3 )
  1257. success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
  1258. printf( "Receive from PID = %d: length = %d: msg = %s:\n",
  1259. td->actual_source_pid, td->actual_senders_length,
  1260. td->msg_buffer );
  1261. td->target_pid = td->actual_source_pid;
  1262. strcpy( td->msg_sent, td->msg_buffer );
  1263. td->send_length= td->actual_senders_length;
  1264. SEND_MESSAGE( td->target_pid, td->msg_sent,
  1265. td->send_length, &Z502_REG_9 );
  1266. STEP( 4 )
  1267. success_expected( Z502_REG_9, "SEND_MESSAGE" );
  1268. GO_NEXT_TO( 2 )
  1269. break;
  1270. } /* End of while */
  1271. } /* End of SELECT */
  1272. } /* End of test1j_echo*/
  1273. /**************************************************************************
  1274. error_expected and success_expected
  1275. These routines simply handle the display of success/error data.
  1276. **************************************************************************/
  1277. void error_expected( INT32 error_code, char sys_call[] )
  1278. {
  1279. if ( error_code == ERR_SUCCESS)
  1280. {
  1281. printf( "An Error SHOULD have occurred.\n" );
  1282. printf("????: Error( %d ) occurred in case %d (%s)\n",
  1283. error_code, Z502_PROGRAM_COUNTER-2, sys_call );
  1284. }
  1285. else
  1286. printf( "Program correctly returned an error: %d\n", error_code );
  1287. } /* End of error_expected */
  1288. void success_expected( INT32 error_code, char sys_call[] )
  1289. {
  1290. if ( error_code != ERR_SUCCESS)
  1291. {
  1292. printf( "An Error should NOT have occurred.\n" );
  1293. printf("????: Error( %d ) occurred in case %d (%s)\n",
  1294. error_code, Z502_PROGRAM_COUNTER-2, sys_call );
  1295. }
  1296. else
  1297. printf( "Program correctly returned success.\n" );
  1298. } /* End of success_expected */
  1299. /**************************************************************************
  1300. Test2a exercises a simple memory write and read
  1301. Use: Z502_REG_1 data_written
  1302. Z502_REG_2 data_read
  1303. Z502_REG_3 address
  1304. Z502_REG_4 process_id
  1305. Z502_REG_9 error
  1306. In global.h, there's a variable DO_MEMORY_DEBUG. Switching it to
  1307. TRUE will allow you to see what the memory system thinks is happening.
  1308. WARNING - it's verbose -- and I don't want to see such output - it's
  1309. strictly for your debugging pleasure.
  1310. **************************************************************************/
  1311. void test2a( void )
  1312. {
  1313. SELECT_STEP
  1314. {
  1315. STEP( 0 )
  1316. GET_PROCESS_ID( "", &Z502_REG_4, &Z502_REG_9 );
  1317. STEP( 1 )
  1318. printf( "Release %s:Test 2a: Pid %ld\n",
  1319. CURRENT_REL, Z502_REG_4 );
  1320. Z502_REG_3 = 412;
  1321. Z502_REG_1 = Z502_REG_3 + Z502_REG_4;
  1322. MEM_WRITE( Z502_REG_3, &Z502_REG_1 );
  1323. STEP( 2 )
  1324. MEM_READ( Z502_REG_3, &Z502_REG_2 );
  1325. STEP( 3 )
  1326. printf("PID= %ld address= %ld written= %ld read= %ld\n",
  1327. Z502_REG_4, Z502_REG_3, Z502_REG_1, Z502_REG_2);
  1328. if ( Z502_REG_2 != Z502_REG_1 )
  1329. printf( "AN ERROR HAS OCCURRED.\n" );
  1330. TERMINATE_PROCESS( -1, &Z502_REG_9 );
  1331. } /* End of SELECT */
  1332. } /* End of test2a */
  1333. /**************************************************************************
  1334. Test2b
  1335. exercises simple memory writes and reads. Watch out,
  1336. the addresses used are diabolical and are designed to show
  1337. unusual features of your memory management system.
  1338. Use: Z502_REG_1 data_written
  1339. Z502_REG_2 data_read
  1340. Z502_REG_3 address
  1341. Z502_REG_4 process_id
  1342. Z502_REG_5 test_data_index
  1343. Z502_REG_9 error
  1344. The following registers are used for sanity checks - after each
  1345. read/write pair, we will read back the first set of data to make
  1346. sure it's still there.
  1347. Z502_REG_6 First data written
  1348. Z502_REG_7 First data read
  1349. Z502_REG_8 First address
  1350. **************************************************************************/
  1351. #define TEST_DATA_SIZE (INT16)7
  1352. void test2b( void )
  1353. {
  1354. static INT32 test_data[TEST_DATA_SIZE] = {
  1355. 0, 4, PGSIZE - 2, PGSIZE, 3 * PGSIZE - 2,
  1356. (VIRTUAL_MEM_PGS - 1) * PGSIZE,
  1357. VIRTUAL_MEM_PGS * PGSIZE - 2};
  1358. while(1)
  1359. {
  1360. SELECT_STEP
  1361. {
  1362. STEP( 0 )
  1363. GET_PROCESS_ID( "", &Z502_REG_4, &Z502_REG_9 );
  1364. STEP( 1 )
  1365. Z502_REG_8 = 5 * PGSIZE;
  1366. Z502_REG_6 = Z502_REG_8 + Z502_REG_4 + 7;
  1367. MEM_WRITE( Z502_REG_8, &Z502_REG_6 );
  1368. printf( "\n\nRelease %s:Test 2b: Pid %ld\n",
  1369. CURRENT_REL, Z502_REG_4 );
  1370. break;
  1371. STEP( 2 )
  1372. Z502_REG_3 = test_data[ (INT16)Z502_REG_5 ];
  1373. Z502_REG_1 = Z502_REG_3 + Z502_REG_4 + 27;
  1374. MEM_WRITE( Z502_REG_3, &Z502_REG_1 );
  1375. STEP( 3 )
  1376. MEM_READ( Z502_REG_3, &Z502_REG_2 );
  1377. STEP( 4 )
  1378. printf("PID= %ld address= %ld written= %ld read= %ld\n",
  1379. Z502_REG_4, Z502_REG_3, Z502_REG_1, Z502_REG_2);
  1380. if (Z502_REG_2 != Z502_REG_1 )
  1381. printf( "AN ERROR HAS OCCURRED.\n" );
  1382. /* Go back and check earlier write */
  1383. MEM_READ( Z502_REG_8, &Z502_REG_7 );
  1384. STEP( 5 )
  1385. GO_NEXT_TO( 2 )
  1386. printf("PID= %ld address= %ld written= %ld read= %ld\n",
  1387. Z502_REG_4, Z502_REG_8, Z502_REG_6, Z502_REG_7);
  1388. if (Z502_REG_6 != Z502_REG_7 )
  1389. printf( "AN ERROR HAS OCCURRED.\n" );
  1390. Z502_REG_5++;
  1391. break;
  1392. } /* End of SELECT */
  1393. } /* End of while */
  1394. } /* End of test2b */
  1395. /**************************************************************************
  1396. Test2c causes usage of disks. The test is designed to give
  1397. you a chance to develop a mechanism for handling disk requests.
  1398. Z502_REG_1 - data that was written.
  1399. Z502_REG_2 - data that was read from memory.
  1400. Z502_REG_3 - address where data was written/read.
  1401. Z502_REG_4 - process id of this process.
  1402. Z502_REG_6 - number of iterations/loops through the code.
  1403. Z502_REG_7 - which page will the write/read be on. start at 0
  1404. Z502_REG_9 - returned error code.
  1405. Many people find it helpful to use os_switch_context_complete in order
  1406. to wrap-up disk requests before returning to the test code. See the
  1407. description at test1i.
  1408. **************************************************************************/
  1409. #define DISPLAY_GRANULARITY2c 10
  1410. typedef union
  1411. {
  1412. char char_data[ PGSIZE ];
  1413. UINT32 int_data[ PGSIZE/ sizeof(int) ];
  1414. } DISK_DATA;
  1415. void test2c( void )
  1416. {
  1417. DISK_DATA *data_written;
  1418. DISK_DATA *data_read;
  1419. INT16 disk_id;
  1420. INT16 sanity = 1234;
  1421. INT16 sector;
  1422. if ( Z502_REG_1 == 0 )
  1423. {
  1424. Z502_REG_1 = ( long )calloc( 1, sizeof( DISK_DATA ) );
  1425. Z502_REG_2 = ( long )calloc( 1, sizeof( DISK_DATA ) );
  1426. if ( Z502_REG_2 == 0 )
  1427. printf( "Something screwed up allocating space in test2c\n");
  1428. }
  1429. data_written = (DISK_DATA *)Z502_REG_1;
  1430. data_read = (DISK_DATA *)Z502_REG_2;
  1431. while(1)
  1432. {
  1433. SELECT_STEP
  1434. {
  1435. STEP( 0 )
  1436. GET_PROCESS_ID( "", &Z502_REG_4, &Z502_REG_9 );
  1437. STEP( 1 )
  1438. Z502_REG_6 = Z502_REG_4;
  1439. printf( "\n\nRelease %s:Test 2c: Pid %ld\n",
  1440. CURRENT_REL, Z502_REG_4 );
  1441. break;
  1442. STEP( 2 )
  1443. disk_id = ( Z502_REG_4 / 2 ) % MAX_NUMBER_OF_DISKS + 1;
  1444. sector = Z502_REG_6 % NUM_LOGICAL_SECTORS;
  1445. data_written->int_data[0] = disk_id;
  1446. data_written->int_data[1] = sanity;
  1447. data_written->int_data[2] = sector;
  1448. data_written->int_data[3] = (int)Z502_REG_4;
  1449. DISK_WRITE( disk_id, sector, (char*)(data_written->char_data ) );
  1450. STEP( 3 )
  1451. disk_id = ( Z502_REG_4 / 2 ) % MAX_NUMBER_OF_DISKS + 1;
  1452. sector = Z502_REG_6 % NUM_LOGICAL_SECTORS;
  1453. DISK_READ( disk_id, sector, (char*)(data_read->char_data ) );
  1454. STEP( 4 )
  1455. disk_id = ( Z502_REG_4 / 2 ) % MAX_NUMBER_OF_DISKS + 1;
  1456. sector = Z502_REG_6 % NUM_LOGICAL_SECTORS;
  1457. if ( Z502_REG_6 % DISPLAY_GRANULARITY2c == 0 )
  1458. printf("PID= %ld disk_id =%d, sector = %d\n",
  1459. Z502_REG_4, disk_id, sector );
  1460. if ( ( data_read->int_data[0] != data_written->int_data[0] )
  1461. || ( data_read->int_data[1] != data_written->int_data[1] )
  1462. || ( data_read->int_data[2] != data_written->int_data[2] )
  1463. || ( data_read->int_data[3] != data_written->int_data[3]))
  1464. printf( "AN ERROR HAS OCCURRED.\n" );
  1465. Z502_REG_6 += 2;
  1466. if ( Z502_REG_6 < 50 )
  1467. GO_NEXT_TO( 2 ) /* Go write/read */
  1468. break;
  1469. /* Now read back the data we've written and paged */
  1470. STEP( 5 )
  1471. printf( "Reading back data: test 2c, PID %ld.\n",
  1472. Z502_REG_4 );
  1473. Z502_REG_6 = Z502_REG_4;
  1474. break;
  1475. STEP( 6 )
  1476. disk_id = ( Z502_REG_4 / 2 ) % MAX_NUMBER_OF_DISKS + 1;
  1477. sector = Z502_REG_6 % NUM_LOGICAL_SECTORS;
  1478. data_written->int_data[0] = disk_id;
  1479. data_written->int_data[1] = sanity;
  1480. data_written->int_data[2] = sector;
  1481. data_written->int_data[3] = Z502_REG_4;
  1482. DISK_READ( disk_id, sector, (char*)(data_read->char_data ) );
  1483. STEP( 7 )
  1484. disk_id = ( Z502_REG_4 / 2 ) % MAX_NUMBER_OF_DISKS + 1;
  1485. sector = Z502_REG_6 % NUM_LOGICAL_SECTORS;
  1486. if ( Z502_REG_6 % DISPLAY_GRANULARITY2c == 0 )
  1487. printf("PID= %ld disk_id =%d, sector = %d\n",
  1488. Z502_REG_4, disk_id, sector );
  1489. if ( ( data_read->int_data[0] != data_written->int_data[0] )
  1490. || ( data_read->int_data[1] != data_written->int_data[1] )
  1491. || ( data_read->int_data[2] != data_written->int_data[2] )
  1492. || ( data_read->int_data[3] != data_written->int_data[3]))
  1493. printf( "AN ERROR HAS OCCURRED.\n" );
  1494. Z502_REG_6 += 2;
  1495. if ( Z502_REG_6 < 50 )
  1496. GO_NEXT_TO( 6 ) /* Go write/read */
  1497. break;
  1498. STEP( 8 )
  1499. GET_TIME_OF_DAY( &Z502_REG_8 );
  1500. STEP( 9 )
  1501. printf( "Test2c, PID %ld, Ends at Time %ld\n",
  1502. Z502_REG_4, Z502_REG_8);
  1503. TERMINATE_PROCESS( -1, &Z502_REG_9 );
  1504. } /* End of SELECT */
  1505. } /* End of while */
  1506. } /* End of test2c */
  1507. /**************************************************************************
  1508. Test2d runs several disk programs at a time. The purpose here
  1509. is to watch the scheduling that goes on for these
  1510. various disk processes. The behavior that should be seen
  1511. is that the processes alternately run and do disk
  1512. activity - there should always be someone running unless
  1513. ALL processes happen to be waiting on the disk at some
  1514. point.
  1515. This program will terminate when all the test2c routines
  1516. have finished.
  1517. Z502_REG_4 - process id of this process.
  1518. Z502_REG_5 - returned error code.
  1519. Z502_REG_6 - pid of target process.
  1520. Z502_REG_8 - returned error code from the GET_PROCESS_ID call.
  1521. **************************************************************************/
  1522. #define MOST_FAVORABLE_PRIORITY 1
  1523. void test2d( void )
  1524. {
  1525. static INT32 trash;
  1526. while(1)
  1527. {
  1528. SELECT_STEP
  1529. {
  1530. STEP( 0 )
  1531. GET_PROCESS_ID( "", &Z502_REG_4, &Z502_REG_5 );
  1532. STEP( 1 )
  1533. printf( "\n\nRelease %s:Test 2d: Pid %ld\n",
  1534. CURRENT_REL, Z502_REG_4 );
  1535. CHANGE_PRIORITY( -1, MOST_FAVORABLE_PRIORITY,
  1536. &Z502_REG_9);
  1537. STEP( 2 )
  1538. CREATE_PROCESS( "first", test2c, 5, &trash, &Z502_REG_5 );
  1539. STEP( 3 )
  1540. CREATE_PROCESS( "second", test2c, 5, &trash, &Z502_REG_5 );
  1541. STEP( 4 )
  1542. CREATE_PROCESS( "third", test2c, 7, &trash, &Z502_REG_5 );
  1543. STEP( 5 )
  1544. CREATE_PROCESS( "fourth", test2c, 7, &trash, &Z502_REG_5 );
  1545. STEP( 6 )
  1546. CREATE_PROCESS( "fifth", test2c, 7, &trash, &Z502_REG_5 );
  1547. STEP( 7 )
  1548. SLEEP ( 50000 );
  1549. STEP( 8 )
  1550. TERMINATE_PROCESS( -1, &Z502_REG_5 );
  1551. } /* End of SELECT */
  1552. } /* End of while */
  1553. } /* End of test2d */
  1554. /**************************************************************************
  1555. Test2e causes extensive page replacement. It simply advances
  1556. through virtual memory. It will eventually end because
  1557. using an illegal virtual address will cause this process to
  1558. be terminated by the operating system.
  1559. Z502_REG_1 - data that was written.
  1560. Z502_REG_2 - data that was read from memory.
  1561. Z502_REG_3 - address where data was written/read.
  1562. Z502_REG_4 - process id of this process.
  1563. Z502_REG_6 - number of iterations/loops through the code.
  1564. Z502_REG_7 - which page will the write/read be on. start at 0
  1565. Z502_REG_9 - returned error code.
  1566. **************************************************************************/
  1567. #define STEP_SIZE VIRTUAL_MEM_PGS/(2 * PHYS_MEM_PGS )
  1568. #define DISPLAY_GRANULARITY2e 16 * STEP_SIZE
  1569. void test2e( void )
  1570. {
  1571. while(1)
  1572. {
  1573. SELECT_STEP
  1574. {
  1575. STEP( 0 )
  1576. GET_PROCESS_ID( "", &Z502_REG_4, &Z502_REG_9 );
  1577. STEP( 1 )
  1578. printf( "\n\nRelease %s:Test 2e: Pid %ld\n",
  1579. CURRENT_REL, Z502_REG_4 );
  1580. break;
  1581. STEP( 2 )
  1582. Z502_REG_3 = PGSIZE * Z502_REG_7; /* Generate address*/
  1583. Z502_REG_1 = Z502_REG_3 + Z502_REG_4; /* Generate data */
  1584. MEM_WRITE( Z502_REG_3, &Z502_REG_1 ); /* Write the data */
  1585. STEP( 3 )
  1586. MEM_READ( Z502_REG_3, &Z502_REG_2 ); /* Read back data */
  1587. STEP( 4 )
  1588. if ( Z502_REG_7 % DISPLAY_GRANULARITY2e == 0 )
  1589. printf("PID= %ld address= %ld written= %ld read= %ld\n",
  1590. Z502_REG_4, Z502_REG_3, Z502_REG_1, Z502_REG_2 );
  1591. if (Z502_REG_2 != Z502_REG_1 ) /* Written = read? */
  1592. printf( "AN ERROR HAS OCCURRED.\n" );
  1593. Z502_REG_7 += STEP_SIZE;
  1594. if ( Z502_REG_7 < VIRTUAL_MEM_PGS )
  1595. GO_NEXT_TO( 2 ) /* Go write/read */
  1596. break;
  1597. /* Now read back the data we've written and paged */
  1598. STEP( 5 )
  1599. printf( "Reading back data: test 2e, PID %ld.\n",
  1600. Z502_REG_4 );
  1601. Z502_REG_7 = 0;
  1602. break;
  1603. STEP( 6 )
  1604. Z502_REG_3 = PGSIZE * Z502_REG_7; /* Generate address*/
  1605. Z502_REG_1 = Z502_REG_3 + Z502_REG_4; /* Data expected */
  1606. MEM_READ( Z502_REG_3, &Z502_REG_2 ); /* Read back data */
  1607. STEP( 7 )
  1608. if ( Z502_REG_7 % DISPLAY_GRANULARITY2e == 0 )
  1609. printf("PID= %ld address= %ld written= %ld read= %ld\n",
  1610. Z502_REG_4, Z502_REG_3, Z502_REG_1, Z502_REG_2 );
  1611. if (Z502_REG_2 != Z502_REG_1 ) /* Written = read? */
  1612. printf( "AN ERROR HAS OCCURRED.\n" );
  1613. Z502_REG_7 += STEP_SIZE;
  1614. GO_NEXT_TO( 6 ) /* Go write/read */
  1615. break;
  1616. } /* End of SELECT */
  1617. } /* End of while */
  1618. } /* End of test2e */
  1619. /**************************************************************************
  1620. Test2f causes extensive page replacement, but reuses pages.
  1621. This program will terminate, but it might take a while.
  1622. Z502_REG_1 - data that was written.
  1623. Z502_REG_2 - data that was read from memory.
  1624. Z502_REG_3 - address where data was written/read.
  1625. Z502_REG_4 - process id of this process.
  1626. Z502_REG_5 - holds the pointer to the record of page touches
  1627. Z502_REG_6 - counter/index - starts at 0.
  1628. Z502_REG_8 - iteration count
  1629. Z502_REG_9 - returned error code.
  1630. **************************************************************************/
  1631. #define NUMBER_OF_ITERATIONS 3
  1632. #define LOOP_COUNT 400
  1633. #define DISPLAY_GRANULARITY2 100
  1634. #define LOGICAL_PAGES_TO_TOUCH 2 * PHYS_MEM_PGS
  1635. typedef struct
  1636. {
  1637. INT16 page_touched[LOGICAL_PAGES_TO_TOUCH];
  1638. } MEMORY_TOUCHED_RECORD;
  1639. void test2f( void )
  1640. {
  1641. MEMORY_TOUCHED_RECORD *mtr;
  1642. short index;
  1643. if ( Z502_REG_5 == 0 )
  1644. {
  1645. Z502_REG_5 = ( long )calloc( 1, sizeof(MEMORY_TOUCHED_RECORD) );
  1646. if ( Z502_REG_5 == 0 )
  1647. {
  1648. printf("Something screwed up allocating space in test2f\n");
  1649. }
  1650. mtr = ( MEMORY_TOUCHED_RECORD *)Z502_REG_5;
  1651. for ( index = 0; index < LOGICAL_PAGES_TO_TOUCH; index++ )
  1652. mtr->page_touched[index] = 0;
  1653. }
  1654. mtr = ( MEMORY_TOUCHED_RECORD *)Z502_REG_5;
  1655. while(1)
  1656. {
  1657. SELECT_STEP
  1658. {
  1659. STEP( 0 )
  1660. GET_PROCESS_ID( "", &Z502_REG_4, &Z502_REG_9 );
  1661. STEP( 1 )
  1662. printf( "\n\nRelease %s:Test 2f: Pid %ld\n",
  1663. CURRENT_REL, Z502_REG_4 );
  1664. break;
  1665. STEP( 2 )
  1666. get_skewed_random_number( &Z502_REG_7, LOGICAL_PAGES_TO_TOUCH );
  1667. Z502_REG_3 = PGSIZE * Z502_REG_7; /* Convert page to addr.*/
  1668. Z502_REG_1 = Z502_REG_3 + Z502_REG_4;
  1669. MEM_WRITE( Z502_REG_3, &Z502_REG_1 );
  1670. STEP( 3 )
  1671. MEM_READ( Z502_REG_3, &Z502_REG_2 );
  1672. STEP( 4 )
  1673. if ( Z502_REG_6 % DISPLAY_GRANULARITY2 == 0 )
  1674. printf("PID= %ld address= %ld written= %ld read= %ld\n",
  1675. Z502_REG_4, Z502_REG_3, Z502_REG_1, Z502_REG_2 );
  1676. Z502_REG_6++;
  1677. if (Z502_REG_2 != Z502_REG_1 )
  1678. printf( "AN ERROR HAS OCCURRED: READ NOT EQUAL WRITE.\n" );
  1679. mtr->page_touched[ (short)Z502_REG_7 ]++;
  1680. if ( Z502_REG_6 <= LOOP_COUNT )
  1681. GO_NEXT_TO( 2 ) /* There are more pages to read/write */
  1682. else
  1683. {
  1684. printf( "PID %ld starting re-read.\n", Z502_REG_4 );
  1685. Z502_REG_6 = 0;
  1686. }
  1687. break;
  1688. STEP( 5 )
  1689. /* We can only read back from pages we've previously
  1690. written to, so find out which pages those are. */
  1691. while( mtr->page_touched[(short)Z502_REG_6] == 0 )
  1692. {
  1693. Z502_REG_6++;
  1694. if ( Z502_REG_6 >= LOGICAL_PAGES_TO_TOUCH )
  1695. {
  1696. GO_NEXT_TO( 7 )
  1697. break;
  1698. }
  1699. }
  1700. mtr->page_touched[(short)Z502_REG_6] = 0;
  1701. Z502_REG_3 = PGSIZE * Z502_REG_6; /* Convert page to addr.*/
  1702. Z502_REG_1 = Z502_REG_3 + Z502_REG_4; /* Expected read*/
  1703. MEM_READ( Z502_REG_3, &Z502_REG_2 );
  1704. STEP( 6 )
  1705. if ( Z502_REG_6 % DISPLAY_GRANULARITY2 == 0 )
  1706. printf("PID= %ld address= %ld written= %ld read= %ld\n",
  1707. Z502_REG_4, Z502_REG_3, Z502_REG_1, Z502_REG_2 );
  1708. Z502_REG_6=0;
  1709. while( mtr->page_touched[(short)Z502_REG_6] == 0 )
  1710. {
  1711. Z502_REG_6++;
  1712. }
  1713. if (Z502_REG_2 != Z502_REG_1 )
  1714. printf( "ERROR HAS OCCURRED: READ NOT SAME AS WRITE.\n" );
  1715. if ( Z502_REG_6 < LOGICAL_PAGES_TO_TOUCH )
  1716. GO_NEXT_TO( 5 ) /* There's more to read back */
  1717. break;
  1718. STEP( 7 )
  1719. /* We've completed reading back everything */
  1720. Z502_REG_8++;
  1721. printf( "TEST 2f, PID %ld, HAS COMPLETED %ld ITERATIONS\n",
  1722. Z502_REG_4, Z502_REG_8 );
  1723. if ( Z502_REG_8 >= NUMBER_OF_ITERATIONS )
  1724. GO_NEXT_TO( 8 ) /* All done */
  1725. else
  1726. GO_NEXT_TO( 2 ) /* Set up to start ALL over */
  1727. printf( "PID %ld starting read/write.\n", Z502_REG_4 );
  1728. Z502_REG_6 = 0;
  1729. break;
  1730. STEP( 8 )
  1731. TERMINATE_PROCESS( -1, &Z502_REG_9 );
  1732. } /* End of SELECT */
  1733. } /* End of while */
  1734. } /* End of test2f */
  1735. /**************************************************************************
  1736. Test2g starts up a number of processes who do tests of shared area.
  1737. Z502_REG_4 - process id of this process.
  1738. Z502_REG_5 - returned error code.
  1739. Z502_REG_6 - pid of target process.
  1740. Z502_REG_8 - returned error code from the GET_PROCESS_ID call.
  1741. **************************************************************************/
  1742. #define MOST_FAVORABLE_PRIORITY 1
  1743. void test2g( void )
  1744. {
  1745. INT32 trash;
  1746. while(1)
  1747. {
  1748. SELECT_STEP
  1749. {
  1750. STEP( 0 )
  1751. GET_PROCESS_ID( "", &Z502_REG_4, &Z502_REG_5 );
  1752. STEP( 1 )
  1753. printf( "\n\nRelease %s:Test 2g: Pid %ld\n",
  1754. CURRENT_REL, Z502_REG_4 );
  1755. CHANGE_PRIORITY( -1, MOST_FAVORABLE_PRIORITY,
  1756. &Z502_REG_5);
  1757. STEP( 2 )
  1758. CREATE_PROCESS( "first", test2gx, 5, &trash, &Z502_REG_5 );
  1759. STEP( 3 )
  1760. CREATE_PROCESS( "second", test2gx, 6, &trash, &Z502_REG_5 );
  1761. STEP( 4 )
  1762. Z502_REG_8 = 0;
  1763. CREATE_PROCESS( "third", test2gx, 7, &trash, &Z502_REG_5 );
  1764. STEP( 5 )
  1765. Z502_REG_8 = 0;
  1766. CREATE_PROCESS( "fourth", test2gx, 8, &trash, &Z502_REG_5 );
  1767. STEP( 6 )
  1768. Z502_REG_8 = 0;
  1769. CREATE_PROCESS( "fifth", test2gx, 9, &trash, &Z502_REG_5 );
  1770. /* Loop here until the "2gx" processes terminate. */
  1771. STEP( 7 )
  1772. GET_PROCESS_ID( "first", &Z502_REG_6, &Z502_REG_8 );
  1773. STEP( 8 )
  1774. if ( Z502_REG_8 != 0 )
  1775. GO_NEXT_TO( 9 )
  1776. else
  1777. {
  1778. GO_NEXT_TO( 7 )
  1779. SLEEP ( 10000 );
  1780. }
  1781. break;
  1782. STEP( 9 )
  1783. TERMINATE_PROCESS( -2, &Z502_REG_5 );
  1784. } /* End of SELECT */
  1785. } /* End of while */
  1786. } /* End of test2g */
  1787. /**************************************************************************
  1788. Test2gx - test shared memory usage.
  1789. This test runs as multiple instances of processes; there are several
  1790. processes who in turn manipulate shared memory.
  1791. NOTE: This test is new in Release 1.5 and has not been tested very
  1792. thoroughly - be careful and trust nothing!!
  1793. The algorithm used here flows as follows:
  1794. o Get our PID and print it out.
  1795. o Use our PID to determine the address at which to start shared
  1796. area - every process will have a different starting address.
  1797. o Define the shared area.
  1798. o Fill in initial portions of the shared area by:
  1799. + Locking the shared area
  1800. + Determine which location in shared area is ours by using the
  1801. number of processes that are already holding the region.
  1802. For this discussion, call it the shared_index.
  1803. + Fill in portions of the shared area.
  1804. + Unlock the shared area.
  1805. o Sleep to let all 2gx PIDs start up.
  1806. o If (shared_index > 0) goto INSIDE_LOOP *** NOT first DEFINER ***
  1807. o LOOP forever doing the following steps:
  1808. + Lock shared area
  1809. + Determine the "next" process, where
  1810. next = ( my_shared_index + 1 ) mod number_of_2gx_processes.
  1811. + Put N + 1 ( initially N = 0 ) into mailbox of next process
  1812. + Put sender's PID into Target's mailbox.
  1813. + Get PID of "next" process.
  1814. + Unlock shared area.
  1815. + SEND_MESSAGE( "next", ..... );
  1816. o INSIDE_LOOP
  1817. + RECEIVE_MESSAGE( "-1", ..... )
  1818. + Lock shared area
  1819. + Read my mailbox
  1820. + Print out lots of stuff
  1821. + Do lots of sanity checks
  1822. + If N < MAX_ITERATIONS then go to LOOP.
  1823. o If (shared_index == 0) ***** the first DEFINER *****
  1824. + sleep ***** let others finish *****
  1825. + print the whole shared structure
  1826. o Terminate the process.
  1827. **************************************************************************/
  1828. #define MAX_NUM_2GX_ITERATIONS 26
  1829. #define MAX_NUM_2GX_PROCS 10
  1830. #define PROC_INFO_STRUCT_TAG 1234
  1831. #define SHARED_MEM_NAME "almost_done!!\0"
  1832. /* The following structure will be laid on shared memory by using
  1833. the MEM_ADJUST macro */
  1834. typedef struct
  1835. {
  1836. INT32 structure_tag;
  1837. INT32 pid;
  1838. INT32 mailbox;
  1839. INT32 writer_of_mailbox;
  1840. } PROC_INFO;
  1841. typedef struct
  1842. {
  1843. INT32 number_2gx_procs;
  1844. INT32 lock_word;
  1845. PROC_INFO proc_info[ MAX_NUM_2GX_PROCS ];
  1846. } SHARED_DATA;
  1847. typedef struct
  1848. {
  1849. INT32 starting_address_of_shared_area;
  1850. INT32 pages_in_shared_area;
  1851. char area_tag[32];
  1852. INT32 number_previous_sharers;
  1853. INT32 error_returned;
  1854. INT32 successful_action;
  1855. INT32 memory_info;
  1856. INT32 our_index;
  1857. INT32 next_index;
  1858. INT32 next_pid;
  1859. INT32 data_being_passed;
  1860. INT32 source_pid;
  1861. char receive_buffer[20];
  1862. INT32 message_receive_length;
  1863. INT32 message_send_length;
  1864. INT32 message_sender_pid;
  1865. } LOCAL_DATA;
  1866. /* This MEM_ADJUST macro allows us to overlay the SHARED_DATA structure
  1867. onto the shared memory we've defined. It generates an address
  1868. appropriate for use by READ and MEM_WRITE. */
  1869. #define MEM_ADJUST( arg ) \
  1870. (long)&(shared_ptr->arg) - (long)(shared_ptr) \
  1871. + (long)ld->starting_address_of_shared_area
  1872. void test2gx( void )
  1873. {
  1874. /* The declaration of shared_ptr is only for use by MEM_ADJUST macro.
  1875. It points to a bogus location - but that's ok because we never
  1876. actually use the result of the pointer. */
  1877. SHARED_DATA *shared_ptr = 0;
  1878. LOCAL_DATA *ld;
  1879. if ( Z502_REG_1 == 0 )
  1880. {
  1881. Z502_REG_1 = (long)calloc( 1, sizeof(LOCAL_DATA) );
  1882. if ( Z502_REG_1 == 0 )
  1883. {
  1884. printf( "Unable to allocate memory in test2gx\n" );
  1885. }
  1886. ld = (LOCAL_DATA *)Z502_REG_1;
  1887. ld->data_being_passed = 0;
  1888. strcpy( ld->area_tag, SHARED_MEM_NAME );
  1889. }
  1890. ld = (LOCAL_DATA *)Z502_REG_1;
  1891. while(1)
  1892. {
  1893. SELECT_STEP
  1894. {
  1895. STEP( 0 )
  1896. GET_PROCESS_ID( "", &Z502_REG_4, &Z502_REG_5 );
  1897. STEP( 1 )
  1898. printf( "\n\nRelease %s:Test 2gx: Pid %ld\n",
  1899. CURRENT_REL, Z502_REG_4 );
  1900. /* As an interesting wrinkle, each process should start
  1901. its shared region at a somewhat different address;
  1902. determine that here. */
  1903. ld->starting_address_of_shared_area =
  1904. ( Z502_REG_4 % 17 ) * PGSIZE;
  1905. ld->pages_in_shared_area = sizeof( SHARED_DATA )/PGSIZE + 1;
  1906. DEFINE_SHARED_AREA( ld->starting_address_of_shared_area,
  1907. ld->pages_in_shared_area,
  1908. ld->area_tag,
  1909. &ld->number_previous_sharers,
  1910. &ld->error_returned );
  1911. STEP( 2 )
  1912. success_expected( ld->error_returned, "DEFINE_SHARED_AREA" );
  1913. /* Put stuff in shared area - lock it first */
  1914. // READ_MODIFY( MEM_ADJUST( lock_word ), &ld->successful_action );
  1915. // BETH NOTES - without a memory lock, this code creates an infinite loop, and so it has
  1916. // been removed.
  1917. // STEP( 3 )
  1918. // if ( ld->successful_action == FALSE )
  1919. // GO_NEXT_TO( 2 ) /* Couldn't get lock - try again */
  1920. // SLEEP( 10 );
  1921. STEP( 4 )
  1922. /* We now have the lock and so own the shared area */
  1923. STEP( 5 )
  1924. /* Increment the number of users of shared area */
  1925. ld->memory_info = ld->number_previous_sharers+1;
  1926. MEM_WRITE( MEM_ADJUST( number_2gx_procs ), &ld->memory_info );
  1927. STEP( 6 )
  1928. ld->memory_info = PROC_INFO_STRUCT_TAG; /* Sanity data */
  1929. ld->our_index = ld->number_previous_sharers;
  1930. MEM_WRITE( MEM_ADJUST(proc_info[ld->our_index].structure_tag),
  1931. &ld->memory_info );
  1932. STEP( 7 )
  1933. ld->memory_info = Z502_REG_4; /* Store PID in our slot */
  1934. MEM_WRITE( MEM_ADJUST(proc_info[ld->our_index].pid),
  1935. &ld->memory_info );
  1936. STEP( 8 )
  1937. ld->memory_info = 0; /* Free lock */
  1938. MEM_WRITE( MEM_ADJUST( lock_word ), &ld->memory_info );
  1939. STEP( 9 )
  1940. if ( ld->our_index == 0 )
  1941. {
  1942. GO_NEXT_TO( 12 ); /* This is the master */
  1943. SLEEP( 10000 ); /* Wait for slaves to start */
  1944. }
  1945. else
  1946. GO_NEXT_TO( 30 ); /* These are the slaves */
  1947. break;
  1948. STEP( 12 )
  1949. /* This is the top of the loop - return here for each
  1950. send - receive pair */
  1951. /* Put stuff in shared area - lock it first */
  1952. // READ_MODIFY( MEM_ADJUST( lock_word ), &ld->successful_action );
  1953. // BETH NOTES - without a memory lock, this code creates an infinite loop, and so it has
  1954. // been removed.
  1955. // STEP( 13 )
  1956. // if ( ld->successful_action == FALSE )
  1957. // GO_NEXT_TO( 12 ) /* Couldn't get lock - try again */
  1958. // SLEEP( 10 );
  1959. STEP( 14 )
  1960. MEM_READ( MEM_ADJUST( number_2gx_procs ), &ld->memory_info );
  1961. STEP( 15 )
  1962. ld->next_index = ( ld->our_index + 1 ) % ld->memory_info;
  1963. ld->our_index = ld->number_previous_sharers;
  1964. MEM_READ( MEM_ADJUST(proc_info[ld->next_index].structure_tag),
  1965. &ld->memory_info );
  1966. STEP( 16 )
  1967. if ( ld->memory_info != PROC_INFO_STRUCT_TAG )
  1968. {
  1969. printf( "We should see a structure tag, but did not\n");
  1970. printf( "This means that this memory is not mapped \n");
  1971. printf( "consistent with the memory used by the writer\n");
  1972. printf( "of this structure. It's a page table problem.\n");
  1973. }
  1974. MEM_WRITE( MEM_ADJUST(proc_info[ld->next_index].mailbox),
  1975. &ld->data_being_passed );
  1976. STEP( 17 )
  1977. MEM_WRITE( MEM_ADJUST(proc_info[ld->next_index].
  1978. writer_of_mailbox), &Z502_REG_4 );
  1979. STEP( 18 )
  1980. MEM_READ( MEM_ADJUST(proc_info[ld->next_index].pid),
  1981. &ld->next_pid );
  1982. STEP( 19 )
  1983. ld->memory_info = 0; /* Free lock */
  1984. MEM_WRITE( MEM_ADJUST( lock_word ), &ld->memory_info );
  1985. if ( ld->data_being_passed >= MAX_NUM_2GX_ITERATIONS-1 )
  1986. {
  1987. GO_NEXT_TO( 40 );
  1988. }
  1989. break;
  1990. STEP( 20 )
  1991. printf( "Sender %ld to Receiver %d passing data %d\n",
  1992. Z502_REG_4, ld->next_pid, ld->data_being_passed );
  1993. SEND_MESSAGE( ld->next_pid, " ", 0, &ld->error_returned );
  1994. STEP( 21 )
  1995. //success_expected( ld->error_returned, "SEND_MESSAGE" );
  1996. if ( ld->data_being_passed < MAX_NUM_2GX_ITERATIONS-1 )
  1997. {
  1998. GO_NEXT_TO( 30 );
  1999. }
  2000. else
  2001. {
  2002. GO_NEXT_TO( 40 );
  2003. }
  2004. break;
  2005. STEP( 30 ) /* SLAVES START HERE */
  2006. ld->source_pid = -1; /* From anyone */
  2007. ld->message_receive_length = 20;
  2008. RECEIVE_MESSAGE( ld->source_pid,
  2009. ld->receive_buffer,
  2010. ld->message_receive_length,
  2011. &ld->message_send_length,
  2012. &ld->message_sender_pid,
  2013. &ld->error_returned );
  2014. STEP( 31 )
  2015. success_expected( ld->error_returned, "RECEIVE_MESSAGE" );
  2016. // READ_MODIFY( MEM_ADJUST( lock_word ), &ld->successful_action );
  2017. // BETH NOTES - without a memory lock, this code creates an infinite loop, and so it has
  2018. // been removed.
  2019. // STEP( 32 )
  2020. // if ( ld->successful_action == FALSE )
  2021. // GO_NEXT_TO( 31 ) /* Couldn't get lock - try again */
  2022. // SLEEP( 10 );
  2023. STEP( 33 )
  2024. MEM_READ( MEM_ADJUST(proc_info[ld->our_index].structure_tag),
  2025. &ld->memory_info );
  2026. STEP( 34 )
  2027. if ( ld->memory_info != PROC_INFO_STRUCT_TAG )
  2028. {
  2029. printf( "We should see a structure tag, but did not.\n");
  2030. printf( "This means that this memory is not mapped \n");
  2031. printf( "consistent with the memory used when WE wrote\n");
  2032. printf( "this structure. It's a page table problem.\n");
  2033. }
  2034. MEM_READ( MEM_ADJUST(proc_info[ld->our_index].mailbox),
  2035. &ld->data_being_passed );
  2036. STEP( 35 )
  2037. printf( "\t\t\tReceiver %ld from Sender %d got data %d\n",
  2038. Z502_REG_4, ld->message_sender_pid,
  2039. ld->data_being_passed );
  2040. MEM_READ( MEM_ADJUST(proc_info[ld->our_index].
  2041. writer_of_mailbox), &ld->memory_info );
  2042. STEP( 36 )
  2043. if ( ld->memory_info != ld->message_sender_pid )
  2044. {
  2045. printf( "ERROR: ERROR: The sender PID, given by the \n");
  2046. printf( "RECIEVE_MESSAGE and the mailbox, don't match\n" );
  2047. }
  2048. ld->data_being_passed++;
  2049. STEP( 37 ) /* Free the lock */
  2050. ld->memory_info = 0;
  2051. MEM_WRITE( MEM_ADJUST(lock_word), &ld->memory_info );
  2052. STEP( 38 )
  2053. GO_NEXT_TO( 12 );
  2054. break;
  2055. /* The code comes here when it's finished with all the messages. */
  2056. STEP( 40 )
  2057. if ( ld->our_index > 0 )
  2058. GO_NEXT_TO( 60 );
  2059. break;
  2060. /* The first sharer prints out the entire shared area */
  2061. STEP( 41 )
  2062. SLEEP( 5000 ); /* Wait for msgs to finish */
  2063. STEP( 42 )
  2064. MEM_READ( MEM_ADJUST( number_2gx_procs ), &ld->memory_info );
  2065. STEP( 43 )
  2066. printf( "Overview of shared area at completion of Test2g\n");
  2067. printf( "number_2gx_processes = %d\n", ld->memory_info );
  2068. Z502_REG_7 = 0;
  2069. break;
  2070. STEP( 44 )
  2071. MEM_READ( MEM_ADJUST(proc_info[ Z502_REG_7].structure_tag),
  2072. &ld->memory_info );
  2073. STEP( 45 )
  2074. MEM_READ( MEM_ADJUST( proc_info[ Z502_REG_7].pid ),
  2075. &Z502_REG_6 );
  2076. STEP( 46 )
  2077. MEM_READ( MEM_ADJUST( proc_info[ Z502_REG_7].mailbox ),
  2078. &Z502_REG_2 );
  2079. STEP( 47 )
  2080. MEM_READ( MEM_ADJUST( proc_info[Z502_REG_7].writer_of_mailbox),
  2081. &Z502_REG_3 );
  2082. STEP( 48 )
  2083. printf( "Mailbox info for index %ld:\n", Z502_REG_7 );
  2084. printf( "\t\t\t%d %ld %ld %ld\n",
  2085. ld->memory_info, Z502_REG_6, Z502_REG_2, Z502_REG_3 );
  2086. Z502_REG_7++;
  2087. if ( Z502_REG_7 < ld->memory_info )
  2088. {
  2089. GO_NEXT_TO( 44 );
  2090. }
  2091. else
  2092. {
  2093. GO_NEXT_TO( 60 );
  2094. }
  2095. break;
  2096. STEP( 60 )
  2097. TERMINATE_PROCESS( -1, &Z502_REG_9 );
  2098. } /* End of SELECT */
  2099. } /* End of while */
  2100. } /* End of test2gx */
  2101. /**************************************************************************
  2102. get_skewed_random_number Is a homegrown deterministic random
  2103. number generator. It produces numbers that are NOT uniform across
  2104. the allowed range.
  2105. This is useful in picking page locations so that pages
  2106. get reused and makes a LRU algorithm meaningful.
  2107. This algorithm is VERY good for developing page replacement tests.
  2108. **************************************************************************/
  2109. #define SKEWING_FACTOR 0.60
  2110. void get_skewed_random_number( long *random_number, long range )
  2111. {
  2112. double temp;
  2113. long extended_range = (long)pow( range, (double)(1/SKEWING_FACTOR) );
  2114. temp = (double)rand();
  2115. if ( temp < 0 )
  2116. temp = -temp;
  2117. temp = (double)((long)temp % extended_range);
  2118. temp = pow(temp, (double)SKEWING_FACTOR);
  2119. *random_number = (long)temp;
  2120. } /* End get_skewed_random_number */