1 
2 /*******************************************************************************
3  *  The BYTE UNIX Benchmarks - Release 3
4  *          Module: context1.c   SID: 3.3 5/15/91 19:30:18
5  *
6  *******************************************************************************
7  * Bug reports, patches, comments, suggestions should be sent to:
8  *
9  *	Ben Smith, Rick Grehan or Tom Yager
10  *	ben@bytepb.byte.com   rick_g@bytepb.byte.com   tyager@bytepb.byte.com
11  *
12  *******************************************************************************
13  *  Modification Log:
14  *  $Header: context1.c,v 3.4 87/06/22 14:22:59 kjmcdonell Beta $
15  *  August 28, 1990 - changed timing routines--now returns total number of
16  *                    iterations in specified time period
17  *  October 22, 1997 - code cleanup to remove ANSI C compiler warnings
18  *                     Andy Kahn <kahn@zk3.dec.com>
19  *
20  ******************************************************************************/
21 char SCCSid[] = "@(#) @(#)context1.c:3.3 -- 5/15/91 19:30:18";
22 /*
23  *  Context switching via synchronized unbuffered pipe i/o
24  *
25  */
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include "timeit.c"
31 
32 unsigned long iter;
33 
report()34 void report()
35 {
36 	fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
37 	exit(0);
38 }
39 
main(argc,argv)40 int main(argc, argv)
41 int	argc;
42 char	*argv[];
43 {
44 	int duration;
45 	unsigned long	check;
46 	int	p1[2], p2[2];
47 	ssize_t ret;
48 
49 	if (argc != 2) {
50 		fprintf(stderr, "Usage: context duration\n");
51 		exit(1);
52 	}
53 
54 	duration = atoi(argv[1]);
55 
56 	/* set up alarm call */
57 	iter = 0;
58 	wake_me(duration, report);
59 	signal(SIGPIPE, SIG_IGN);
60 
61 	if (pipe(p1) || pipe(p2)) {
62 		perror("pipe create failed");
63 		exit(1);
64 	}
65 
66 	if (fork()) {	/* parent process */
67 		/* master, write p1 & read p2 */
68 		close(p1[0]); close(p2[1]);
69 		while (1) {
70 			if ((ret = write(p1[1], (char *)&iter, sizeof(iter))) != sizeof(iter)) {
71 				if ((ret == -1) && (errno == EPIPE)) {
72 					alarm(0);
73 					report(); /* does not return */
74 				}
75 				if ((ret == -1) && (errno != 0) && (errno != EINTR))
76 					perror("master write failed");
77 				exit(1);
78 			}
79 			if ((ret = read(p2[0], (char *)&check, sizeof(check))) != sizeof(check)) {
80 				if ((ret == 0)) { /* end-of-stream */
81 					alarm(0);
82 					report(); /* does not return */
83 				}
84 				if ((ret == -1) && (errno != 0) && (errno != EINTR))
85 					perror("master read failed");
86 				exit(1);
87 			}
88 			if (check != iter) {
89 				fprintf(stderr, "Master sync error: expect %lu, got %lu\n",
90 					iter, check);
91 				exit(2);
92 			}
93 			iter++;
94 		}
95 	}
96 	else { /* child process */
97 		/* slave, read p1 & write p2 */
98 		close(p1[1]); close(p2[0]);
99 		while (1) {
100 			if ((ret = read(p1[0], (char *)&check, sizeof(check))) != sizeof(check)) {
101 				if ((ret == 0)) { /* end-of-stream */
102 					alarm(0);
103 					report(); /* does not return */
104 				}
105 				if ((ret == -1) && (errno != 0) && (errno != EINTR))
106 					perror("slave read failed");
107 				exit(1);
108 			}
109 			if (check != iter) {
110 				fprintf(stderr, "Slave sync error: expect %lu, got %lu\n",
111 					iter, check);
112 				exit(2);
113 			}
114 			if ((ret = write(p2[1], (char *)&iter, sizeof(iter))) != sizeof(check)) {
115 				if ((ret == -1) && (errno == EPIPE)) {
116 					alarm(0);
117 					report(); /* does not return */
118 				}
119 				if ((ret == -1) && (errno != 0) && (errno != EINTR))
120 					perror("slave write failed");
121 				exit(1);
122 			}
123 			iter++;
124 		}
125 	}
126 }
127