public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH] add clock_gettime04
@ 2014-09-10 12:46 Jan Stancek
  2014-09-10 15:18 ` chrubis
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Stancek @ 2014-09-10 12:46 UTC (permalink / raw)
  To: ltp-list

Add regression test for commit:
  commit 4036ac1567834222fc763ab18e3e17df93b4eaaf
  Author: Mike Galbraith <umgwanakikbuti@gmail.com>
  Date:   Tue Jun 24 07:49:40 2014 +0200
    sched: Fix clock_gettime(CLOCK_[PROCESS/THREAD]_CPUTIME_ID) monotonicity

Cpu time returned by clock_gettime for thread specific clock prior to
this commit is not monotonic.

Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
 runtest/timers                                     |    1 +
 testcases/kernel/timers/clock_gettime/.gitignore   |    1 +
 .../kernel/timers/clock_gettime/clock_gettime04.c  |  208 ++++++++++++++++++++
 3 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/timers/clock_gettime/clock_gettime04.c

diff --git a/runtest/timers b/runtest/timers
index a58ac57..daa617f 100644
--- a/runtest/timers
+++ b/runtest/timers
@@ -1,6 +1,7 @@
 #DESCRIPTION:Posix Timer Tests
 clock_gettime02 clock_gettime02
 clock_gettime03 clock_gettime03
+clock_gettime04 clock_gettime04
 clock_settime02 clock_settime02
 clock_settime03 clock_settime03
 timer_create02 timer_create02
diff --git a/testcases/kernel/timers/clock_gettime/.gitignore b/testcases/kernel/timers/clock_gettime/.gitignore
index 004e742..4f17c8b 100644
--- a/testcases/kernel/timers/clock_gettime/.gitignore
+++ b/testcases/kernel/timers/clock_gettime/.gitignore
@@ -1,2 +1,3 @@
 /clock_gettime02
 /clock_gettime03
+/clock_gettime04
diff --git a/testcases/kernel/timers/clock_gettime/clock_gettime04.c b/testcases/kernel/timers/clock_gettime/clock_gettime04.c
new file mode 100644
index 0000000..9d1cb55
--- /dev/null
+++ b/testcases/kernel/timers/clock_gettime/clock_gettime04.c
@@ -0,0 +1,208 @@
+/*
+ *  Copyright (c) Linux Test Project, 2014
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ */
+/*
+ * This is a regression test for bug fixed by:
+ *   commit 4036ac1567834222fc763ab18e3e17df93b4eaaf
+ *   Author: Mike Galbraith <umgwanakikbuti@gmail.com>
+ *   Date:   Tue Jun 24 07:49:40 2014 +0200
+ *     sched: Fix clock_gettime(CLOCK_[PROCESS/THREAD]_CPUTIME_ID) monotonicity
+ *
+ * cpu time returned by clock_gettime for thread specific clock prior to
+ * this commit is not monotonic.
+ */
+
+#include <pthread.h>
+#include <inttypes.h>
+#include <errno.h>
+
+#include "test.h"
+#include "usctest.h"
+#include "safe_macros.h"
+
+#define DEFAULT_TEST_TIME 4
+#define THREAD_COUNT 8
+#define NANOSECS_PER_SEC 1000000000
+
+#define SAFE_PTHREAD(fn, ...) do { \
+	int ret = fn(__VA_ARGS__); \
+	if (ret) { \
+		TEST_ERRNO = ret; \
+		tst_brkm(TBROK | TTERRNO, cleanup, #fn); \
+	} \
+} while (0)
+
+char *TCID = "clock_gettime04";
+int TST_TOTAL = 1;
+
+static volatile sig_atomic_t done_testing;
+static int opt_testtime;
+static char *opt_testtimestr;
+static option_t options[] = {
+	{"T:", &opt_testtime, &opt_testtimestr},
+	{NULL, NULL, NULL}
+};
+static pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void setup(void);
+static void cleanup(void);
+
+static void sigproc(int sig)
+{
+	(void) sig;
+	done_testing = 1;
+}
+
+int64_t get_thread_cpu_time(pthread_t thread)
+{
+	clockid_t clockid;
+	int ret;
+	struct timespec tp;
+
+	SAFE_PTHREAD(pthread_getcpuclockid, thread, &clockid);
+
+	ret = clock_gettime(clockid, &tp);
+	if (ret)
+		tst_brkm(TBROK | TERRNO, cleanup, "clock_gettime: %d", ret);
+
+	return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
+}
+
+static void *child(void *arg)
+{
+	struct timespec tim;
+	int64_t t, t_last = 0;
+	int check_own_cpu_time = *(int *)arg;
+
+	tim.tv_sec = 0;
+	tim.tv_nsec = 5000;
+
+	while (!done_testing) {
+		nanosleep(&tim, NULL);
+
+		if (!check_own_cpu_time)
+			continue;
+
+		t = get_thread_cpu_time(pthread_self());
+		if (t < t_last) {
+			tst_resm(TFAIL, "t: %" PRId64 " < t_last: %"
+				PRId64,	t, t_last);
+			done_testing = 2;
+		} else {
+			t_last = t;
+		}
+	}
+
+	SAFE_PTHREAD(pthread_mutex_lock, &exit_mutex);
+	SAFE_PTHREAD(pthread_mutex_unlock, &exit_mutex);
+
+	return NULL;
+}
+
+static void test(int seconds)
+{
+	int i, child_check_cpu_time[] = { 0, 1 };
+	pthread_t thread[THREAD_COUNT];
+	clockid_t clockid[THREAD_COUNT];
+	int64_t thread_time[THREAD_COUNT], cur_time;
+
+	done_testing = 0;
+	alarm(seconds);
+
+	/* create children and make every 2nd child check its own
+	 * cpu time as well. */
+	for (i = 0; i < THREAD_COUNT; i++) {
+		SAFE_PTHREAD(pthread_create, &thread[i], NULL, child,
+			&child_check_cpu_time[i % 2]);
+		SAFE_PTHREAD(pthread_getcpuclockid, thread[i], &clockid[i]);
+		tst_resm(TINFO, "thread no.: %d clockid: %d", i, clockid[i]);
+	}
+
+	for (i = 0; i < THREAD_COUNT; i++)
+		thread_time[i] = get_thread_cpu_time(thread[i]);
+
+	SAFE_PTHREAD(pthread_mutex_lock, &exit_mutex);
+
+	/* check periodically that cpu time of each thread
+	 * doesn't go backwards */
+	while (!done_testing) {
+		for (i = 0; i < THREAD_COUNT; i++) {
+			cur_time = get_thread_cpu_time(thread[i]);
+			if (cur_time < thread_time[i]) {
+				tst_resm(TFAIL, "cpu clock time went backwards "
+						"thread no. %d, clock id: %d"
+						" previous value: %" PRId64
+						" current value: %" PRId64,
+						i, clockid[i], thread_time[i],
+						cur_time);
+				done_testing = 2;
+				break;
+			}
+			thread_time[i] = cur_time;
+		}
+	}
+
+	/* allow children to exit now */
+	SAFE_PTHREAD(pthread_mutex_unlock, &exit_mutex);
+
+	for (i = 0; i < THREAD_COUNT; i++)
+		SAFE_PTHREAD(pthread_join, thread[i], NULL);
+
+	if (done_testing == 1)
+		tst_resm(TPASS, "Test completed, cpu times of all "
+				"thread clocks were monotonic");
+}
+
+int main(int argc, char *argv[])
+{
+	int testtime = DEFAULT_TEST_TIME;
+	const char *msg = NULL;
+
+	msg = parse_opts(argc, argv, options, NULL);
+	if (msg)
+		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+
+	if (opt_testtime) {
+		testtime = atoi(opt_testtimestr);
+		if (testtime <= 0) {
+			tst_brkm(TBROK, NULL, "Invalid arg for -T: %s",
+				opt_testtimestr);
+		}
+	}
+
+	setup();
+
+	test(testtime);
+
+	cleanup();
+	tst_exit();
+}
+
+static void setup(void)
+{
+	struct sigaction sa;
+
+	TEST_PAUSE;
+
+	sigemptyset(&sa.sa_mask);
+	sa.sa_handler = sigproc;
+	sa.sa_flags = 0;
+
+	if (sigaction(SIGALRM, &sa, 0) == -1)
+		tst_brkm(TBROK | TERRNO, NULL, "sigaction() failed");
+}
+
+static void cleanup(void)
+{
+	TEST_CLEANUP;
+}
-- 
1.7.1


------------------------------------------------------------------------------
Want excitement?
Manually upgrade your production database.
When you want reliability, choose Perforce
Perforce version control. Predictably reliable.
http://pubads.g.doubleclick.net/gampad/clk?id=157508191&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-09-10 16:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-10 12:46 [LTP] [PATCH] add clock_gettime04 Jan Stancek
2014-09-10 15:18 ` chrubis
     [not found]   ` <1162485694.20768561.1410363325469.JavaMail.zimbra@redhat.com>
2014-09-10 16:32     ` chrubis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox