lat_sem.c

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

C
146
字号
/* 
 * 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 semaphores and mutual exclusion locks (mutex)
 *	using N threads in the same protection domains.
 *
 *	See lat_sem2.c for a similar test of N threads in separate
 * 	protection domains.
 */
#include "pebble.h"
#include "unistd.h"
#include "types.h"
#include "time.h"
#include "synch.h"

#define	N	10000
#define	NTHREAD	8

static int *s;
static Barrier b;
static Lock lock[N];

void
worker(int i, int n)
{
	int j;
	int nctx = n * N;
	uvlong start, elapsed;
	uvlong start_usec, elapsed_usec;

	printf("worker %d of %d: asid=%d\n", i, n, get_asid());
	
	if (barrier_wait(&b, i, n) < 0)
		panic("barrier_wait:");

	start = hrtime();
	start_usec = uptime();
	for (j = 0; j < N; j++) {
		if (sem_wait(s[i]) < 0)
			panic("sem_wait:");
		if (sem_post(s[(i+1)%n]) < 0)
			panic("sem_post:");
	}
	elapsed = 2*(hrtime() - start);
	elapsed_usec = uptime() - start_usec;


	if (i == 0) {
		printf("%d iterations of %d threads (%d context switches):\n",
			N, n, 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));
	}

	/* do not test mutex on a single thread, since we will deadlock! */
	if (n <= 1)
		return;

	printf("worker %d of %d: starting mutex\n", i, n);

	if (barrier_wait(&b, i, n) < 0)
		panic("barrier_wait:");

	start = hrtime();
	start_usec = uptime();
	for (j = 0; j < N; j++) {
		mutex_lock(&lock[i]);
		mutex_lock(&lock[(i+1)%n]);
		yield();
		mutex_unlock(&lock[i]);
		mutex_unlock(&lock[(i+1)%n]);
	}
	elapsed = 2*(hrtime() - start);
	elapsed_usec = uptime() - start_usec;


	if (i > 0)
		return;

	printf("%d iterations of %d threads (%d mutex):\n",
		N, n, 2*nctx);
	printf("elapsed time %d cycles; each pair of mutex %d cycles\n",
		(int)elapsed, (int)((elapsed + nctx/2)/nctx));
	printf("elapsed time %d usec.; each pair of mutex %d usec.\n",
		(int)elapsed_usec, (int)((elapsed_usec + nctx/2)/nctx));
}


int
main(void)
{
	int i, j, code;


	printf("lat_sem benchmark starting\n");

	if ((s = (int *)calloc(NTHREAD, sizeof(int))) == NULL)
		panic("malloc:");

	for (i = 0; i < NTHREAD; i++) {
		if ((s[i] = sem_create(0)) < 0)
			panic("sem_create:");
		mutex_init(&lock[i], 0);
	}

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

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

	worker(0, 1);	/* one thread */

	for (i = 1; i < NTHREAD; i++) {
		code = fork();
		if (code < 0)
			panic("fork:");
		if (code == 0) {
			for (j = i+1;; j++)
				worker(i, j);
		}

		worker(0, i+1);
	}


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

⌨️ 快捷键说明

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