FreeBSD/tools/tools/netrate/juggle/juggle.c
/*
 * Juggle messages between two file descriptors in two processes, so measure
 * the cost of IPC and the cost of a process context switch.
 *
 * Since we can't use a mutex between the processes, we simply do an extra
 * write on the child to let the parent know that it's ready to start.
 */
Juggle messages between two file descriptors in two processes, so measure
the cost of IPC and the cost of a process context switch.

Since we can't use a mutex between the processes, we simply do an extra
write on the child to let the parent know that it's ready to start.
Juggle messages between two file descriptors in two processes so measure the cost of IPC and the cost of a process context switch . Since we can ' t use a mutex between the processes we simply do an extra write on the child to let the parent know that it ' s ready to start .
static struct timespec
process_juggle(int fd1, int fd2, int pipeline)
{
	struct timespec tstart, tfinish;
	pid_t pid, ppid, wpid;
	int error, i, j;
	ppid = getpid();
	pid = fork();
	if (pid < 0)
		err(-1, "process_juggle: fork");
	if (pid == 0) {
		if (message_send(fd2) < 0) {
			error = errno;
			kill(ppid, SIGTERM);
			errno = error;
			err(-1, "process_juggle: child: message_send");
		}
		for (i = 0; i < NUMCYCLES; i++) {
			for (j = 0; j < pipeline; j++) {
				if (message_send(fd2) < 0)
					err(-1, "message_send fd2");
				if (message_recv(fd2) < 0)
					err(-1, "message_recv fd2");
			}
		}
		exit(0);
	} else {
		if (message_recv(fd1) < 0) {
			error = errno;
			kill(pid, SIGTERM);
			errno = error;
			err(-1, "process_juggle: parent: message_recv");
		}
		if (clock_gettime(CLOCK_REALTIME, &tstart) < 0)
			err(-1, "process_juggle: clock_gettime");
		for (i = 0; i < NUMCYCLES; i++) {
			for (j = 0; j < pipeline; j++) {
				if (message_send(fd1) < 0) {
					error = errno;
					kill(pid, SIGTERM);
					errno = error;
					err(-1, "message_send fd1");
				}
			}
			for (j = 0; j < pipeline; j++) {
				if (message_recv(fd1) < 0) {
					error = errno;
					kill(pid, SIGTERM);
					errno = error;
					err(-1, "message_recv fd1");
				}
			}
		}
		if (clock_gettime(CLOCK_REALTIME, &tfinish) < 0)
			err(-1, "process_juggle: clock_gettime");
	}
	wpid = waitpid(pid, NULL, 0);
	if (wpid < 0)
		err(-1, "process_juggle: waitpid");
	if (wpid != pid)
		errx(-1, "process_juggle: waitpid: pid != wpid");
	timespecsub(&tfinish, &tstart);
	return (tfinish);
}
static struct timespec process_juggle ( int fd1 , int fd2 , int pipeline ) { struct timespec tstart , tfinish ; pid_t pid , ppid , wpid ; int error , i , j ; ppid = getpid ( ) ; pid = fork ( ) ; if ( pid < 0 ) err ( -1 , " " ) ; if ( pid == 0 ) { if ( message_send ( fd2 ) < 0 ) { error = errno ; kill ( ppid , SIGTERM ) ; errno = error ; err ( -1 , " " ) ; } for ( i = 0 ; i < NUMCYCLES ; i ++ ) { for ( j = 0 ; j < pipeline ; j ++ ) { if ( message_send ( fd2 ) < 0 ) err ( -1 , " " ) ; if ( message_recv ( fd2 ) < 0 ) err ( -1 , " " ) ; } } exit ( 0 ) ; } else { if ( message_recv ( fd1 ) < 0 ) { error = errno ; kill ( pid , SIGTERM ) ; errno = error ; err ( -1 , " " ) ; } if ( clock_gettime ( CLOCK_REALTIME , & tstart ) < 0 ) err ( -1 , " " ) ; for ( i = 0 ; i < NUMCYCLES ; i ++ ) { for ( j = 0 ; j < pipeline ; j ++ ) { if ( message_send ( fd1 ) < 0 ) { error = errno ; kill ( pid , SIGTERM ) ; errno = error ; err ( -1 , " " ) ; } } for ( j = 0 ; j < pipeline ; j ++ ) { if ( message_recv ( fd1 ) < 0 ) { error = errno ; kill ( pid , SIGTERM ) ; errno = error ; err ( -1 , " " ) ; } } } if ( clock_gettime ( CLOCK_REALTIME , & tfinish ) < 0 ) err ( -1 , " " ) ; } wpid = waitpid ( pid , NULL , 0 ) ; if ( wpid < 0 ) err ( -1 , " " ) ; if ( wpid != pid ) errx ( -1 , " " ) ; timespecsub ( & tfinish , & tstart ) ; return ( tfinish ) ; }
Juggle messages between two file descriptors in two processes, so measure
 the cost of IPC and the cost of a process context switch.
Juggle messages between two file descriptors in two processes so measure the cost of IPC and the cost of a process context switch .