app1.c

来自「pebble」· C语言 代码 · 共 2,046 行 · 第 1/4 页

C
2,046
字号
		task_exit(1);
	}
	printf("correct shared memory contents from both domains\n");

	printf("testing mutual exclusion locks in shared region\n");
	mutex_init((Lock *)addr, MUTEX_ERRORCHECK);
	if (mutex_trylock((Lock *)addr) < 0) {
		printf("mutex_trylock failed; expected to succeed\n");
		task_exit(1);
	}
	if (mutex_trylock((Lock *)addr) >= 0) {
		printf("mutex_trylock succeeded; expected to fail\n");
		task_exit(1);
	}
	if (call_portal(try_id, addr) >= 0) {
		printf("fs trylock succeeded; expected to fail\n");
		task_exit(1);
	}
	mutex_unlock((Lock *)addr);
	if (call_portal(try_id, addr) < 0) {
		printf("fs trylock failed; expected to succceed\n");
		task_exit(1);
	}
	if (call_portal(try_id, addr) >= 0) {
		printf("fs trylock succeeded; expected to fail\n");
		task_exit(1);
	}
	if (mutex_trylock((Lock *)addr) >= 0) {
		printf("mutex_trylock succeeded; expected to fail\n");
		task_exit(1);
	}

	printf("check access to shared memory region in a child domain\n");
	if ((s1 = sem_create(0)) < 0)
		panic("sem_create:");
	if ((s2 = sem_create(0)) < 0)
		panic("sem_create:");
	set_mem(addr, sz);

	if ((code = domain_fork(NULL)) < 0)
		panic("domain_fork:");
	if (code == 0) {
		/* child */
		check_mem(addr, (int)addr, sz);
		printf("child domain accessed shared region successfully\n");
		/* wakeup parent */
		sem_post(s1);
		/* sleep forever */
		sem_wait(s2);
	}
	sem_wait(s1);

	printf("shared memory test ended successfully\n\n");
}


void
test_sem(void)
{
	int s;
	int s1, s2, i, j;
	Time start, elapsed;

	printf("testing semaphores\n");

	if ((s = sem_open("fs_sem")) < 0)
		panic("sem_open(fs_sem):");
	sem_wait(s);

	s1 = sem_create(0);
	s2 = sem_create(0);
	if (s1 < 0 || s2 < 0)
		panic("sem_create:");

	printf("created semaphores: s1=%d s2=%d\n", s1, s2);
	printf("sem_post(%d) returns %d\n", s1, sem_post(s1));
	printf("sem_wait(%d) returns %d\n", s1, sem_wait(s1));

	start = hrtime();
	sem_twait(s1, start + sec2ticks());
	elapsed = hrtime() - start;
	printf("sem_twait() for 1 second waited %u clock ticks; expected %u clock ticks\n",
		(int)elapsed, (int)sec2ticks());
	if (elapsed > (5*sec2ticks())/4)
		panic("sem_twait() waited significantly more than one second");

	start = hrtime();
	sem_post(s1);
	sem_twait(s1, start + sec2ticks());
	elapsed = hrtime() - start;
	printf("sem_twait() on an available semaphore waited %u clock ticks\n",
		(int)elapsed);
	if (elapsed > sec2ticks()/1000)
		panic("sem_twait() on an available semphore took too long");

	start = hrtime();
	for (i = 0; i < N; i++) {
		sem_post(s2);
		sem_wait(s2);
	}
	elapsed = 2*(hrtime() - start) - loop_overhead;
	printf("elapsed cycles of %d sem_wait/sem_post pairs is %d\n", i,
		(int)elapsed);
	printf("each sem_wait/sem_post pair: %d cycles\n\n",
		(int)(elapsed+N/2)/N);

	printf("before fork: parent status=%08lx stack at %p\n",
		get_psw(), &j);
	if (fork() == 0) {
		printf("after fork: child status=%08lx stack at %p\n",
			get_psw(), &j);
		printf("the child asid=%d calling rpc1\n", get_asid());
		printf("portal(%d,3)=%d\n", rpc1, call_portal(rpc1, 3));
		do {
			printf("shared_flag=%d\n", shared_flag);
			yield();
		} while(shared_flag == 0);
		printf("child: shared_flag=%d\n", shared_flag);

		/* semaphore ping-pong with parent */
		printf("child before semaphore ping-pong\n");
		for (i = 0; i < N; i++) {
			sem_post(s1);
			sem_wait(s2);
		}

		/* child waits forever */
		sem_wait(s2);
	}

	printf("after fork: parent status=%08lx stack at %p\n",
		get_psw(), &j);
	yield();
	shared_flag = 1;
	yield(); 

	printf("parent before semaphore ping-pong\n");
	start = hrtime();
	for (i = 0; i < N; i++) {
		sem_wait(s1);
		sem_post(s2);
	}
	elapsed = 2*(hrtime() - start) - loop_overhead;
	printf("elapsed cycles of %d sem_wait/sem_post with child is %d\n", i,
		(int)elapsed);
	printf("each sem_wait/sem_post with child: %d cycles\n",
		(int)(elapsed+N/2)/N);

	printf("semaphore test ended successfully\n\n");
}


void
measure_timeout(char *test_name, int keep_event[])
{
	Time now, max_delay, start_idle, elapsed_idle, expected_idle;
	Time first_event, latest_event;
	int i;
	Time usec2ticks = sec2ticks() / SEC2USEC;

	printf("starting %s test\n", test_name);

	/* compute the largest expected delay */
	latest_event = when[0];
	first_event = when[0];
	for (i = 1; i < M; i++) {
		if (when[i] < first_event)
			first_event = when[i];
		if (when[i] > latest_event)
			latest_event = when[i];
	}

	/* generate M timeout events */
	start_idle = idle_time();
	now = hrtime();

	if (first_event < now)
		panic("measure_timeout: first event=%u %u now=%u %u\n",
			(int)(first_event >> 32), (int)first_event,
			(int)(now >> 32), (int)now);
	usec2ticks = sec2ticks() / SEC2USEC;

	/* generate the M timeout events */
	for (i = 0; i < M; i++) {
		timeout_flag[i] = 0;
		if (timeout(tout, (void*)i, when[i]) < 0) {
			printf("timeout(%d) failed\n", i);
			task_exit(1);
		}
		/* allow timeout thread to run after generating each timeout event */
		usleep((first_event - now) / ((M+1)*usec2ticks));
	}

	/* cancel the requested events */
	for (i = 0; i < M; i++) {
		if (keep_event[i])
			continue;
		if (untimeout(tout, (void*)i, when[i]) < 0) {
			printf("untimeout(%d) failed\n", i);
			task_exit(1);
		}
	}

	/* wait until all timeout events have occured */
	hrsleep(latest_event + sec2ticks());
	expected_idle = (latest_event + sec2ticks()) - now;

	/* verify that the timeouts have occured on time */
	elapsed_idle = idle_time() - start_idle;
	max_delay = 0;
	for (i = 0; i < M; i++) {
		printf("timeout event %d @ %u %u \n",
			i, (int)(when[i] >> 32), (int)when[i]);

		if (timeout_flag[i])
			printf("called with delay of %u ticks\n",
				(int)timeout_delay[i]);
		else
			printf("not called\n");

		if (timeout_flag[i] != keep_event[i]) {
			printf("timeout_flag[%d] is %d. should be %d\n",
				i, timeout_flag[i], keep_event[i]);
			task_exit(1);
		}
		if (timeout_delay[i] > max_delay)
			max_delay = timeout_delay[i];
	}

	printf("idle time during %s test: %u %u ticks; expected %u %u ticks\n",
		test_name,
		(int)(elapsed_idle >> 32), (int)elapsed_idle,
		(int)(expected_idle >> 32), (int)expected_idle);

	printf("maximal timeout delay during %s test: %u %u ticks\n",
		test_name, (int)(max_delay >> 32), (int)max_delay);
	if (max_delay > sec2ticks()/1000)
		panic("*** %s test failed ***\n\n", test_name);
	else
		printf("%s test passed successfully\n\n", test_name);

}


void
test_timeout(void)
{
	Time now;
	int i;
	Time s2ticks = sec2ticks();
	int keep_event[M];

	/* increasing timeout test */
	now = hrtime();
	for (i = 0; i < M; i++) {
		when[i] = now + s2ticks + (s2ticks * i) / M;
		keep_event[i] = 1;
	}

	measure_timeout("increasing timeout", keep_event);

	/* decreasing timeout test */
	now = hrtime();
	for (i = 0; i < M; i++) {
		when[i] = now + 2*s2ticks - (s2ticks * i) / M;
		keep_event[i] = 1;
	}

	measure_timeout("decreasing timeout", keep_event);

	/* generate M random timeout events, waiting between a second and two */
	now = hrtime();
	random();	/* get the first random number */

	/* none of the timeout events has occurred yet, since they all */
	/* start at least one second after "now" */
	/* cancel every second timeout event */
	for (i = 0; i < M; i++) {
		when[i] = now + s2ticks + ((Time)random() % s2ticks);
		keep_event[i] = i & 01;
	}

	measure_timeout("random timeout with event deletions", keep_event);
}


void
printenv(const char *name)
{
	char val[NAMELEN];

	if (get_env(name, val) < 0)
		printf("environment variable %s not defined\n", name);
	else
		printf("environment variable %s = %s\n", name, val);
}

int
main(int arg, char *argv[])
{
	int i, code;
	int fd;
	int last_time;
	volatile int *q, *u;
	Time start, elapsed;
	Time start_usec, elapsed_usec;
	char msg[NAMELEN];

	printf("hello, world! arg=%d\n", arg);
	printf("hr_count=%d psw=%08lx asid=%d\n",
		(int)hrtime(), get_psw(), get_asid());
	if ((code = get_caller_asid(0)) != get_asid())
		panic("get_caller_asid(0) returned %d; expected %d :",
			code, get_asid());
	printf("initial TLB miss count=%d general exceptions count=%d\n",
		get_tlb_excpt_count(), get_gen_excpt_count());

	test_mod(1622650073);
	test_idle();

	printenv("hostname");
	printenv("netaddr");
	printenv("netmask");

	printf("initial error msg=%s\n", msg);
	printf("fd_open(\"?\")=%d\n", fd_open("?"));
	get_error(msg);
	printf("error msg=%s\n", msg);

	printf("calling portal(0)\n");
	code = call_portal(0);
	if (code >= 0)
		panic("call_portal(0) did not fail!");
	get_error(msg);
	printf("code=%d error msg=%s\n", code, msg);

	printf("calling portal(-1)\n");
	code = call_portal(-1);
	if (code >= 0)
		panic("call_portal(-1) did not fail!");
	get_error(msg);
	printf("code=%d error msg=%s\n", code, msg);

	printf("calling portal(too large)\n");
	code = call_portal(NPORTALS);
	if (code >= 0)
		panic("call_portal(NPORTALS) did not fail!");
	get_error(msg);
	printf("code=%d error msg=%s\n", code, msg);

	/* The following yield allows the fs thread to run, so that */
	/* if the debug messages are enabled, they do not appear AFTER */
	/* the input prompt. Before this fix, you may miss the input prompt */
	/* due to the lengthy debug messages that appear after it. */
	yield();
	printf("reading from console, type up to 64 chars\n");
	fgets(msg, sizeof(msg), NULL);
	printf("read %d chars, \"%s\" from console\n", strlen(msg), msg);

	fd = 0;
	printf("writing on LED display\n");
	if ((fd = fd_open("led")) < 0)
		panic("fd_open(led):");
	if (write(fd, "d00d", 4) < 0)
		panic("write:");

	printf("task %d asid=%d defines rpc1 & rpc2\n", arg, get_asid());

	if ((rpc1 = portal_create(-1, "smtiii", 0, &f, 0)) < 0)
		panic("portal_create(rpc1):");
	printf("task asid=%d portal_create(-1,\"smtiii\", 0, %p, 0) returns %d\n",
		get_asid(), &f, rpc1);

	if ((rpc2 = portal_create(-1, "smtiii", 0, &g, 0)) < 0)
		panic("portal_create(rpc2):");
	printf("task asid=%d portal_create(-1,\"smtiii\", 0, %p, 0) returns %d\n",
		get_asid(), &g, rpc2);

	start = hrtime();
	for (i = 0; i < N; i++)
		yield();
	elapsed = 2*(hrtime() - start);
	printf("elapsed cycles of %d yields is %d\n", i, (int)elapsed);
	printf("each yield: %d cycles\n", (int)(elapsed+N/2)/N);

	start = hrtime();
	for (i = 0; i < N; i++)
		;
	loop_overhead = 2*(hrtime() - start);
	printf("empty loop overhead %d iterations=%d cycles. should be %d\n",
		i, (int)loop_overhead, i*3);

	set_error(NULL);
	printf("phys(NULL)=%p\n", virt2phys(NULL));
	get_error(msg);
	printf("expected error message=%s\n", msg);

	set_error(NULL);
	printf("&shared_flag=%p phys=%p\n",
		&shared_flag, virt2phys(&shared_flag));
	get_error(msg);
	if (strlen(msg) != 0) {
		printf("virt2phys(data address) failed. message=%s\n", msg);
		task_exit(1);
	}

	set_error(NULL);
	printf("&f=%p phys=%p\n",
		&f, virt2phys(&f));
	get_error(msg);
	printf("expected error message=%s\n\n", msg);

	printf("testing uncached access\n");
	q = &shared_flag;
	if ((u = (int *)uncached_window((void *)q)) == (int *)-1)
		panic("uncached_window:");
	printf("virt addr=%p phys addr=%p uncached addr=%p\n",
		q, virt2phys((void *)q), u);
	if (uncached_window((void *)q) != (void *)-1)
		panic("second uncached_window did not fail");
	get_error(msg);
	printf("expected error from uncached_window: %s\n", msg);
	*u = 0x12345678;
	*q = 0xdeadbeef;
	printf("before cache flush: virt mem=%08x uncached mem=%08x\n", *q, *u);
	clean_cache((void *)q, sizeof(int));
	if (*q != *u) {
		printf("after cache flush: virt mem=%08x uncached mem=%08x\n",
			*q, *u);
		printf("*** uncached memory not equal to virtual memory ***\n");
		task_exit(1);
	}
	printf("after cache flush: virt mem=%08x uncached mem=%08x\n\n",
		*q, *u);

	test_csd();

	test_log();

	test_malloc();

	test_portal_alloc();

	test_portal_window();

	test_page_transfer();
		
	last_time = time();
	printf("current time() is %d\n", last_time);
	while (time() < last_time + 10)
		yield();
	printf("time() after 10 seconds is %d\n\n", time());

	test_mutex();

	test_signal();

	test_shm();

	test_sem();

	printf("the parent asid=%d before calling rpc1\n", get_asid());
	printf("portal(%d,3)=%d\n",
		rpc1, call_portal(rpc1, 3));
	printf("task %d asid=%d before calling rpc2\n", arg, get_asid());
	printf("portal(%d,4)=%d\n",
		rpc2, call_portal(rpc2, 4));

	start = hrtime();
	for (i = 0; i < N; i++)
		hrtime();
	elapsed = 2*(hrtime() - start) - loop_overhead;

	printf("elapsed time of %d hrtime=%d cycles\n", i, (int)elapsed);
	printf("each hrtime: %d cycles\n", (int)(elapsed+N/2)/N);

	printf("hrcount per second=%d\n", sec2ticks());
	start = hrtime();
	for (i = 0; i < N; i++)
		uptime();
	elapsed = 2*(hrtime() - start) - loop_overhead;
	printf("elapsed time of %d uptime()=%d cycles\n", i, (int)elapsed);
        printf("each uptime: %d cycles\n", (int)(elapsed+N/2)/N);

	start_usec = uptime();
	for (i = 0; i < N; i++)
		uptime();
	elapsed_usec = uptime() - start_usec;
	printf("elapsed time of %d uptime()=%d usec.\n", i, (int)elapsed_usec);
	printf("each uptime: %d usec.\n", (int)((elapsed_usec+N/2)/N));

	for (i = 0; i < N; i++)
		if (call_portal(rpc2, i) != -i)
			printf("error in rpc2(%d)\n", i);

	start = hrtime();
	for (i = 0; i < N; i++)
		call_portal(rpc2, i);
	elapsed = 2*(hrtime() - start) - loop_overhead;
	printf("elapsed time of %d rpc2=%d cycles\n", i, (int)elapsed);
	printf("each RPC: %d cycles\n\n", (int)(elapsed+N/2)/N);

	test_timeout();

	printf("APP1 ENDING\n");
	printf("parent domain asid=%d calling task exit\n", get_asid());
	task_exit(0);
	return(1);
}

⌨️ 快捷键说明

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