-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.c.bkup
2735 lines (2111 loc) · 104 KB
/
test.c.bkup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/************************************************************************
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 );