vdso/gettimeofday.c

This is vdso/gettimeofday.c, an example to accompany the book, The Linux Programming Interface.

This file is not printed in the book; it demonstrates Linux features that are not described in the book (typically features that have appeared since the book was published).

The source code file is copyright 2024, Michael Kerrisk, and is licensed under the GNU General Public License, version 3.

In the listing below, the names of Linux system calls and C library functions are hyperlinked to manual pages from the Linux man-pages project, and the names of functions implemented in the book are hyperlinked to the implementations of those functions.

 

Download vdso/gettimeofday.c

  Cover of The Linux Programming Interface

Function list (Bold in this list means a function is not static)

/* gettimeofday.c

   A short program to demonstrate the benefits that the VDSO confers by
   replacing some traditional system calls with a user-space implementation
   in a shared library that is created by the kernel and mapped into the
   process's address space. Only certain system calls--those whose
   functionality can be performed entirely in user space--can be replaced
   with VDSO implementations; the vdso(7) manual page describes which
   functions are implemented in the VDSO on each Linux architecture.

   One system call that is commonly bypassed through an implementation in
   the VDSO is gettimeofday(2), which returns the current time. Obtaining
   the time on a computer is typically a matter of reading the value of a
   dedicated register (the "timestamp counter", TSC) or other hardware
   location. This operation can be performed from user space, but doing so
   requires machine-specific instructions and information, and we normally
   don't want to code such machine-specific dependencies into a user-space
   application. Thus, instead, the kernel (which by definition knows about
   every architecture) provides a system call that executes the necessary
   machine-specific code.  With the existence of the VDSO, there is now an
   alternative: the kernel (which knows the machine specifics of accessing
   the TSC) can provide code in the VDSO that accesses the TSC. Since the
   VDSO is mapped into the process's user-space memory, the process can now
   access the TSC directly from user space (without itself containing any
   machine-specific code to perform that access).

   This program can be used to produce two binaries, one of which calls the
   gettimeofday() wrapper function in the C library while the other
   directly invokes the kernel system call using syscall(2). The choice is
   determined based on whether or not the USE_SYSCALL macro is defined. On
   systems (e.g., x86) where the kernel provides a VDSO implementation of
   gettimeofday() and the C library knows to use that implementation,
   obtaining the time will be a fast user-space operation.  By contrast,
   when the system call is directly invoked via syscall(2) (a binary build
   with "cc -DUSE_SYSCALL"), obtaining the system time will be much slower.

   The program takes one command-line argument, which specifies the number
   times to loop fetching the system time. Try running the two different
   binaries with the same argument and timing the results using time(1).
   For example:

        time ./syscall_gettimeofday 10000000
        time ./vdso_gettimeofday    10000000
*/
#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <sys/syscall.h>
#include <sys/time.h>
#include "tlpi_hdr.h"
int
main(int argc, char *argv[])
{
    if (argc < 2 || strcmp(argv[1], "--help") == 0)
        usageErr("%s loop-count\n", argv[0]);

    long lim = atoi(argv[1]);

    for (int j = 0; j < lim; j++) {
        struct timeval curr;

#ifdef USE_SYSCALL
        if (syscall(__NR_gettimeofday, &curr, NULL) == -1)
            errExit("gettimeofday");
#else
        if (gettimeofday(&curr, NULL) == -1)
            errExit("gettimeofday");
#endif
    }

    exit(EXIT_SUCCESS);
}

 

Download vdso/gettimeofday.c

Note that, in most cases, the programs rendered in these web pages are not free standing: you'll typically also need a few other source files (mostly in the lib/ subdirectory) as well. Generally, it's easier to just download the entire source tarball and build the programs with make(1). By hovering your mouse over the various hyperlinked include files and function calls above, you can see which other source files this file depends on.

Valid XHTML 1.1