diff options
| author | Alejandro Colomar <alx.manpages@gmail.com> | 2022-09-05 23:03:38 +0200 |
|---|---|---|
| committer | Alejandro Colomar <alx.manpages@gmail.com> | 2022-09-05 23:03:47 +0200 |
| commit | 70ac1c4785fc1e158ab2349a962dba2526bf4fbc (patch) | |
| tree | bff270e2496dd284bccfc1271b43946f5d225224 /man/man2/timer_create.2 | |
| parent | 5423a6f86b2b920a5f3e8cf8d759b513050f2d33 (diff) | |
| download | man-pages-70ac1c4785fc1e158ab2349a962dba2526bf4fbc.tar.gz | |
src.mk, All pages: Move man* to man/
The root of the repository is becoming a bit overpopulated and
unorganized, due to the recent addition of more mandirs, and more
informative and configuration files too. Let's create a specific
mandir <man/> that contains the mandirs <man[1-8]*>.
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Diffstat (limited to 'man/man2/timer_create.2')
| -rw-r--r-- | man/man2/timer_create.2 | 486 |
1 files changed, 486 insertions, 0 deletions
diff --git a/man/man2/timer_create.2 b/man/man2/timer_create.2 new file mode 100644 index 0000000000..a07528ba6c --- /dev/null +++ b/man/man2/timer_create.2 @@ -0,0 +1,486 @@ +.\" Copyright (c) 2009 Linux Foundation, written by Michael Kerrisk +.\" <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.TH TIMER_CREATE 2 2021-03-22 "Linux man-pages (unreleased)" +.SH NAME +timer_create \- create a POSIX per-process timer +.SH LIBRARY +Real-time library +.RI ( librt ", " \-lrt ) +.SH SYNOPSIS +.nf +.BR "#include <signal.h>" " /* Definition of " SIGEV_* " constants */" +.B #include <time.h> +.PP +.BI "int timer_create(clockid_t " clockid ", struct sigevent *restrict " sevp , +.BI " timer_t *restrict " timerid ); +.fi +.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 +.B CLOCK_MONOTONIC +clock does not measure the time while a system is suspended, the +.B CLOCK_BOOTTIME +clock does include the time during which the system is suspended. +This is useful for applications that need to be suspend-aware. +.B 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 +.B SIGEV_NONE +Don't asynchronously notify when the timer expires. +Progress of the timer can be monitored using +.BR timer_gettime (2). +.TP +.B 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 +.B 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 +.I 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 +.I 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 +.B CLOCK_REALTIME_ALARM +or +.B CLOCK_BOOTTIME_ALARM +but the caller did not have the +.B CAP_WAKE_ALARM +capability. +.SH VERSIONS +This system call is available since Linux 2.6. +.SH STANDARDS +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 +.B 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 +.B 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 +.B 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 +.B 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 +\& +.\" SRC BEGIN (timer_create.c) +.EX +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.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 +.\" SRC END +.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) |
