lat_pipe.c

来自「pebble」· C语言 代码 · 共 194 行

C
194
字号
/* 
 * Copyright 1999, 2000, 2001, 2002 Lucent Technologies Inc.
 * All Rights Reserved.
 * Information Sciences Research Center, Bell Labs.
 *
 * LUCENT TECHNOLOGIES DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE 
 * OR THE SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The
 * software is provided "as is" without expressed or implied warranty 
 * of any kind.
 *
 * These notices must be retained in any copies of any part of this
 * software.
 *
 */

#include "pebble.h"
#include "unistd.h"
#include "types.h"
#include "time.h"
#include "synch.h"
#include "perfcount.h"

#define	N	10000
#define	BUFSIZE	1024	/* was 1024 */
#define	NDOMAIN	8	/* was 8 */

static Barrier *b;
static int fd[NDOMAIN];

void
tester(int i)
{
	int j, len;
	char buf[BUFSIZE];

	printf("tester %d of %d active: asid=%d\n", i, NDOMAIN, get_asid());
	printf("tester %d: fd[%d]=%d fd[%d]=%d\n",
		i, i, fd[i], (i+1)%NDOMAIN, fd[(i+1)%NDOMAIN]);

	for (len = i + 1; len <= BUFSIZE; len += NDOMAIN) {
#if	0
		printf("tester %d before read fd %d len %d\n", i, fd[i], len);
#endif
		if (read(fd[i], buf, BUFSIZE) != len) {
			printf("tester %d: read did not return %d\n", i, len);
			task_exit(1);
		}
#if	0
		printf("tester %d read returned %d\n", i, len);
#endif

		for (j = 0; j < len; j++)
			if (buf[j] != (char)j) {
				printf("tester %d: message %d: element %d is %d\n",
					i, len, j, buf[j]);
				task_exit(1);
			}

		if (len < BUFSIZE) {
			buf[len] = (char)len;
#if	0
			printf("tester %d before write fd %d len %d\n", i,
				fd[(i+1)%NDOMAIN], len+1);
#endif
			if (write(fd[(i+1)%NDOMAIN], buf, len+1) != len+1) {
				printf("tester %d: write did not return %d\n", i, len+1);
				task_exit(1);
			}
		}
	} 

	printf("tester %d ended\n", i);
}

void
worker(int i, int size)
{
	int ndomains, nctx, next_i, perf_ix;
	int j;
	uvlong start, elapsed;
	uvlong start_usec, elapsed_usec;
	char buf[BUFSIZE];
	uint perf_count;

	printf("worker %d of %d: asid=%d\n", i, NDOMAIN, get_asid());
	
	for (ndomains = 1; ndomains <= NDOMAIN; ndomains++) {
		for (perf_ix = 0; perf_vec[perf_ix].name != NULL; perf_ix++) {
			nctx = ndomains * N;
			next_i = (i+1)%ndomains;
			if (barrier_wait(b, i, NDOMAIN) < 0)
				panic("barrier_wait:");

			if (i >= ndomains)
				continue;

			/* only processor #0 sets the control register and */
			/* initializes the counter */
			if (i == 0)
				set_perf_ctrl(perf_vec[perf_ix].ctrl);

			start = hrtime();
			start_usec = uptime();
			for (j = 0; j < N; j++) {
				if (read(fd[i], buf, BUFSIZE) != size)
					panic("read:");
				if (write(fd[next_i], buf, size) != size)
					panic("write:");
			}

			perf_count = get_perf_count();
			elapsed = 2*(hrtime() - start);
			elapsed_usec = uptime() - start_usec;

			if (i > 0)
				continue;

			printf("===============\n");
			printf("%d iterations of %d domains with %d byte message (%d context switches):\n",
				N, ndomains, size, nctx);
			printf("elapsed time %d cycles; each context switch %d cycles\n",
				(int)elapsed, (int)((elapsed + nctx/2)/nctx));
			printf("elapsed time %d usec.; each context switch %d usec.\n",
				(int)elapsed_usec, (int)((elapsed_usec + nctx/2)/nctx));
			printf("%s: %d\n", perf_vec[perf_ix].name, perf_count);
		}
	}
}


int
main(void)
{
	int i, code;
	char buf[BUFSIZE];

	printf("lat_pipe starting\n");

	for (i = 0; i < NDOMAIN; i++) {
		if ((fd[i] = pipe_create()) < 0)
			panic("pipe_create:");
	}

	b = (Barrier *)shm_create(sizeof(Barrier));
	if (b == (Barrier *)-1)
		panic("shm_create");

	if (barrier_init(b) < 0)
		panic("barrier_init:");

	for (i = 1; i < NDOMAIN; i++) {
		code = domain_fork(NULL);
		if (code < 0)
			panic("domain_fork:");
		if (code == 0) {
			/* child domain */
			tester(i);
			worker(i, 1);
			if (barrier_wait(b, i, NDOMAIN) < 0)
				panic("barrier_wait:");
			worker(i, BUFSIZE);
			if (barrier_wait(b, i, NDOMAIN) < 0)
				panic("barrier_wait:");
			/* never reached */
			task_exit(0);
		}
	}

	/* parent domain */
	buf[0] = 0;
	printf("parent before write on fd %d 1 byte\n", fd[0]);
	if (write(fd[0], buf, 1) != 1)
		panic("write:");
	tester(0);

	printf("parent before write on fd %d 1 byte\n", fd[0]);
	if (write(fd[0], buf, 1) != 1)
		panic("write:");
	worker(0, 1);
	if (barrier_wait(b, 0, NDOMAIN) <0)
		panic("barrier_wait:");

	/* fd[0] contains the last message of the previous test */
	if (read(fd[0], buf, BUFSIZE) != 1)
		panic("read:");
	if (write(fd[0], buf, BUFSIZE) != BUFSIZE)
		panic("write:");
	worker(0, BUFSIZE);

	printf("LAT_PIPE ENDED\n");
	task_exit(0);
	return(1);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?