| .\" Copyright (c) 2009 Linux Foundation, written by Michael Kerrisk |
| .\" <mtk.manpages@gmail.com> |
| .\" |
| .\" %%%LICENSE_START(VERBATIM) |
| .\" Permission is granted to make and distribute verbatim copies of this |
| .\" manual provided the copyright notice and this permission notice are |
| .\" preserved on all copies. |
| .\" |
| .\" Permission is granted to copy and distribute modified versions of this |
| .\" manual under the conditions for verbatim copying, provided that the |
| .\" entire resulting derived work is distributed under the terms of a |
| .\" permission notice identical to this one. |
| .\" |
| .\" Since the Linux kernel and libraries are constantly changing, this |
| .\" manual page may be incorrect or out-of-date. The author(s) assume no |
| .\" responsibility for errors or omissions, or for damages resulting from |
| .\" the use of the information contained herein. The author(s) may not |
| .\" have taken the same level of care in the production of this manual, |
| .\" which is licensed free of charge, as they might when working |
| .\" professionally. |
| .\" |
| .\" Formatted or processed versions of this manual, if unaccompanied by |
| .\" the source, must acknowledge the copyright and authors of this work. |
| .\" %%%LICENSE_END |
| .\" |
| .TH TIMER_CREATE 2 2021-03-22 Linux "Linux Programmer's Manual" |
| .SH NAME |
| timer_create \- create a POSIX per-process timer |
| .SH SYNOPSIS |
| .nf |
| .B #include <signal.h> |
| .B #include <time.h> |
| .PP |
| .BI "int timer_create(clockid_t " clockid ", struct sigevent *restrict " sevp , |
| .BI " timer_t *restrict " timerid ); |
| .fi |
| .PP |
| Link with \fI\-lrt\fP. |
| .PP |
| .RS -4 |
| Feature Test Macro Requirements for glibc (see |
| .BR feature_test_macros (7)): |
| .RE |
| .PP |
| .BR timer_create (): |
| .nf |
| _POSIX_C_SOURCE >= 199309L |
| .fi |
| .SH DESCRIPTION |
| .BR timer_create () |
| creates a new per-process interval timer. |
| The ID of the new timer is returned in the buffer pointed to by |
| .IR timerid , |
| which must be a non-null pointer. |
| This ID is unique within the process, until the timer is deleted. |
| The new timer is initially disarmed. |
| .PP |
| The |
| .I clockid |
| argument specifies the clock that the new timer uses to measure time. |
| It can be specified as one of the following values: |
| .TP |
| .B CLOCK_REALTIME |
| A settable system-wide real-time clock. |
| .TP |
| .B CLOCK_MONOTONIC |
| A nonsettable monotonically increasing clock that measures time |
| from some unspecified point in the past that does not change |
| after system startup. |
| .\" Note: the CLOCK_MONOTONIC_RAW clock added for clock_gettime() |
| .\" in 2.6.28 is not supported for POSIX timers -- mtk, Feb 2009 |
| .TP |
| .BR CLOCK_PROCESS_CPUTIME_ID " (since Linux 2.6.12)" |
| A clock that measures (user and system) CPU time consumed by |
| (all of the threads in) the calling process. |
| .TP |
| .BR CLOCK_THREAD_CPUTIME_ID " (since Linux 2.6.12)" |
| A clock that measures (user and system) CPU time consumed by |
| the calling thread. |
| .\" The CLOCK_MONOTONIC_RAW that was added in 2.6.28 can't be used |
| .\" to create a timer -- mtk, Feb 2009 |
| .TP |
| .BR CLOCK_BOOTTIME " (Since Linux 2.6.39)" |
| .\" commit 70a08cca1227dc31c784ec930099a4417a06e7d0 |
| Like |
| .BR CLOCK_MONOTONIC , |
| this is a monotonically increasing clock. |
| However, whereas the |
| .BR CLOCK_MONOTONIC |
| clock does not measure the time while a system is suspended, the |
| .BR CLOCK_BOOTTIME |
| clock does include the time during which the system is suspended. |
| This is useful for applications that need to be suspend-aware. |
| .BR CLOCK_REALTIME |
| is not suitable for such applications, since that clock is affected |
| by discontinuous changes to the system clock. |
| .TP |
| .BR CLOCK_REALTIME_ALARM " (since Linux 3.0)" |
| .\" commit 9a7adcf5c6dea63d2e47e6f6d2f7a6c9f48b9337 |
| This clock is like |
| .BR CLOCK_REALTIME , |
| but will wake the system if it is suspended. |
| The caller must have the |
| .B CAP_WAKE_ALARM |
| capability in order to set a timer against this clock. |
| .TP |
| .BR CLOCK_BOOTTIME_ALARM " (since Linux 3.0)" |
| .\" commit 9a7adcf5c6dea63d2e47e6f6d2f7a6c9f48b9337 |
| This clock is like |
| .BR CLOCK_BOOTTIME , |
| but will wake the system if it is suspended. |
| The caller must have the |
| .B CAP_WAKE_ALARM |
| capability in order to set a timer against this clock. |
| .TP |
| .BR CLOCK_TAI " (since Linux 3.10)" |
| A system-wide clock derived from wall-clock time but ignoring leap seconds. |
| .PP |
| See |
| .BR clock_getres (2) |
| for some further details on the above clocks. |
| .PP |
| As well as the above values, |
| .I clockid |
| can be specified as the |
| .I clockid |
| returned by a call to |
| .BR clock_getcpuclockid (3) |
| or |
| .BR pthread_getcpuclockid (3). |
| .PP |
| The |
| .I sevp |
| argument points to a |
| .I sigevent |
| structure that specifies how the caller |
| should be notified when the timer expires. |
| For the definition and general details of this structure, see |
| .BR sigevent (7). |
| .PP |
| The |
| .I sevp.sigev_notify |
| field can have the following values: |
| .TP |
| .BR SIGEV_NONE |
| Don't asynchronously notify when the timer expires. |
| Progress of the timer can be monitored using |
| .BR timer_gettime (2). |
| .TP |
| .BR SIGEV_SIGNAL |
| Upon timer expiration, generate the signal |
| .I sigev_signo |
| for the process. |
| See |
| .BR sigevent (7) |
| for general details. |
| The |
| .I si_code |
| field of the |
| .I siginfo_t |
| structure will be set to |
| .BR SI_TIMER . |
| At any point in time, |
| at most one signal is queued to the process for a given timer; see |
| .BR timer_getoverrun (2) |
| for more details. |
| .TP |
| .BR SIGEV_THREAD |
| Upon timer expiration, invoke |
| .I sigev_notify_function |
| as if it were the start function of a new thread. |
| See |
| .BR sigevent (7) |
| for details. |
| .TP |
| .BR SIGEV_THREAD_ID " (Linux-specific)" |
| As for |
| .BR SIGEV_SIGNAL , |
| but the signal is targeted at the thread whose ID is given in |
| .IR sigev_notify_thread_id , |
| which must be a thread in the same process as the caller. |
| The |
| .IR sigev_notify_thread_id |
| field specifies a kernel thread ID, that is, the value returned by |
| .BR clone (2) |
| or |
| .BR gettid (2). |
| This flag is intended only for use by threading libraries. |
| .PP |
| Specifying |
| .I sevp |
| as NULL is equivalent to specifying a pointer to a |
| .I sigevent |
| structure in which |
| .I sigev_notify |
| is |
| .BR SIGEV_SIGNAL , |
| .I sigev_signo |
| is |
| .BR SIGALRM , |
| and |
| .I sigev_value.sival_int |
| is the timer ID. |
| .SH RETURN VALUE |
| On success, |
| .BR timer_create () |
| returns 0, and the ID of the new timer is placed in |
| .IR *timerid . |
| On failure, \-1 is returned, and |
| .I errno |
| is set to indicate the error. |
| .SH ERRORS |
| .TP |
| .B EAGAIN |
| Temporary error during kernel allocation of timer structures. |
| .TP |
| .B EINVAL |
| Clock ID, |
| .IR sigev_notify , |
| .IR sigev_signo , |
| or |
| .IR sigev_notify_thread_id |
| is invalid. |
| .TP |
| .B ENOMEM |
| .\" glibc layer: malloc() |
| Could not allocate memory. |
| .TP |
| .B ENOTSUP |
| The kernel does not support creating a timer against this |
| .IR clockid . |
| .TP |
| .B EPERM |
| .I clockid |
| was |
| .BR CLOCK_REALTIME_ALARM |
| or |
| .BR CLOCK_BOOTTIME_ALARM |
| but the caller did not have the |
| .BR CAP_WAKE_ALARM |
| capability. |
| .SH VERSIONS |
| This system call is available since Linux 2.6. |
| .SH CONFORMING TO |
| POSIX.1-2001, POSIX.1-2008. |
| .SH NOTES |
| A program may create multiple interval timers using |
| .BR timer_create (). |
| .PP |
| Timers are not inherited by the child of a |
| .BR fork (2), |
| and are disarmed and deleted during an |
| .BR execve (2). |
| .PP |
| The kernel preallocates a "queued real-time signal" |
| for each timer created using |
| .BR timer_create (). |
| Consequently, the number of timers is limited by the |
| .BR RLIMIT_SIGPENDING |
| resource limit (see |
| .BR setrlimit (2)). |
| .PP |
| The timers created by |
| .BR timer_create () |
| are commonly known as "POSIX (interval) timers". |
| The POSIX timers API consists of the following interfaces: |
| .IP * 3 |
| .BR timer_create (): |
| Create a timer. |
| .IP * |
| .BR timer_settime (2): |
| Arm (start) or disarm (stop) a timer. |
| .IP * |
| .BR timer_gettime (2): |
| Fetch the time remaining until the next expiration of a timer, |
| along with the interval setting of the timer. |
| .IP * |
| .BR timer_getoverrun (2): |
| Return the overrun count for the last timer expiration. |
| .IP * |
| .BR timer_delete (2): |
| Disarm and delete a timer. |
| .PP |
| Since Linux 3.10, the |
| .IR /proc/[pid]/timers |
| file can be used to list the POSIX timers for the process with PID |
| .IR pid . |
| See |
| .BR proc (5) |
| for further information. |
| .PP |
| Since Linux 4.10, |
| .\" baa73d9e478ff32d62f3f9422822b59dd9a95a21 |
| support for POSIX timers is a configurable option that is enabled by default. |
| Kernel support can be disabled via the |
| .BR CONFIG_POSIX_TIMERS |
| option. |
| .\" |
| .SS C library/kernel differences |
| Part of the implementation of the POSIX timers API is provided by glibc. |
| .\" See nptl/sysdeps/unix/sysv/linux/timer_create.c |
| In particular: |
| .IP * 3 |
| Much of the functionality for |
| .BR SIGEV_THREAD |
| is implemented within glibc, rather than the kernel. |
| (This is necessarily so, |
| since the thread involved in handling the notification is one |
| that must be managed by the C library POSIX threads implementation.) |
| Although the notification delivered to the process is via a thread, |
| internally the NPTL implementation uses a |
| .I sigev_notify |
| value of |
| .BR SIGEV_THREAD_ID |
| along with a real-time signal that is reserved by the implementation (see |
| .BR nptl (7)). |
| .IP * |
| The implementation of the default case where |
| .I evp |
| is NULL is handled inside glibc, |
| which invokes the underlying system call with a suitably populated |
| .I sigevent |
| structure. |
| .IP * |
| The timer IDs presented at user level are maintained by glibc, |
| which maps these IDs to the timer IDs employed by the kernel. |
| .\" See the glibc source file kernel-posix-timers.h for the structure |
| .\" that glibc uses to map user-space timer IDs to kernel timer IDs |
| .\" The kernel-level timer ID is exposed via siginfo.si_tid. |
| .PP |
| The POSIX timers system calls first appeared in Linux 2.6. |
| Prior to this, |
| glibc provided an incomplete user-space implementation |
| .RB ( CLOCK_REALTIME |
| timers only) using POSIX threads, |
| and in glibc versions before 2.17, |
| .\" glibc commit 93a78ac437ba44f493333d7e2a4b0249839ce460 |
| the implementation falls back to this technique on systems |
| running pre-2.6 Linux kernels. |
| .SH EXAMPLES |
| The program below takes two arguments: a sleep period in seconds, |
| and a timer frequency in nanoseconds. |
| The program establishes a handler for the signal it uses for the timer, |
| blocks that signal, |
| creates and arms a timer that expires with the given frequency, |
| sleeps for the specified number of seconds, |
| and then unblocks the timer signal. |
| Assuming that the timer expired at least once while the program slept, |
| the signal handler will be invoked, |
| and the handler displays some information about the timer notification. |
| The program terminates after one invocation of the signal handler. |
| .PP |
| In the following example run, the program sleeps for 1 second, |
| after creating a timer that has a frequency of 100 nanoseconds. |
| By the time the signal is unblocked and delivered, |
| there have been around ten million overruns. |
| .PP |
| .in +4n |
| .EX |
| $ \fB./a.out 1 100\fP |
| Establishing handler for signal 34 |
| Blocking signal 34 |
| timer ID is 0x804c008 |
| Sleeping for 1 seconds |
| Unblocking signal 34 |
| Caught signal 34 |
| sival_ptr = 0xbfb174f4; *sival_ptr = 0x804c008 |
| overrun count = 10004886 |
| .EE |
| .in |
| .SS Program source |
| \& |
| .EX |
| #include <stdint.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <stdio.h> |
| #include <signal.h> |
| #include <time.h> |
| |
| #define CLOCKID CLOCK_REALTIME |
| #define SIG SIGRTMIN |
| |
| #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e |
| } while (0) |
| |
| static void |
| print_siginfo(siginfo_t *si) |
| { |
| timer_t *tidp; |
| int or; |
| |
| tidp = si\->si_value.sival_ptr; |
| |
| printf(" sival_ptr = %p; ", si\->si_value.sival_ptr); |
| printf(" *sival_ptr = %#jx\en", (uintmax_t) *tidp); |
| |
| or = timer_getoverrun(*tidp); |
| if (or == \-1) |
| errExit("timer_getoverrun"); |
| else |
| printf(" overrun count = %d\en", or); |
| } |
| |
| static void |
| handler(int sig, siginfo_t *si, void *uc) |
| { |
| /* Note: calling printf() from a signal handler is not safe |
| (and should not be done in production programs), since |
| printf() is not async\-signal\-safe; see signal\-safety(7). |
| Nevertheless, we use printf() here as a simple way of |
| showing that the handler was called. */ |
| |
| printf("Caught signal %d\en", sig); |
| print_siginfo(si); |
| signal(sig, SIG_IGN); |
| } |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| timer_t timerid; |
| struct sigevent sev; |
| struct itimerspec its; |
| long long freq_nanosecs; |
| sigset_t mask; |
| struct sigaction sa; |
| |
| if (argc != 3) { |
| fprintf(stderr, "Usage: %s <sleep\-secs> <freq\-nanosecs>\en", |
| argv[0]); |
| exit(EXIT_FAILURE); |
| } |
| |
| /* Establish handler for timer signal. */ |
| |
| printf("Establishing handler for signal %d\en", SIG); |
| sa.sa_flags = SA_SIGINFO; |
| sa.sa_sigaction = handler; |
| sigemptyset(&sa.sa_mask); |
| if (sigaction(SIG, &sa, NULL) == \-1) |
| errExit("sigaction"); |
| |
| /* Block timer signal temporarily. */ |
| |
| printf("Blocking signal %d\en", SIG); |
| sigemptyset(&mask); |
| sigaddset(&mask, SIG); |
| if (sigprocmask(SIG_SETMASK, &mask, NULL) == \-1) |
| errExit("sigprocmask"); |
| |
| /* Create the timer. */ |
| |
| sev.sigev_notify = SIGEV_SIGNAL; |
| sev.sigev_signo = SIG; |
| sev.sigev_value.sival_ptr = &timerid; |
| if (timer_create(CLOCKID, &sev, &timerid) == \-1) |
| errExit("timer_create"); |
| |
| printf("timer ID is %#jx\en", (uintmax_t) timerid); |
| |
| /* Start the timer. */ |
| |
| freq_nanosecs = atoll(argv[2]); |
| its.it_value.tv_sec = freq_nanosecs / 1000000000; |
| its.it_value.tv_nsec = freq_nanosecs % 1000000000; |
| its.it_interval.tv_sec = its.it_value.tv_sec; |
| its.it_interval.tv_nsec = its.it_value.tv_nsec; |
| |
| if (timer_settime(timerid, 0, &its, NULL) == \-1) |
| errExit("timer_settime"); |
| |
| /* Sleep for a while; meanwhile, the timer may expire |
| multiple times. */ |
| |
| printf("Sleeping for %d seconds\en", atoi(argv[1])); |
| sleep(atoi(argv[1])); |
| |
| /* Unlock the timer signal, so that timer notification |
| can be delivered. */ |
| |
| printf("Unblocking signal %d\en", SIG); |
| if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == \-1) |
| errExit("sigprocmask"); |
| |
| exit(EXIT_SUCCESS); |
| } |
| .EE |
| .SH SEE ALSO |
| .ad l |
| .nh |
| .BR clock_gettime (2), |
| .BR setitimer (2), |
| .BR timer_delete (2), |
| .BR timer_getoverrun (2), |
| .BR timer_settime (2), |
| .BR timerfd_create (2), |
| .BR clock_getcpuclockid (3), |
| .BR pthread_getcpuclockid (3), |
| .BR pthreads (7), |
| .BR sigevent (7), |
| .BR signal (7), |
| .BR time (7) |