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);
}