[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ltp-list
Subject:    [LTP] Correct start latency for sched_latency
From:       Vernon Mauery <vernux () us ! ibm ! com>
Date:       2008-05-30 22:14:27
Message-ID: 200805301514.27914.vernux () us ! ibm ! com
[Download RAW message or body]

I spent some time looking at the sched_latency test trying to see why it
took so long to start the thread.  The java version of the test takes
a comparable amount of time to start the thread as it does for each period.
The rt-test version was taking an order of magnitude longer.  After digging
through the java documentation, I found that the RealtimeThread does not
actually start executing until the RealtimeThread.waitForNextPeriod()
fulfills the time specified in the PeriodicParameters parameter included in
its constructor.  So all the tests are scheduled to run about 1 second
after the threads are created.  This gives the system plenty of time to
create the thread (a non-realtime code path), set the scheduling parameters
and then sleep until the specified run time.  The start latency as measured
by the test goes something like this:

start_time = nanoTime() + 1000000000;
rt = new realtimeThread(sched_param, new \
	PeriodicParameters(start_time, ...), ..., run);

/* by the rtsj specification, this method will not run until start_time */
run() {
	now = nanoTime();
	start_latency = now - start_time;
	...
}

The rt-tests version went something like this:

start_time = rt_gettime();
create_fifo_thread(periodic_thread, (void*)0, PRIO);

periodic_thread() {
	now = rt_gettime();
	start_latency = now - start;
	...
}

As you can see, the start_latency is a very different measurement in these
two cases.  In the first, it is basically the initial starting latency as
measured by the remainder of the loops.  In the second, the execution path
of creating the pthread is also counted in the latency.  While this might
be an important number for us to keep low in our testing, this is not what
the java test is measuring.

This patch puts the rt-test version in line with the java version.  I also
think this is reasonable since the rt-wiki says that we should _NEVER_
create threads on the real-time stage.

Signed-off-by: Vernon Mauery <vernux@us.ibm.com>

diff --git a/testcases/realtime/func/sched_latency/sched_latency.c 
b/testcases/realtime/func/sched_latency/sched_latency.c
index 021ee94..5c65704 100644
--- a/testcases/realtime/func/sched_latency/sched_latency.c
+++ b/testcases/realtime/func/sched_latency/sched_latency.c
@@ -126,6 +126,9 @@ void *periodic_thread(void *arg)
 	int failures = 0;
 	nsec_t next = 0, now = 0, sched_delta = 0, delta = 0, prev = 0, iter_start;
 
+ 	/* wait for the specified start time */
+ 	rt_nanosleep_until(start);
+
 	now = rt_gettime();
 	start_delay = (now - start)/NS_PER_US;
 	iter_start = next = now;
@@ -279,7 +282,8 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
-	start = rt_gettime();
+	/* wait one quarter second to execute */
+	start = rt_gettime() + 250 * NS_PER_MS;
 	per_id = create_fifo_thread(periodic_thread, (void*)0, PRIO);
 
 	join_thread(per_id);
diff --git a/testcases/realtime/include/librttest.h 
b/testcases/realtime/include/librttest.h
index c298f34..dbc4ab0 100644
--- a/testcases/realtime/include/librttest.h
+++ b/testcases/realtime/include/librttest.h
@@ -312,6 +312,10 @@ void nsec_to_ts(nsec_t ns, struct timespec *ts);
  */
 int ts_to_nsec(struct timespec *ts, nsec_t *ns);
 
+/* rt_nanosleep: sleep until absolute time ns (in nanoseconds) using 
clock_nanosleep
+ */
+void rt_nanosleep_until(nsec_t ns);
+
 /* rt_nanosleep: sleep for ns nanoseconds using clock_nanosleep
  */
 void rt_nanosleep(nsec_t ns);
diff --git a/testcases/realtime/lib/librttest.c 
b/testcases/realtime/lib/librttest.c
index 703d6c8..20cb7a1 100644
--- a/testcases/realtime/lib/librttest.c
+++ b/testcases/realtime/lib/librttest.c
@@ -398,6 +398,18 @@ void nsec_to_ts(nsec_t ns, struct timespec *ts)
 	ts->tv_nsec = ns%NS_PER_SEC;
 }
 
+void rt_nanosleep_until(nsec_t ns) {
+	struct timespec ts_sleep, ts_rem;
+	int rc;
+	nsec_to_ts(ns, &ts_sleep);
+	rc = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts_sleep, &ts_rem);
+	/* FIXME: when should we display the remainder ? */
+	if (rc != 0) {
+		printf("WARNING: rt_nanosleep() returned early by %d s %d ns\n",
+			(int)ts_rem.tv_sec, (int)ts_rem.tv_nsec);
+	}
+}
+
 void rt_nanosleep(nsec_t ns) {
 	struct timespec ts_sleep, ts_rem;
 	int rc;

There.  I just inlined it using Message -> insert file.  However, I think that 
will still word wrap the file if it is too long.  So I am attaching the file 
as well.

--Vernon

> Signed-off-by: Vernon Mauery <vernux@us.ibm.com>
>
> --Vernon



["sched_latency_fix.patch" (text/plain)]

diff --git a/testcases/realtime/func/sched_latency/sched_latency.c \
b/testcases/realtime/func/sched_latency/sched_latency.c index 021ee94..5c65704 100644
--- a/testcases/realtime/func/sched_latency/sched_latency.c
+++ b/testcases/realtime/func/sched_latency/sched_latency.c
@@ -126,6 +126,9 @@ void *periodic_thread(void *arg)
 	int failures = 0;
 	nsec_t next = 0, now = 0, sched_delta = 0, delta = 0, prev = 0, iter_start;
 
+ 	/* wait for the specified start time */
+ 	rt_nanosleep_until(start);
+
 	now = rt_gettime();
 	start_delay = (now - start)/NS_PER_US;
 	iter_start = next = now;
@@ -279,7 +282,8 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
-	start = rt_gettime();
+	/* wait one quarter second to execute */
+	start = rt_gettime() + 250 * NS_PER_MS;
 	per_id = create_fifo_thread(periodic_thread, (void*)0, PRIO);
 
 	join_thread(per_id);
diff --git a/testcases/realtime/include/librttest.h \
b/testcases/realtime/include/librttest.h index c298f34..dbc4ab0 100644
--- a/testcases/realtime/include/librttest.h
+++ b/testcases/realtime/include/librttest.h
@@ -312,6 +312,10 @@ void nsec_to_ts(nsec_t ns, struct timespec *ts);
  */
 int ts_to_nsec(struct timespec *ts, nsec_t *ns);
 
+/* rt_nanosleep: sleep until absolute time ns (in nanoseconds) using clock_nanosleep
+ */
+void rt_nanosleep_until(nsec_t ns);
+
 /* rt_nanosleep: sleep for ns nanoseconds using clock_nanosleep
  */
 void rt_nanosleep(nsec_t ns);
diff --git a/testcases/realtime/lib/librttest.c b/testcases/realtime/lib/librttest.c
index 703d6c8..20cb7a1 100644
--- a/testcases/realtime/lib/librttest.c
+++ b/testcases/realtime/lib/librttest.c
@@ -398,6 +398,18 @@ void nsec_to_ts(nsec_t ns, struct timespec *ts)
 	ts->tv_nsec = ns%NS_PER_SEC;
 }
 
+void rt_nanosleep_until(nsec_t ns) {
+	struct timespec ts_sleep, ts_rem;
+	int rc;
+	nsec_to_ts(ns, &ts_sleep);
+	rc = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts_sleep, &ts_rem);
+	/* FIXME: when should we display the remainder ? */
+	if (rc != 0) {
+		printf("WARNING: rt_nanosleep() returned early by %d s %d ns\n",
+			(int)ts_rem.tv_sec, (int)ts_rem.tv_nsec);
+	}
+}
+
 void rt_nanosleep(nsec_t ns) {
 	struct timespec ts_sleep, ts_rem;
 	int rc;



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic