www.pudn.com > pebble.zip > app4.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 "unistd.h" 
#include "pebble.h" 
#include "synch.h" 
#include "perfcount.h" 
 
#define	N	10 
#define	NTHREAD	4 
 
Barrier *b; 
 
void 
do_hrsleep(int tid, Time elapsed[N], Time delay[N]) 
{ 
	int i, j; 
	Time start; 
 
	for (i = 0; i < N; i++) { 
		j =  (i + tid + N) % N; 
		delay[i] = 2000 + (2000 << j); 
		start = hrtime(); 
		if (hrsleep(start + delay[i]) < 0) 
			panic("hrsleep:"); 
		elapsed[i] = 2 * (hrtime() - start - delay[i]); 
	} 
} 
 
void 
test_hrsleep(int tid) 
{ 
	int i, perf_ix; 
	vlong elapsed[N], delay[N]; 
	uint perf_count; 
 
	/* all copies are running here with private stacks */ 
 
	for (perf_ix = 0; perf_vec[perf_ix].name != NULL; perf_ix++) { 
		printf("===============\n"); 
		printf("thread %d testing hrsleep\n", tid); 
 
		/* wait until all have finished printing */ 
		if (barrier_wait(b, tid, NTHREAD) < 0) 
			panic("barrier_wait:"); 
 
		/* only thread #0 sets the control register and */ 
		/* initializes the counter */ 
		if (tid == 0) 
			set_perf_ctrl(perf_vec[perf_ix].ctrl); 
 
 
		do_hrsleep(tid, elapsed, delay); 
 
		/* wait until all have completed the measurements */ 
		if (barrier_wait(b, tid, NTHREAD) < 0) 
			panic("barrier_wait:"); 
		perf_count = get_perf_count(); 
 
		printf("thread %d hrsleep accuracy:\n", tid); 
		/* first delay is longer due to internal initializations */ 
		for (i = 0; i < N; i++) 
			printf("hrsleep(%d): wakeup delay %d cycles\n", 
				(int)delay[i], (int)elapsed[i]); 
 
		if (tid == 0) 
			printf("%s: %d\n", perf_vec[perf_ix].name, perf_count); 
 
		/* wait until all have printed their results */ 
		if (barrier_wait(b, tid, NTHREAD) < 0) 
			panic("barrier_wait:"); 
	} 
 
	printf("task %d ended. bye!\n", tid); 
	printf("TEST DONE\n"); 
	task_exit(0); 
} 
 
 
int 
wait_a_sec(void) 
{ 
	int t, last_t; 
 
	last_t = time(); 
	if (last_t < 0) 
		return -1; 
	while ((t = time()) == last_t) 
		yield(); 
 
	if (t < 0) 
		return -1; 
	else 
		return 0; 
} 
 
int 
main(int arg, char *argv[]) 
{ 
	int i; 
	Time start_usec, end_usec, start_hrtime, end_hrtime; 
	Time elapsed_usec[N], elapsed_hrtime[N], delay[N]; 
	int code; 
 
	write(2, "app4", 4); 
	 
	printf("\ntesting RTC interrupts\n"); 
	printf("before wait_a_sec: current time=%d usec.\n", (int)uptime()); 
	if (wait_a_sec() < 0) 
		panic("wait_a_sec:"); 
	printf("after wait_a_sec: current time=%d usec.\n", (int)uptime()); 
 
	printf("please wait %d seconds...\n", N); 
	write(2, "10s.", 4); 
	end_usec = uptime(); 
	end_hrtime = hrtime(); 
	for (i = 0; i < N; i++) { 
		start_usec = end_usec; 
		start_hrtime = end_hrtime; 
		if (wait_a_sec() < 0) 
			panic("wait_a_sec:"); 
		end_usec = uptime(); 
		end_hrtime = hrtime(); 
		elapsed_usec[i] = end_usec - start_usec; 
		elapsed_hrtime[i] = end_hrtime - start_hrtime; 
	} 
 
	write(2, "thx.", 4); 
	printf("elapsed time for wait_a_sec:\n"); 
	for (i = 1; i < N; i++) { 
		printf("%d: %d usec\n", i, (int)elapsed_usec[i]); 
		printf("%d: %d ticks\n", i, (int)elapsed_hrtime[i]); 
	} 
 
	printf("usleep to allow idle task to run for first time\n"); 
	usleep(1000); 
 
	/* test usleep */ 
	start_usec = uptime(); 
	start_hrtime = hrtime(); 
	/* sleep for 1 second */ 
	usleep(SEC2USEC); 
	end_usec = uptime(); 
	end_hrtime = hrtime(); 
	printf("usleep(1 second): elapsed usec=%d error=%d elapsed ticks=%d error=%d\n", 
		(int)(end_usec - start_usec), (int)(end_usec - start_usec) - 1000000, 
		(int)(end_hrtime - start_hrtime), 
		(int)(end_hrtime - start_hrtime) - sec2ticks()); 
 
	printf("testing serial hrsleep (one process active):\n"); 
	do_hrsleep(0, elapsed_hrtime, delay); 
	for (i = 0; i < N; i++) 
		printf("hrsleep(%d): wakeup delay %d cycles\n", 
			(int)delay[i], (int)elapsed_hrtime[i]); 
 
	printf("starting concurrent hrsleep measurements\n"); 
	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 < NTHREAD; i++) { 
		if ((code = fork()) < 0) 
			panic("fork:"); 
		if (code == 0) 
			test_hrsleep(i); 
	} 
	/* parent testing hrsleep */ 
	test_hrsleep(0); 
 
	task_exit(0); 
	return(1); 
}