lat_interpose.c

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

C
167
字号
/* 
 * 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.
 *
 */

/*
 * Test system call interposition
 */

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

#define	N	10000

static int sem_id1, sem_id2;
static int child_asid;
static int count[NPORTALS];

void
dump_counters(void)
{
	int i;

	for (i = 0; i < NPORTALS; i++)
		if (count[i] > 0)
			printf("portal %d called %d times\n", i, count[i]);
}


int
intercept(int id, int p1, int p2, int p3, int p4, int p5)
{
	count[id]++;
	if (id == SYS_EXIT) {
		dump_counters();
		printf("child domain of lat_interpose ended\n");
	}
	return call_portal(id, p1, p2, p3, p4, p5);
}


int
notify(int asid, int id, char *template)
{
	char s[NAMELEN];

	printf("portal table changed: asid=%d id=%d template=%s\n",
		asid, id, template);

	/* create a new portal from the child to the parent with a modified */
	/* template */
	sprintf(s, "sm#%s", template+3);
	portal_create_child(child_asid, id, s, 0, intercept);

	return 0;
}


void
measure(void)
{
	int code;
	int i, perf_ix;
	uvlong start, elapsed;
	uint perf_count;

	/* create semaphores with initial value 0 */
	if ((sem_id1 = sem_create(0)) < 0)
		panic("sem_create:");
	if ((sem_id2 = sem_create(0)) < 0)
		panic("sem_create:");

	/* create a new thread in the same domain */
	if ((code = fork()) < 0)
		panic("fork:");

	if (code == 0) {
		/* child thread */

		/* wake up parent */
		if (sem_post(sem_id1) < 0)
			panic("sem_post:");

		for (i = 0;; i++) {
			if (sem_wait(sem_id2) < 0)
				panic("sem_wait:");
			if (sem_post(sem_id1) < 0)
				panic("sem_post:");
		}

		/* never reached */
		task_exit(1);
	}

	/* parent waits for the child to wake up */
	if (sem_wait(sem_id1) < 0)
		panic("sem_wait:");

	for (perf_ix = 0; perf_vec[perf_ix].name != NULL; perf_ix++) {
		/* time semphore ping-pong with child */
		set_perf_ctrl(perf_vec[perf_ix].ctrl);
		start = hrtime();

		for (i = 0; i < N; i++) {
			if (sem_post(sem_id2) < 0)
				panic("sem_post:");
			if (sem_wait(sem_id1) < 0)
				panic("sem_wait:");
		}

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

		printf("============\n");
		printf("elapsed time %d cycles\n", (int)elapsed);
		printf("each iteration took %d cycles\n", (int)(elapsed/N));
		printf("%s: %d\n", perf_vec[perf_ix].name, perf_count);
	}
}

int
main(void)
{
	printf("lat_interpose benchmark starting\n");

	printf("two threads in the same domain without interposition:\n");
	measure();

	if (portal_notify(notify) < 0)
		panic("portal_notify:");

	/* from this place and on, the parent will be notified if a new portal */
	/* is generated in its portals table for any reason. */

	if ((child_asid = domain_fork(intercept)) < 0)
		panic("domain_fork:");

	if (child_asid == 0) {
		/* child domain */
		measure();
		task_exit(0);
	}

	/* parent waits forever */
	while(1)
		sem_wait(sem_id1);

	printf("lat_interpose ended\n");

	task_exit(0);
	return(1);
}

⌨️ 快捷键说明

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