/test.c
C | 2743 lines | 1588 code | 491 blank | 664 comment | 158 complexity | 275cb323385a166f20cd2dae60cb3916 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /************************************************************************
- test.c
- These programs are designed to test the OS502 functionality
- Read Appendix B about test programs and Appendix C concerning
- system calls when attempting to understand these programs.
- Revision History:
- 1.0 August 1990
- 1.1 December 1990: Tests cleaned up; 1b, 1e - 1k added
- Portability attempted.
- 1.2 December 1991: Still working on portabililty.
- 1.3 July 1992: tests1i/1j made re-entrant.
- 1.4 December 1992: Minor changes - portability
- tests2c/2d added. 2f/2g rewritten
- 1.5 August 1993: Produced new test2g to replace old
- 2g that did a swapping test.
- 1.6 June 1995: Test Cleanup.
- 1.7 June 1999: Add test0, minor fixes.
- 2.0 January 2000: Lots of small changes & bug fixes
- 2.1 March 2001: Minor Bugfixes.
- Rewrote get_skewed_random_number
- 2.2 July 2002: Make appropriate for undergrads
- 3.0 August 2004: Modified to support memory mapped IO
- 3.1 August 2004: hardware interrupt runs on separate thread
- 3.11 August 2004: Support for OS level locking
- 3.13 November 2004: Minor fix defining USER
- 3.41 August 2009: Additional work for multiprocessor + 64 bit
- 3.53 November 2011: Changed test2c so data structure used
- ints (4 bytes) rather than longs.
- ************************************************************************/
- #define USER
- #include "global.h"
- #include "syscalls.h"
- #include "z502.h"
- #include "protos.h"
- #include "stdio.h"
- #include "string.h"
- #include "stdlib.h"
- #include "math.h"
- extern INT16 Z502_PROGRAM_COUNTER;
- extern INT32 SYS_CALL_CALL_TYPE;
- extern Z502_ARG Z502_ARG1;
- extern Z502_ARG Z502_ARG2;
- extern Z502_ARG Z502_ARG3;
- extern Z502_ARG Z502_ARG4;
- extern Z502_ARG Z502_ARG5;
- extern Z502_ARG Z502_ARG6;
- extern long Z502_REG_1;
- extern long Z502_REG_2;
- extern long Z502_REG_3;
- extern long Z502_REG_4;
- extern long Z502_REG_5;
- extern long Z502_REG_6;
- extern long Z502_REG_7;
- extern long Z502_REG_8;
- extern long Z502_REG_9;
- extern INT16 Z502_MODE;
- /* Prototypes for internally called routines. */
- void test1x( void );
- void test1j_echo( void );
- void test2gx( void );
- void error_expected( INT32, char[] );
- void success_expected( INT32, char[] );
- /**************************************************************************
- Test0
-
- Exercises GET_TIME_OF_DAY and TERMINATE_PROCESS
- Z502_REG_1 Time returned from call
- Z502_REG_9 Error returned
- **************************************************************************/
- void test0( void ) {
- SELECT_STEP {
- STEP( 0 )
- printf( "This is Release %s: Test 0\n", CURRENT_REL );
- GET_TIME_OF_DAY( &Z502_REG_1 );
- STEP( 1 )
- printf( "Time of day is %ld\n", Z502_REG_1 );
- TERMINATE_PROCESS( -1, &Z502_REG_9 );
- STEP( 2 )
- printf( "ERROR: Test should be terminated but isn't.\n");
- break;
- } // End of SELECT
- } // End of test0
- /**************************************************************************
- Test1a
-
- Exercises GET_TIME_OF_DAY and SLEEP and TERMINATE_PROCESS
- Z502_REG_9 Error returned
- **************************************************************************/
- void test1a( void ) {
- static INT32 sleep_time = 100;
- static INT32 time1, time2;
- SELECT_STEP {
- STEP( 0 )
- printf( "This is Release %s: Test 1a\n", CURRENT_REL );
- GET_TIME_OF_DAY( &time1 );
- STEP( 1 )
- SLEEP ( sleep_time );
- STEP( 2 )
- GET_TIME_OF_DAY( &time2 );
- STEP( 3 )
- printf( "sleep time= %d, elapsed time= %d\n",
- sleep_time, time2 - time1 );
- TERMINATE_PROCESS( -1, &Z502_REG_9 );
- STEP( 4 )
- printf( "ERROR: Test should be terminated but isn't.\n");
- break;
- } /* End of SELECT */
- } /* End of test1a */
- /**************************************************************************
- Test1b
-
- Exercises the CREATE_PROCESS and GET_PROCESS_ID commands.
- This test tries lots of different inputs for create_process.
- In particular, there are tests for each of the following:
- 1. use of illegal priorities
- 2. use of a process name of an already existing process.
- 3. creation of a LARGE number of processes, showing that
- there is a limit somewhere ( you run out of some
- resource ) in which case you take appropriate action.
- Test the following items for get_process_id:
- 1. Various legal process id inputs.
- 2. An illegal/non-existant name.
- Z502_REG_1, _2 Used as return of process id's.
- Z502_REG_3 Cntr of # of processes created.
- Z502_REG_9 Used as return of error code.
- **************************************************************************/
- #define ILLEGAL_PRIORITY -3
- #define LEGAL_PRIORITY 10
- void test1b( void) {
- static char process_name[16];
- while (1) {
- SELECT_STEP {
- /* Try to create a process with an illegal priority. */
- STEP( 0 )
- printf( "This is Release %s: Test 1b\n", CURRENT_REL );
- CREATE_PROCESS( "test1b_a", test1x, ILLEGAL_PRIORITY,
- &Z502_REG_1, &Z502_REG_9 );
- STEP( 1 )
- error_expected( Z502_REG_9, "CREATE_PROCESS" );
- /* Create two processes with same name - 1st succeeds, 2nd fails */
- CREATE_PROCESS( "two_the_same", test1x, LEGAL_PRIORITY,
- &Z502_REG_2, &Z502_REG_9 );
- STEP( 2 )
- success_expected( Z502_REG_9, "CREATE_PROCESS" );
- CREATE_PROCESS( "two_the_same", test1x, LEGAL_PRIORITY,
- &Z502_REG_1, &Z502_REG_9 );
- STEP( 3 )
- error_expected( Z502_REG_9, "CREATE_PROCESS" );
- TERMINATE_PROCESS( Z502_REG_2, &Z502_REG_9 );
- STEP( 4 )
- success_expected( Z502_REG_9, "TERMINATE_PROCESS" );
- break;
- /* Loop until an error is found on the create_process.
- Since the call itself is legal, we must get an error
- because we exceed some limit. */
- STEP( 5 )
- Z502_REG_3++; /* Generate next prog name*/
- sprintf( process_name, "Test1b_%ld", Z502_REG_3 );
- printf( "Creating process \"%s\"\n", process_name );
- CREATE_PROCESS( process_name, test1x, LEGAL_PRIORITY,
- &Z502_REG_1, &Z502_REG_9 );
- STEP( 6 )
- if ( Z502_REG_9 == ERR_SUCCESS )
- {
- GO_NEXT_TO( 5 ) /* LOOP BACK */
- }
- break;
- /* When we get here, we've created all the processes we can.*/
- STEP( 7 )
- error_expected( Z502_REG_9, "CREATE_PROCESS" );
- printf( "%ld processes were created in all.\n", Z502_REG_3 );
- /* Now test the call GET_PROCESS_ID */
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 ); /* Legal */
- STEP( 8 )
- success_expected( Z502_REG_9, "GET_PROCESS_ID" );
- printf( "The PID of this process is %ld\n", Z502_REG_2 );
- strcpy( process_name, "Test1b_1" );
- GET_PROCESS_ID( process_name, &Z502_REG_1,
- &Z502_REG_9 ); /* Legal */
- STEP( 9 )
- success_expected( Z502_REG_9, "GET_PROCESS_ID" );
- printf( "The PID of target process is %ld\n", Z502_REG_1 );
- GET_PROCESS_ID( "bogus_name", &Z502_REG_1,
- &Z502_REG_9 ); /* Illegal */
- STEP( 10 )
- error_expected( Z502_REG_9, "GET_PROCESS_ID" );
- GET_TIME_OF_DAY( &Z502_REG_4 );
- STEP( 11 )
- printf( "Test1b, PID %ld, Ends at Time %ld\n",
- Z502_REG_2, Z502_REG_4);
- TERMINATE_PROCESS( -2, &Z502_REG_9 )
- } /* End of SELECT */
- } /* End of while */
- } /* End of test1b */
- /**************************************************************************
- Test1c
- Tests multiple copies of test1x running simultaneously.
- Test1c runs these with the same priority in order to show
- FCFS scheduling behavior; Test1d uses different priorities
- in order to show priority scheduling.
- WARNING: This test assumes tests 1a - 1b run successfully
- Z502_REG_1, 2, 3, 4, 5 Used as return of process id's.
- Z502_REG_6 Return of PID on GET_PROCESS_ID
- Z502_REG_9 Used as return of error code.
- **************************************************************************/
- #define PRIORITY1C 10
- void test1c( void)
- {
- static INT32 sleep_time = 1000;
- while( 1 )
- {
- SELECT_STEP
- {
- STEP( 0 )
- printf( "This is Release %s: Test 1c\n", CURRENT_REL );
- CREATE_PROCESS( "test1c_a", test1x, PRIORITY1C,
- &Z502_REG_1, &Z502_REG_9 );
-
- STEP( 1 )
- success_expected( Z502_REG_9, "CREATE_PROCESS" );
- CREATE_PROCESS( "test1c_b", test1x, PRIORITY1C,
- &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 2 )
- CREATE_PROCESS( "test1c_c", test1x, PRIORITY1C,
- &Z502_REG_3, &Z502_REG_9 );
-
- STEP( 3 )
- CREATE_PROCESS( "test1c_d", test1x, PRIORITY1C,
- &Z502_REG_4, &Z502_REG_9 );
-
- STEP( 4 )
- CREATE_PROCESS( "test1c_e", test1x, PRIORITY1C,
- &Z502_REG_5, &Z502_REG_9 );
-
- /* In these next three cases, we will loop until the target
- process ( test1c_e ) has terminated. We know it
- terminated because for a while we get success on the call
- GET_PROCESS_ID, and then we get failure when the process
- no longer exists. */
- STEP( 5 )
- SLEEP ( sleep_time );
-
- STEP( 6 )
- GET_PROCESS_ID( "test1c_e", &Z502_REG_6, &Z502_REG_9 );
-
- STEP( 7 )
- if ( Z502_REG_9 == ERR_SUCCESS )
- GO_NEXT_TO( 5 ) /* Loop back */
- break;
- STEP( 8 )
- TERMINATE_PROCESS( -2, &Z502_REG_9 ); /* Terminate all */
-
- } /* End switch */
- } /* End while */
- } /* End test1c */
- /**************************************************************************
- Test 1d
-
- Tests multiple copies of test1x running simultaneously.
- Test1c runs these with the same priority in order to show
- FCFS scheduling behavior; Test1d uses different priorities
- in order to show priority scheduling.
- WARNING: This test assumes tests 1a - 1b run successfully
- Z502_REG_1, 2, 3, 4, 5 Used as return of process id's.
- Z502_REG_6 Return of PID on GET_PROCESS_ID
- Z502_REG_9 Used as return of error code.
- **************************************************************************/
- #define PRIORITY1 10
- #define PRIORITY2 11
- #define PRIORITY3 11
- #define PRIORITY4 90
- #define PRIORITY5 40
- void test1d( void)
- {
- static INT32 sleep_time = 1000;
- while( 1 )
- {
- SELECT_STEP
- {
- STEP( 0 )
- printf( "This is Release %s: Test 1d\n", CURRENT_REL );
- CREATE_PROCESS( "test1d_1", test1x, PRIORITY1,
- &Z502_REG_1, &Z502_REG_9 );
-
- STEP( 1 )
- success_expected( Z502_REG_9, "CREATE_PROCESS" );
- CREATE_PROCESS( "test1d_2", test1x, PRIORITY2,
- &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 2 )
- CREATE_PROCESS( "test1d_3", test1x, PRIORITY3,
- &Z502_REG_3, &Z502_REG_9 );
- STEP( 3 )
- CREATE_PROCESS( "test1d_4", test1x, PRIORITY4,
- &Z502_REG_4, &Z502_REG_9 );
-
- STEP( 4 )
- CREATE_PROCESS( "test1d_5", test1x, PRIORITY5,
- &Z502_REG_5, &Z502_REG_9 );
-
- /* We will loop until the target process ( test1d_4 ) has terminated.
- We know it terminated because for a while we get success on the call
- GET_PROCESS_ID, and then failure when the process no longer exists. */
- STEP( 5 )
- SLEEP ( sleep_time );
-
- STEP( 6 )
- GET_PROCESS_ID( "test1d_4", &Z502_REG_6, &Z502_REG_9 );
-
- STEP( 7 )
- if ( Z502_REG_9 == ERR_SUCCESS )
- GO_NEXT_TO( 5 ) /* Loop back */
- break;
- STEP( 8 )
- TERMINATE_PROCESS( -2, &Z502_REG_9 );
-
- } /* End switch */
- } /* End while */
- } /* End test1d */
- /**************************************************************************
- Test 1e exercises the SUSPEND_PROCESS and RESUME_PROCESS commands
-
- This test should try lots of different inputs for suspend and resume.
- In particular, there should be tests for each of the following:
- 1. use of illegal process id.
- 2. what happens when you suspend yourself - is it legal? The answer
- to this depends on the OS architecture and is up to the developer.
- 3. suspending an already suspended process.
- 4. resuming a process that's not suspended.
- there are probably lots of other conditions possible.
-
- Z502_REG_1 Target process ID
- Z502_REG_2 OUR process ID
- Z502_REG_9 Error returned
- **************************************************************************/
- #define LEGAL_PRIORITY_1E 10
- void test1e( void)
- {
- SELECT_STEP
- {
- STEP( 0 ) /* Get OUR PID */
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 1 ) /* Make legal target */
- printf( "Release %s:Test 1e: Pid %ld\n", CURRENT_REL, Z502_REG_2 );
- CREATE_PROCESS( "test1e_a", test1x, LEGAL_PRIORITY_1E,
- &Z502_REG_1, &Z502_REG_9);
-
- STEP( 2 )
- success_expected( Z502_REG_9, "CREATE_PROCESS" );
- /* Suspend Illegal PID */
- SUSPEND_PROCESS( (INT32)9999, &Z502_REG_9);
-
- STEP( 3 )
- error_expected( Z502_REG_9, "SUSPEND_PROCESS" );
- /* Resume Illegal PID */
- RESUME_PROCESS( (INT32)9999, &Z502_REG_9);
-
- STEP( 4 )
- error_expected( Z502_REG_9, "RESUME_PROCESS" );
- /* Suspend legal PID */
- SUSPEND_PROCESS(Z502_REG_1, &Z502_REG_9);
-
- STEP( 5 )
- success_expected( Z502_REG_9, "SUSPEND_PROCESS" );
- /* Suspend already suspended PID */
- SUSPEND_PROCESS(Z502_REG_1, &Z502_REG_9);
-
- STEP( 6 )
- error_expected( Z502_REG_9, "SUSPEND_PROCESS" );
- /* Do a legal resume */
- RESUME_PROCESS(Z502_REG_1, &Z502_REG_9);
-
- STEP( 7 )
- success_expected( Z502_REG_9, "RESUME_PROCESS" );
- /* Resume an already resumed process */
- RESUME_PROCESS(Z502_REG_1, &Z502_REG_9);
-
- STEP( 8 )
- error_expected( Z502_REG_9, "RESUME_PROCESS" );
- /* Try to resume ourselves */
- RESUME_PROCESS(Z502_REG_2, &Z502_REG_9);
- STEP( 9 )
- error_expected( Z502_REG_9, "RESUME_PROCESS" );
- /* It may or may not be legal to suspend ourselves;
- architectural decision. */
- SUSPEND_PROCESS(-1, &Z502_REG_9);
-
- STEP( 10 )
- /* If we returned "SUCCESS" here, then there is an inconsistancy;
- * success implies that the process was suspended. But if we
- * get here, then we obviously weren't suspended. Therefore
- * this must be an error. */
- error_expected( Z502_REG_9, "SUSPEND_PROCESS" );
- GET_TIME_OF_DAY( &Z502_REG_4 );
- STEP( 11 )
- printf( "Test1e, PID %ld, Ends at Time %ld\n", Z502_REG_2, Z502_REG_4);
- TERMINATE_PROCESS(-2, &Z502_REG_9);
- } /* End of SELECT */
- } /* End of test1e */
- /**************************************************************************
- Test1f Successfully suspend and resume processes.
-
- In particular, show what happens to scheduling when processes
- are temporarily suspended.
- This test works by starting up a number of processes at different
- priorities. Then some of them are suspended. Then some are resumed.
- Z502_REG_1 Loop counter
- Z502_REG_2 OUR process ID
- Z502_REG_3,4,5,6,7 Target process ID
- Z502_REG_9 Error returned
- **************************************************************************/
- #define PRIORITY_1F1 5
- #define PRIORITY_1F2 10
- #define PRIORITY_1F3 15
- #define PRIORITY_1F4 20
- #define PRIORITY_1F5 25
- void test1f( void)
- {
- static INT32 sleep_time = 300;
- SELECT_STEP
- {
- STEP( 0 ) /* Get OUR PID */
- Z502_REG_1 = 0; /* Initialize */
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 1 ) /* Make legal target */
- printf( "Release %s:Test 1f: Pid %ld\n",
- CURRENT_REL, Z502_REG_2 );
- CREATE_PROCESS( "test1f_a", test1x, PRIORITY_1F1,
- &Z502_REG_3, &Z502_REG_9);
-
- STEP( 2 ) /* Make legal target */
- CREATE_PROCESS( "test1f_b", test1x, PRIORITY_1F2,
- &Z502_REG_4, &Z502_REG_9);
-
- STEP( 3 ) /* Make legal target */
- CREATE_PROCESS( "test1f_c", test1x, PRIORITY_1F3,
- &Z502_REG_5, &Z502_REG_9);
-
- STEP( 4 ) /* Make legal target */
- CREATE_PROCESS( "test1f_d", test1x, PRIORITY_1F4,
- &Z502_REG_6, &Z502_REG_9);
-
- STEP( 5 ) /* Make legal target */
- CREATE_PROCESS( "test1f_e", test1x, PRIORITY_1F5,
- &Z502_REG_7, &Z502_REG_9);
-
- /* Let the 5 pids go for a bit */
- STEP( 6 )
- SLEEP ( sleep_time );
-
- /* Suspend 3 of the pids and see what happens - we
- should see scheduling behavior where the processes
- are yanked out of the ready and the waiting states,
- and placed into the suspended state. */
- STEP( 7 )
- SUSPEND_PROCESS(Z502_REG_3, &Z502_REG_9);
- STEP( 8 )
- SUSPEND_PROCESS(Z502_REG_5, &Z502_REG_9);
- STEP( 9 )
- SUSPEND_PROCESS(Z502_REG_7, &Z502_REG_9);
- STEP( 10 )
- SLEEP ( sleep_time );
-
- STEP( 11 )
- RESUME_PROCESS(Z502_REG_3, &Z502_REG_9);
-
- STEP( 12 )
- RESUME_PROCESS(Z502_REG_5, &Z502_REG_9);
-
- STEP( 13 )
- if ( Z502_REG_1 < 4 )
- GO_NEXT_TO( 6 )
- Z502_REG_1++; /* Inc the loop counter */
- RESUME_PROCESS(Z502_REG_7, &Z502_REG_9);
- /* Wait for children to finish, then quit */
- STEP( 14 )
- SLEEP ( (INT32)10000 );
- STEP( 15 )
- TERMINATE_PROCESS(-1, &Z502_REG_9);
-
- } /* End of SELECT */
- } /* End of test1f */
- /**************************************************************************
- Test1g Generate lots of errors for CHANGE_PRIORITY
- Try lots of different inputs: In particular, some of the possible
- inputs include:
- 1. use of illegal priorities
- 2. use of an illegal process id.
-
- Z502_REG_1 Target process ID
- Z502_REG_2 OUR process ID
- Z502_REG_9 Error returned
- **************************************************************************/
- #define LEGAL_PRIORITY_1G 10
- #define ILLEGAL_PRIORITY_1G 999
- void test1g( void)
- {
- SELECT_STEP
- {
- STEP( 0 ) /* Get OUR PID */
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 1 ) /* Make legal target */
- printf( "Release %s:Test 1g: Pid %ld\n", CURRENT_REL, Z502_REG_2 );
- CREATE_PROCESS( "test1g_a", test1x, LEGAL_PRIORITY_1G,
- &Z502_REG_1, &Z502_REG_9);
-
- STEP( 2 )
- success_expected( Z502_REG_9, "CREATE_PROCESS" );
- /* Target Illegal PID */
- CHANGE_PRIORITY( (INT32)9999, LEGAL_PRIORITY_1G, &Z502_REG_9);
-
- STEP( 3 )
- error_expected( Z502_REG_9, "CHANGE_PRIORITY" );
- /* Use illegal priority */
- CHANGE_PRIORITY( Z502_REG_1, ILLEGAL_PRIORITY_1G, &Z502_REG_9);
-
- STEP( 4 )
- error_expected( Z502_REG_9, "CHANGE_PRIORITY" );
- // Change made - I assume both proce
- TERMINATE_PROCESS(-2, &Z502_REG_9);
-
- } /* End of SELECT */
- } /* End of test1g */
- /**************************************************************************
- Test1h Successfully change the priority of a process
- When you change the priority, it should be possible to see
- the scheduling behaviour of the system change; processes
- that used to be scheduled first are no longer first.
-
- Z502_REG_2 OUR process ID
- Z502_REG_3 - 5 Target process IDs
- Z502_REG_9 Error returned
- **************************************************************************/
- #define MOST_FAVORABLE_PRIORITY 1
- #define FAVORABLE_PRIORITY 10
- #define NORMAL_PRIORITY 20
- #define LEAST_FAVORABLE_PRIORITY 30
- void test1h( void)
- {
- INT32 ourself;
- SELECT_STEP
- {
- STEP( 0 ) /* Get OUR PID */
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 1 ) /* Make our priority high */
- printf( "Release %s:Test 1h: Pid %ld\n",
- CURRENT_REL, Z502_REG_2 );
- ourself = -1;
- CHANGE_PRIORITY( ourself, MOST_FAVORABLE_PRIORITY,
- &Z502_REG_9);
- STEP( 2 ) /* Make legal targets */
- CREATE_PROCESS( "test1h_a", test1x, NORMAL_PRIORITY,
- &Z502_REG_3, &Z502_REG_9);
-
- STEP( 3 ) /* Make legal targets */
- CREATE_PROCESS( "test1h_b", test1x, NORMAL_PRIORITY,
- &Z502_REG_4, &Z502_REG_9);
-
- STEP( 4 ) /* Make legal targets */
- CREATE_PROCESS( "test1h_c", test1x, NORMAL_PRIORITY,
- &Z502_REG_5, &Z502_REG_9);
- /* Sleep awhile to watch the scheduling */
- STEP( 5 )
- SLEEP( 200 );
- /* Now change the priority - it should be possible to see
- that the priorities have been changed for processes that
- are ready and for processes that are sleeping. */
- STEP( 6 )
- CHANGE_PRIORITY( Z502_REG_3, FAVORABLE_PRIORITY,
- &Z502_REG_9);
- STEP( 7 )
- CHANGE_PRIORITY( Z502_REG_5, LEAST_FAVORABLE_PRIORITY,
- &Z502_REG_9);
- /* Sleep awhile to watch the scheduling */
- STEP( 8 )
- SLEEP( 200 );
- /* Now change the priority - it should be possible to see
- that the priorities have been changed for processes that
- are ready and for processes that are sleeping. */
- STEP( 9 )
- CHANGE_PRIORITY( Z502_REG_3, LEAST_FAVORABLE_PRIORITY,
- &Z502_REG_9);
- STEP( 10 )
- CHANGE_PRIORITY( Z502_REG_4, FAVORABLE_PRIORITY,
- &Z502_REG_9);
- /* Sleep awhile to watch the scheduling */
- STEP( 11 )
- SLEEP( 600 );
- STEP( 12 )
- TERMINATE_PROCESS(-2, &Z502_REG_9);
- } /* End of SELECT */
- } /* End of test1h */
- /**************************************************************************
- Test1i SEND_MESSAGE and RECEIVE_MESSAGE with errors.
- This has the same kind of error conditions that previous tests did;
- bad PIDs, bad message lengths, illegal buffer addresses, etc.
- Your imagination can go WILD on this one.
- This is a good time to mention os_switch_context_complete:::::
- As you know, after doing a switch_context, the hardware passes
- control to the code in this test. What hasn't been obvious thus
- far, is that control passes from swich_context, THEN to routine,
- os_switch_context_complete, and THEN to this test code.
- What it does: This function allows you to gain control in the
- OS of a scheduled-in process before it goes to test.
- Where to find it: The code is in base.c - right now it does nothing.
- Why use it: Suppose process A has sent a message to
- process B. It so happens that you may well want
- to do some preparation in process B once it's
- registers are in memory, but BEFORE it executes
- the test. In other words, it allows you to
- complete the work for the send to process B.
-
- Z502_REG_1 Pointer to data private to each process
- running this routine.
- Z502_REG_2 OUR process ID
- Z502_REG_3 Target process IDs
- Z502_REG_9 Error returned
- **************************************************************************/
- #define LEGAL_MESSAGE_LENGTH (INT16)64
- #define ILLEGAL_MESSAGE_LENGTH (INT16)1000
- #define MOST_FAVORABLE_PRIORITY 1
- #define NORMAL_PRIORITY 20
- typedef struct
- {
- INT32 target_pid;
- INT32 source_pid;
- INT32 actual_source_pid;
- INT32 send_length;
- INT32 receive_length;
- INT32 actual_send_length;
- INT32 loop_count;
- char msg_buffer[LEGAL_MESSAGE_LENGTH];
- } TEST1I_DATA;
- void test1i( void)
- {
- TEST1I_DATA *td; /* Use as ptr to data */
- /* Here we maintain the data to be used by this process when running
- on this routine. This code should be re-entrant. */
- if ( Z502_REG_1 == 0 )
- {
- Z502_REG_1 = (long)calloc( 1, sizeof ( TEST1I_DATA ));
- if ( Z502_REG_1 == 0 )
- {
- printf( "Something screwed up allocating space in test1i\n" );
- }
- td = ( TEST1I_DATA *)Z502_REG_1;
- td->loop_count = 0;
- }
- td = ( TEST1I_DATA *)Z502_REG_1;
- while ( 1 )
- {
- SELECT_STEP
- {
- STEP( 0 ) /* Get OUR PID */
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 1 ) /* Make our prior high */
- printf( "Release %s:Test 1i: Pid %ld\n", CURRENT_REL, Z502_REG_2 );
- CHANGE_PRIORITY( -1, MOST_FAVORABLE_PRIORITY, &Z502_REG_9);
- STEP( 2 ) /* Make legal targets */
- CREATE_PROCESS( "test1i_a", test1x, NORMAL_PRIORITY,
- &Z502_REG_3, &Z502_REG_9);
-
- STEP( 3 ) /* Send to illegal process */
- td->target_pid = 9999;
- td->send_length= 8;
- SEND_MESSAGE( td->target_pid, "message", td->send_length, &Z502_REG_9 );
-
- STEP( 4 )
- error_expected( Z502_REG_9, "SEND_MESSAGE" );
- /* Try an illegal message length */
- td->target_pid = Z502_REG_3;
- td->send_length= ILLEGAL_MESSAGE_LENGTH;
- SEND_MESSAGE( td->target_pid, "message", td->send_length, &Z502_REG_9 );
-
- STEP( 5 )
- error_expected( Z502_REG_9, "SEND_MESSAGE" );
- /* Receive from illegal process */
- td->source_pid = 9999;
- td->receive_length = LEGAL_MESSAGE_LENGTH;
- RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
- td->receive_length, &(td->actual_send_length),
- &(td->actual_source_pid), &Z502_REG_9 );
- STEP( 6 )
- error_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
- /* Receive with illegal buffer size */
- td->source_pid = Z502_REG_3;
- td->receive_length = ILLEGAL_MESSAGE_LENGTH;
- RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
- td->receive_length, &(td->actual_send_length),
- &(td->actual_source_pid), &Z502_REG_9 );
- STEP( 7 )
- error_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
- /* Send a legal ( but long ) message to self */
- td->target_pid = Z502_REG_2;
- td->send_length= LEGAL_MESSAGE_LENGTH;
- SEND_MESSAGE( td->target_pid, "a long but legal message",
- td->send_length, &Z502_REG_9 );
- STEP( 8 )
- success_expected( Z502_REG_9, "SEND_MESSAGE" );
- td->loop_count++;
- /* Receive this long message, which should error
- because the receive buffer is too small */
- td->source_pid = Z502_REG_2;
- td->receive_length = 10;
- RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
- td->receive_length, &(td->actual_send_length),
- &(td->actual_source_pid), &Z502_REG_9 );
- STEP( 9 )
- error_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
- break;
- /* Keep sending legal messages until the architectural
- limit for buffer space is exhausted. In order to pass
- the test1j, this number should be at least EIGHT */
- STEP( 10 )
- td->target_pid = Z502_REG_3;
- td->send_length= LEGAL_MESSAGE_LENGTH;
- SEND_MESSAGE( td->target_pid, "message", td->send_length, &Z502_REG_9 );
-
- STEP( 11 )
- if (Z502_REG_9 == ERR_SUCCESS)
- GO_NEXT_TO( 10 ) /* Loop back */
- td->loop_count++;
- break;
- STEP( 12 )
- printf( "A total of %d messages were enqueued.\n", td->loop_count - 1 );
- TERMINATE_PROCESS(-2, &Z502_REG_9);
- } /* End of SELECT */
- } /* End of while */
- } /* End of test1i */
-
- /**************************************************************************
- Test1j SEND_MESSAGE and RECEIVE_MESSAGE Successfully.
- Creates three other processes, each running their own code.
- RECEIVE and SEND messages are winged back and forth at them.
-
- Z502_REG_1 Pointer to data private to each process
- running this routine.
- Z502_REG_2 OUR process ID
- Z502_REG_3 - 5 Target process IDs
- Z502_REG_9 Error returned
- Again, as mentioned in detail on Test1i, use of the code in
- os_switch_context_complete could be beneficial here. In fact
- it will be difficult to make the test work successfully UNLESS
- you use the os_switch_context_complete().
- The SEND and RECEIVE system calls as implemented by this test
- imply the following behavior:
- SENDER = PID A RECEIVER = PID B,
- Designates source_pid =
- target_pid = A C -1
- ----------------+------------+------------+--------------+
- | | | |
- B | Message | X | Message |
- |Transmitted | | Transmitted |
- ----------------+------------+------------+--------------+
- | | | |
- C | X | X | X |
- | | | |
- ----------------+------------+------------+--------------+
- | | | |
- -1 | Message | X | Message |
- | Transmitted| | Transmitted |
- ----------------+------------+------------+--------------+
- A broadcast ( target_pid = -1 ) means send to everyone BUT yourself.
- ANY of the receiving processes can handle a broadcast message.
- A receive ( source_pid = -1 ) means receive from anyone.
- **************************************************************************/
- #define LEGAL_MESSAGE_LENGTH (INT16)64
- #define ILLEGAL_MESSAGE_LENGTH (INT16)1000
- #define MOST_FAVORABLE_PRIORITY 1
- #define NORMAL_PRIORITY 20
- typedef struct
- {
- INT32 target_pid;
- INT32 source_pid;
- INT32 actual_source_pid;
- INT32 send_length;
- INT32 receive_length;
- INT32 actual_send_length;
- INT32 send_loop_count;
- INT32 receive_loop_count;
- char msg_buffer[LEGAL_MESSAGE_LENGTH];
- char msg_sent[LEGAL_MESSAGE_LENGTH];
- } TEST1J_DATA;
- void test1j( void)
- {
- TEST1J_DATA *td; /* Use as ptr to data */
- /* Here we maintain the data to be used by this process when running
- on this routine. This code should be re-entrant. */
- if ( Z502_REG_1 == 0 )
- {
- Z502_REG_1 = (long)calloc( 1, sizeof ( TEST1J_DATA ));
- if ( Z502_REG_1 == 0 )
- {
- printf( "Something screwed up allocating space in test1j\n" );
- }
- td = ( TEST1J_DATA *)Z502_REG_1;
- td->send_loop_count = 0;
- td->receive_loop_count = 0;
- }
- td = ( TEST1J_DATA *)Z502_REG_1;
- while ( 1 )
- {
- SELECT_STEP
- {
- STEP( 0 ) /* Get OUR PID */
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 1 ) /* Make our prior high */
- printf( "Release %s:Test 1j: Pid %ld\n",
- CURRENT_REL, Z502_REG_2 );
- CHANGE_PRIORITY( -1, MOST_FAVORABLE_PRIORITY,
- &Z502_REG_9);
- STEP( 2 ) /* Make legal targets */
- success_expected( Z502_REG_9, "CHANGE_PRIORITY" );
- CREATE_PROCESS( "test1j_1", test1j_echo, NORMAL_PRIORITY,
- &Z502_REG_3, &Z502_REG_9);
-
- STEP( 3 ) /* Make legal targets */
- success_expected( Z502_REG_9, "CREATE_PROCESS" );
- CREATE_PROCESS( "test1j_2", test1j_echo, NORMAL_PRIORITY,
- &Z502_REG_4, &Z502_REG_9);
-
- STEP( 4 ) /* Make legal targets */
- success_expected( Z502_REG_9, "CREATE_PROCESS" );
- CREATE_PROCESS( "test1j_3", test1j_echo, NORMAL_PRIORITY,
- &Z502_REG_5, &Z502_REG_9);
- STEP( 5 )
- success_expected( Z502_REG_9, "CREATE_PROCESS" );
- /* Send/receive a legal message to each child */
- td->target_pid = Z502_REG_3;
- td->send_length= 20;
- strcpy( td->msg_sent, "message to #3" );
- SEND_MESSAGE( td->target_pid, td->msg_sent,
- td->send_length, &Z502_REG_9 );
- STEP( 6 )
- success_expected( Z502_REG_9, "SEND_MESSAGE" );
- td->source_pid = -1;
- td->receive_length = LEGAL_MESSAGE_LENGTH;
- RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
- td->receive_length, &(td->actual_send_length),
- &(td->actual_source_pid), &Z502_REG_9 );
- STEP( 7 )
- success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
- if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
- printf("ERROR - msg sent != msg received.\n");
- if ( td->actual_source_pid != Z502_REG_3 )
- printf( "ERROR - source PID not correct.\n" );
- if ( td->actual_send_length != td->send_length )
- printf( "ERROR - send length not sent correctly.\n" );
- td->target_pid = Z502_REG_4;
- td->send_length= 20;
- strcpy( td->msg_sent, "message to #4" );
- SEND_MESSAGE( td->target_pid, td->msg_sent,
- td->send_length, &Z502_REG_9 );
- STEP( 8 )
- success_expected( Z502_REG_9, "SEND_MESSAGE" );
- td->source_pid = -1;
- td->receive_length = LEGAL_MESSAGE_LENGTH;
- RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
- td->receive_length, &(td->actual_send_length),
- &(td->actual_source_pid), &Z502_REG_9 );
- STEP( 9 )
- success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
- if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
- printf("ERROR - msg sent != msg received.\n");
- if ( td->actual_source_pid != Z502_REG_4 )
- printf( "ERROR - source PID not correct.\n" );
- if ( td->actual_send_length != td->send_length )
- printf( "ERROR - send length not sent correctly.\n" );
- td->target_pid = Z502_REG_5;
- td->send_length= 20;
- strcpy( td->msg_sent, "message to #5" );
- SEND_MESSAGE( td->target_pid, td->msg_sent,
- td->send_length, &Z502_REG_9 );
- STEP( 10 )
- success_expected( Z502_REG_9, "SEND_MESSAGE" );
- td->source_pid = -1;
- td->receive_length = LEGAL_MESSAGE_LENGTH;
- RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
- td->receive_length, &(td->actual_send_length),
- &(td->actual_source_pid), &Z502_REG_9 );
- STEP( 11 )
- success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
- if ( strcmp( td->msg_buffer, td->msg_sent ) != 0 )
- printf("ERROR - msg sent != msg received.\n");
- if ( td->actual_source_pid != Z502_REG_5 )
- printf( "ERROR - source PID not correct.\n" );
- if ( td->actual_send_length != td->send_length )
- printf( "ERROR - send length not sent correctly.\n" );
- break; // Bugfix 08/2012 - Rel 3.60 so we explicitly
- // go to the next step
- /* Keep sending legal messages until the architectural (OS)
- limit for buffer space is exhausted. */
- STEP( 12 )
- td->target_pid = -1;
- sprintf( td->msg_sent, "This is message %d",
- td->send_loop_count );
- td->send_length= 20;
- SEND_MESSAGE( td->target_pid, td->msg_sent,
- td->send_length, &Z502_REG_9 );
-
- STEP( 13 )
- if (Z502_REG_9 == ERR_SUCCESS)
- GO_NEXT_TO( 12 ) /* Loop back */
- td->send_loop_count++;
- break;
- STEP( 14 )
- td->send_loop_count--;
- printf( "A total of %d messages were enqueued.\n",
- td->send_loop_count );
- break;
- STEP( 15 )
- td->source_pid = -1;
- td->receive_length = LEGAL_MESSAGE_LENGTH;
- RECEIVE_MESSAGE( td->source_pid, td->msg_buffer,
- td->receive_length, &(td->actual_send_length),
- &(td->actual_source_pid), &Z502_REG_9 );
- STEP( 16 )
- success_expected( Z502_REG_9, "RECEIVE_MESSAGE" );
- printf( "Receive from PID = %d: length = %d: msg = %s:\n",
- td->actual_source_pid, td->actual_send_length,
- td->msg_buffer );
- td->receive_loop_count++;
- if ( td->receive_loop_count < td->send_loop_count )
- GO_NEXT_TO( 15 ) /* Loop back */
- break;
- STEP( 17 )
- printf( "A total of %d messages were received.\n",
- td->receive_loop_count - 1 );
- TERMINATE_PROCESS(-2, &Z502_REG_9);
- } /* End of SELECT */
- } /* End of while */
- } /* End of test1j */
- /**************************************************************************
- Test1k Test other oddities in your system.
- There are many other strange effects, not taken into account
- by the previous tests. One of these is:
- 1. Executing a privileged instruction from a user program
-
- Registers Used:
- Z502_REG_2 OUR process ID
- Z502_REG_9 Error returned
-
- **************************************************************************/
- void test1k( void)
- {
- INT32 Result;
- SELECT_STEP
- {
- STEP( 0 )
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
-
- STEP( 1 )
- printf( "Release %s:Test 1k: Pid %ld\n", CURRENT_REL, Z502_REG_2 );
- /* Do an illegal hardware instruction - we will
- not return from this. */
- MEM_READ( Z502TimerStatus, &Result);
- } /* End of SELECT */
- } /* End of test1k */
- /**************************************************************************
- Test1l SEND_MESSAGE and RECEIVE_MESSAGE with SUSPEND/RESUME
- Explores how message handling is done in the midst of SUSPEND/RESUME
- system calls,
-
- The SEND and RECEIVE system calls as implemented by this test
- imply the following behavior:
- Case 1:
- - a process waiting to recieve a message can be suspended
- - a process waiting to recieve a message can be resumed
- - after being resumed, it can receive a message
- Case 2:
- - when a process waiting for a message is suspended, it is out of
- circulation and cannot recieve any message
- - once it is unsuspended, it may recieve a message and go on the ready
- queue
- Case 3:
- - a process that waited for and found a message is now the ready queue
- - this process can be suspended before handling the message
- - the message and process remain paired up, no other process can have
- that message
- - when resumed, the process will handle the message
- **************************************************************************/
- #define LEGAL_MESSAGE_LENGTH (INT16)64
- #define MOST_FAVORABLE_PRIORITY 1
- #define NORMAL_PRIORITY 20
- typedef struct
- {
- INT32 target_pid;
- INT32 source_pid;
- INT32 actual_source_pid;
- INT32 send_length;
- INT32 receive_length;
- INT32 actual_send_length;
- INT32 send_loop_count;
- INT32 receive_loop_count;
- char msg_buffer[LEGAL_MESSAGE_LENGTH];
- char msg_sent[LEGAL_MESSAGE_LENGTH];
- } TEST1L_DATA;
- void test1l( void)
- {
- TEST1L_DATA *td; /* Use as ptr to data */
- /* Here we maintain the data to be used by this process when running
- on this routine. This code should be re-entrant. */
- if ( Z502_REG_1 == 0 )
- {
- Z502_REG_1 = (long)calloc( 1, sizeof ( TEST1L_DATA ));
- if ( Z502_REG_1 == 0 )
- {
- printf( "Something screwed up allocating space in test1j\n" );
- }
- td = ( TEST1L_DATA *)Z502_REG_1;
- td->send_loop_count = 0;
- td->receive_loop_count = 0;
- }
- td = ( TEST1L_DATA *)Z502_REG_1;
- while ( 1 )
- {
- SELECT_STEP
- {
- STEP( 0 ) /* Get OUR PID */
- GET_PROCESS_ID( "", &Z502_REG_2, &Z502_REG_9 );
- STEP( 1 ) /* Make our prior high */
- printf( "Release %s:Test 1l: Pid %ld\n",
- CURRENT_REL, Z502_REG_2 );
- CHANGE_PRIORITY( -1, MOST_FAVORABLE_PRIORITY,
- &Z502_REG_9);
- STEP( 2 ) /* Make process to test with */
- succes…
Large files files are truncated, but you can click here to view the full file