⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lat_sem2.c

📁 pebble
💻 C
字号:
/* 
 * 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	NDOMAIN	8	

static int s[NDOMAIN];		/* s must be static to be shared correctly with child */
static int dummy_s;	/* dummy semaphores used for timing sem_post */
				/* only */
static Barrier *bp;

void
worker(int i)
{
	int ndomains, nctx, next_i;
	int perf_ix, j;
	uvlong start, elapsed;
	uvlong start_usec, elapsed_usec;
	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;
			usleep(SEC2USEC);	/* check concurrent usleep() */
			if (barrier_wait(bp, i, NDOMAIN) < 0)
				panic("barrier_wait:");

			if (i >= ndomains)
				continue;

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

			for (j = 0; j < N; j++)
				yield();

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

			if (i > 0)
				continue;

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

	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(bp, 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 (sem_wait(s[i]) < 0)
						panic("sem_wait:");
				if (sem_post(s[next_i]) < 0)
					panic("sem_post:");
			}

			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 in a ring of %d semaphores (%d context switches):\n",
				N, ndomains, ndomains, 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);
		}
	}

	/* only the first domain terminates; the others wait here */
	if (i > 0)
		barrier_wait(bp, i, NDOMAIN);
}

int
main(void)
{
	int i, j, code;
	Time start, elapsed;


	printf("lat_sem2 benchmark starting\n");

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

	if ((dummy_s = sem_create(0)) < 0)
		panic("sem_create:");

	if (sem_post(s[0]) < 0)
		panic("sem_post:");

	start = hrtime();

	for (j = 0; j < N; j++)
		sem_post(dummy_s);

	elapsed = 2*(hrtime() - start);
			
	printf("===============\n");
	printf("%d semaphore posts of %d domains (no context switches):\n",
		N, 1);
	printf("elapsed time %d cycles; each sem_post %d cycles\n",
		(int)elapsed, (int)((elapsed +N/2)/N));

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

	if (barrier_init(bp) < 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 */
			worker(i);
			/* never reached */
			task_exit(0);
		}
	}

	/* parent domain */
	worker(0);


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

⌨️ 快捷键说明

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