[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <cfd18e0f0902090128i1a4902f4of0d4d830b567602f@mail.gmail.com>
Date: Mon, 9 Feb 2009 22:28:36 +1300
From: Michael Kerrisk <mtk.manpages@...glemail.com>
To: Davide Libenzi <davidel@...ilserver.org>
Cc: Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Thomas Gleixner <tglx@...utronix.de>,
Andrew Morton <akpm@...ux-foundation.org>
Subject: Re: [patch 2/2] timerfd extend clockid support
On Mon, Feb 9, 2009 at 12:23 PM, Davide Libenzi <davidel@...ilserver.org> wrote:
> The following patch extends timerfd clockid support to cover the ones
> supported by timer_create().
> It exports the invalid_clockid() function outside posix-timers.c to allow
> timerfd to properly check input parameters.
> Andrew, this is (eventually) .30 material, and do not take the patch
> until you have Thomas sign off.
> Thomas, timerfd uses core hrtimer functions for its tasks. By extending
> the clockid support, I assume that the clockids other than CLOCK_MONOTONIC
> and CLOCK_REALTIME, behaves the same from a hrtimer caller POV. Right?
Hi Davide,
Have you done any testing of this patch? My attempts at testing with
clocks other than REALTIME and MONOTONIC all don't work so far. In
some cases, my test programs causes the system to hang. Try
experimenting with the (not yet well tested) test program below, to
check the behavior with other clocks.
Cheers,
Michael
/* timerfd_demo.c
Compile with -lrt
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/timerfd.h>
#include <pthread.h>
#include <stdint.h> /* Definition of uint64_t */
#define SIG SIGUSR1
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
static void *
thread_func(void *arg)
{
printf("Thread burning CPU\n");
for (;;)
;
}
int
main(int argc, char *argv[])
{
timer_t timer_id;
struct itimerspec its;
clockid_t clock_id;
int flags, s, fd;
struct timespec ts;
uint64_t numExp;
if (argc < 4) {
fprintf(stderr, "Usage: %s <clockid> <flags> <num-secs> "
"[<clock-adj-secs>]\n", argv[0]);
#define fpe(str) fprintf(stderr, str);
fpe("<clockid> is one of:\n");
fpe("\tm CLOCK_MONOTONIC\n");
fpe("\tr CLOCK_REALTIME\n");
fpe("\tp CLOCK_PROCESS_CPUTIME_ID\n");
fpe("\tC clock of a child process that burns CPU time\n");
fpe("\tT clock of a sub-thread that burns CPU time\n");
fpe("<flags> is one of:\n");
fpe("\ta absolute timer (<num-secs> is added to current\n");
fpe("\t clock value)\n")
fpe("\t- relative timer\n")
fpe("<num-secs> is the initial expiration time for the timer\n");
fpe("<clock-adj-secs> is number of seconds by which clock\n");
fpe("\tshould be adjusted (clock_settime()) after timer\n");
fpe("\thas started\n")
exit(EXIT_FAILURE);
}
if (argv[1][0] == 'C') {
pid_t cpid;
cpid = fork();
if (cpid == -1)
errExit("fork");
if (cpid == 0) {
usleep(10000);
printf("Child process burning CPU time\n");
alarm(100); /* Ensure child eventually dies */
for (;;)
;
} else { /* Parent gets CPU clock ID of child and
falls through */
if (clock_getcpuclockid(cpid, &clock_id) == -1)
errExit("clock_getcpuclockid");
}
} else if (argv[1][0] == 'T') {
pthread_t t;
errno = pthread_create(&t, NULL, thread_func, NULL);
if (errno != 0)
errExit("pthread_create");
errno = pthread_getcpuclockid(t, &clock_id);
if (errno != 0)
errExit("pthread_getcpuclockid");
} else {
clock_id = (argv[1][0] == 'm') ? CLOCK_MONOTONIC :
(argv[1][0] == 'r') ? CLOCK_REALTIME :
(argv[1][0] == 'p') ? CLOCK_PROCESS_CPUTIME_ID :
-999999; /* Unlikely to be a valid clock ID */
if (clock_id == CLOCK_PROCESS_CPUTIME_ID) {
pthread_t t;
errno = pthread_create(&t, NULL, thread_func, NULL);
if (errno != 0)
errExit("pthread_create");
}
}
fd = timerfd_create(clock_id, 0);
if (fd == -1)
errExit("timerfd_create");
printf("clock ID is 0x%lx\n", (long) clock_id);
printf("timer ID is 0x%lx\n", (long) timer_id);
flags = (argv[2][0] == 'a') ? TFD_TIMER_ABSTIME : 0;
if (flags & TFD_TIMER_ABSTIME) {
printf("Absolute timer\n");
if (clock_gettime(clock_id, &ts) == -1)
errExit("clock_gettime");
printf("Current clock value = %ld\n", (long) ts.tv_sec);
its.it_value.tv_sec = ts.tv_sec + atoi(argv[3]);
its.it_value.tv_nsec = ts.tv_nsec;
} else {
its.it_value.tv_sec = atoi(argv[3]);
its.it_value.tv_nsec = 0;
}
its.it_interval.tv_sec = 1;
its.it_interval.tv_nsec = 0;
printf("its.it_value.tv_sec = %ld\n",
(long) its.it_value.tv_sec);
if (timerfd_settime(fd, flags, &its, NULL) == -1)
errExit("timer_settime");
if (argc > 4) {
if (clock_gettime(clock_id, &ts) == -1)
errExit("clock_gettime");
ts.tv_sec += atoi(argv[4]);
printf("About to adjust clock to %ld\n", (long) ts.tv_sec);
if (clock_settime(clock_id, &ts) == -1)
errExit("clock_settime");
}
s = read(fd, &numExp, sizeof(uint64_t));
if (s != sizeof(uint64_t))
errExit("read");
printf("number of expirations = %lld\n",
(unsigned long long) numExp);
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists