Re: RFC: A revised timerfd API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Davide,

Davide Libenzi wrote:
> On Sat, 22 Sep 2007, Michael Kerrisk wrote:
> 
>> So I'm inclined to implement option (b), unless someone has strong
>> objections.  Davide, could I persuade you to help?
> 
> I guess I better do, otherwise you'll continue to stress me ;)

Thanks -- that was more than I hoped for!

> int timerfd_create(int clockid);
> int timerfd_settime(int ufd, int flags,
>                     const struct itimerspec *utmr,
>                     struct itimerspec *otmr);
> int timerfd_gettime(int ufd, struct itimerspec *otmr);
> 
> Patch below. Builds, not tested yet (you need to remove the "broken" 
> status from CONFIG_TIMERFD in case you want to test - and plug the new 
> syscall to arch/xxx).

I applied this patch against 2.6.27-rc7, and wired up the syscalls as shown
in the definitions below.  When I ran the the program below, my system
immediately froze.  Can you try it on your system please.

Cheers,

Michael

/* Link with -lrt */

#define _GNU_SOURCE
#include <sys/syscall.h>
#include <unistd.h>
#include <time.h>
#if defined(__i386__)
#define __NR_timerfd_create 325
#define __NR_timerfd_settime 326
#define __NR_timerfd_gettime 327
17170:man-pages/man2> cat timerfd3_test.c
/* Link with -lrt */

#define _GNU_SOURCE
#include <sys/syscall.h>
#include <unistd.h>
#include <time.h>
#if defined(__i386__)
#define __NR_timerfd_create 325
#define __NR_timerfd_settime 326
#define __NR_timerfd_gettime 327
#endif

static int
timerfd_create(int clockid)
{
    return syscall(__NR_timerfd_create, clockid);
}

static int
timerfd_settime(int ufd, int flags, struct itimerspec *utmr,
        struct itimerspec *outmr)
{
    return syscall(__NR_timerfd_settime, ufd, flags, utmr, outmr);
}

static int
timerfd_gettime(int ufd, struct itimerspec *outmr)
{
    return syscall(__NR_timerfd_gettime, ufd, outmr);
}

/*
static int
timerfd(int ufd, int clockid, int flags, struct itimerspec *utmr,
        struct itimerspec *outmr)
{
    return syscall(__NR_timerfd, ufd, clockid, flags, utmr, outmr);
}

*/


/*
int timerfd_settime(int ufd, int flags,
> >                     const struct itimerspec *utmr,
> >                     struct itimerspec *otmr);
> > int timerfd_gettime(int ufd, struct itimerspec *otmr)
*/
#define TFD_TIMER_ABSTIME (1 << 0)

////////////////////////////////////////////////////////////

// #include <sys/timerfd.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>     /* Definition of uint32_t */

#define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)

static void
print_elapsed_time(void)
{
    static struct timespec start;
    struct timespec curr;
    static int first_call = 1;
    int secs, nsecs;

    if (first_call) {
        first_call = 0;
        if (clock_gettime(CLOCK_MONOTONIC, &start) == -1)
            die("clock_gettime");
    }

    if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1)
        die("clock_gettime");

    secs = curr.tv_sec - start.tv_sec;
    nsecs = curr.tv_nsec - start.tv_nsec;
    if (nsecs < 0) {
        secs--;
        nsecs += 1000000000;
    }
    printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
}

int
main(int argc, char *argv[])
{
    struct itimerspec utmr, outmr;
    int ufd;
    struct timespec now;
    int j, s;
    uint64_t exp;
    time_t start;

    if (argc < 2) {
        fprintf(stderr, "%s init-secs [interval-secs]\n",
                argv[0]);
        exit(EXIT_FAILURE);
    }

    if (clock_gettime(CLOCK_REALTIME, &now) == -1)
        die("clock_gettime");

    /* Create a CLOCK_REALTIME absolute timer with initial
       expiration and interval as specified in command line */

    utmr.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
    utmr.it_value.tv_nsec = now.tv_nsec;
    if (argc == 2) {
        utmr.it_interval.tv_sec = 0;
    } else {
        utmr.it_interval.tv_sec = atoi(argv[2]);
    }
    utmr.it_interval.tv_nsec = 0;

    ufd = timerfd_create(CLOCK_REALTIME);
    if (ufd == -1)
        die("timerfd");
    s = timerfd_settime(ufd, TFD_TIMER_ABSTIME, &utmr, NULL);
    if (ufd == -1)
        die("timerfd");

    start = time(NULL);
    for (j = 0; ; j++) {
        sleep(1);
        if (0 && (j % 10) == 0) {
            printf("Resetting timer\n");
            utmr.it_value.tv_sec += 1;
            utmr.it_interval.tv_sec += 2;
            s = timerfd_settime(ufd, 0, &utmr, &outmr);
            if (s == -1)
                die("timerfd-2");

        }
        s = timerfd_gettime(ufd, &outmr);
        printf("Retrieval %3d (%3ld) - Got: %ld %ld; %ld %ld\n",
                j, (long) (time(NULL) - start),
                (long) outmr.it_value.tv_sec,
                (long) outmr.it_value.tv_nsec,
                (long) outmr.it_interval.tv_sec,
                (long) outmr.it_interval.tv_nsec);
        if ((j % 30) == 0 && j > 0) {
            printf("About to read\n");
            s = read(ufd, &exp, sizeof(uint64_t));
            if (s != sizeof(uint64_t))
                die("read");
            printf("Read: %lld\n", exp);
        }
    }

    exit(EXIT_SUCCESS);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux