timerfd_create(2) System Calls Manual timerfd_create(2) NOM timerfd_create, timerfd_settime, timerfd_gettime - Minuteries qui informent par l'intermediaire de descripteurs de fichier BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include int timerfd_create(int clockid, int flags); int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *_Nullable old_value); int timerfd_gettime(int fd, struct itimerspec *curr_value); DESCRIPTION Ces appels systeme creent et operent sur une minuterie qui fournit des notifications d'expiration par un descripteur de fichier. Ils fournissent une alternative a setitimer(2) ou timer_create(2) avec l'avantage que le descripteur de fichier peut etre surveille avec select(2), poll(2) ou epoll(7). L'utilisation de ces trois appels systeme est analogue a l'utilisation de timer_create(2), timer_settime(2) et timer_gettime(2). (Il n'y a pas d'equivalent a timer_getoverrun(2) puisque cette fonctionnalite est fournie par read(2), comme decrit ci-dessous) timerfd_create() timerfd_create() cree un nouvel objet minuterie et renvoie un descripteur de fichier qui se refere a cette minuterie. Le parametre clockid indique l'horloge utilisee pour marquer la progression de la minuterie qui doit etre une des suivantes : CLOCK_REALTIME Une horloge temps reel configurable a l'echelle du systeme. CLOCK_MONOTONIC Une horloge non configurable, toujours croissante qui mesure le temps depuis un instant non specifie dans le passe et qui ne change pas apres le demarrage du systeme. CLOCK_BOOTTIME (depuis Linux 3.15) C'est une horloge toujours croissante comme CLOCK_MONOTONIC. Cependant alors que l'horloge CLOCK_MONOTONIC ne mesure pas le temps aussi longtemps que le systeme est suspendu, l'horloge CLOCK_BOOTTIME inclut le temps pendant lequel le systeme est suspendu. Cela est utile pour les applications qui doivent etre sensibles au temps de suspension. CLOCK_REALTIME n'est pas adapte a ce type d'application dans la mesure ou cette horloge est affectee par des modifications discontinues de l'horloge systeme. CLOCK_REALTIME_ALARM (depuis Linux 3.11) Cette horloge se comporte comme CLOCK_REALTIME, mais reveillera le systeme s'il est suspendu. L'appelant doit avoir la capacite CAP_WAKE_ALARM afin de regler une minuterie utilisant cette horloge. CLOCK_BOOTTIME_ALARM (depuis Linux 3.11) Cette horloge se comporte comme CLOCK_BOOTTIME, mais reveillera le systeme s'il est suspendu. L'appelant doit avoir la capacite CAP_WAKE_ALARM afin de regler une minuterie utilisant cette horloge. Consultez clock_getres(2) pour quelques details supplementaires sur les horloges mentionnees. La valeur actuelle de chacune de ces horloges peut etre obtenue avec clock_gettime(2). A partir de Linux 2.6.27, les valeurs suivantes peuvent etre incluses avec un OU binaire dans flags pour changer le comportement de timerfd_create() : TFD_NONBLOCK Placer l'attribut d'etat de fichier O_NONBLOCK sur la description du fichier ouvert referencee par le nouveau descripteur de fichier (consulter open(2)). Utiliser cet attribut economise des appels supplementaires a fcntl(2) pour obtenir le meme resultat. TFD_CLOEXEC Placer l'attribut << close-on-exec >> (FD_CLOEXEC) sur le nouveau descripteur de fichier. Consultez la description de l'attribut O_CLOEXEC dans open(2) pour savoir pourquoi cela peut etre utile. Dans les versions de Linux jusqu'a la version 2.6.26 incluse, flags doit etre nul. timerfd_settime() timerfd_settime() arme (demarre) ou desarme (stoppe) la minuterie a laquelle se refere le descripteur de fichier fd. Le parametre new_value specifie l'expiration initiale et l'intervalle de la minuterie. La structure itimerspec utilisee pour ce parametre est decrite dans itimerspec(3type) : new_value.it_value specifie l'expiration initiale de la minuterie, en secondes et nanosecondes. Une valeur non nulle dans un des champs de new_value.it_value arme la minuterie. La minuterie est desarmee si les deux champs de new_value.it_value sont mis a zero. Une valeur non nulle dans un des champs de new_value.it_interval configure la periode, en secondes et nanosecondes, pour une expiration repetitive apres l'expiration initiale. Si les deux champs de new_value.it_interval sont nuls, la minuterie expirera qu'une seule fois, dont l'heure est specifiee dans new_value.it_value. Par defaut, l'heure d'expiration initiale specifiee dans new_value est interpretee de facon relative par rapport a l'heure actuelle sur l'horloge de la minuterie au moment de l'appel (c'est-a-dire que new_value.it_value indique une heure relative a la valeur actuelle de l'horloge specifiee par clockid). Un delai absolu peut etre selectionne avec le parametre flags. Le parametre flags est un masque de bits qui peut avoir les valeurs suivantes : TFD_TIMER_ABSTIME Interpreter new_value.it_value comme une valeur absolue sur l'horloge de la minuterie. La minuterie expirera quand la valeur de l'horloge de la minuterie atteint la valeur specifiee dans new_value.it_value. TFD_TIMER_CANCEL_ON_SET Si cet attribut est specifie en meme temps que TFD_TIMER_ABSTIME et si l'horloge pour cette minuterie est CLOCK_REALTIME ou CLOCK_REALTIME_ALARM, alors marquer cette minuterie comme annulable si l'horloge en temps reel subit une modification discontinue (settimeofday(2), clock_settime(2) ou similaire). Quand des modifications se produisent, un appel actuel ou futur a read(2) a partir du descripteur de fichier echouera avec l'erreur ECANCELED. Si le parametre old_value n'est pas egal a NULL, la structure itimerspec vers laquelle il pointe est utilisee pour renvoyer la configuration de la minuterie au moment de l'appel ; consultez la description de timerfd_gettime() ci-dessous. timerfd_gettime() timerfd_gettime() renvoie, dans curr_value, une structure itimerspec qui contient les parametres actuels de la minuterie auquel le descripteur de fichier fd fait reference. Le champ it_value renvoie la duree jusqu'a la prochaine expiration. Si les deux champs de cette structure sont nuls, alors la minuterie est actuellement desactivee. Ce champ contient toujours une valeur relative, sans tenir compte d'un attribut TFD_TIMER_ABSTIME qui aurait ete specifie quand la minuterie a ete configuree. Le champ it_interval renvoie l'intervalle de la minuterie. Si les deux champs de cette structure sont nuls, alors la minuteries est configuree pour n'expirer qu'une seule fois, a l'heure specifiee par curr_value.it_value. Operations sur un descripteur de fichier de minuterie Le descripteur de fichier renvoye par timerfd_create() gere les operations supplementaires suivantes : read(2) Si la minuterie a deja expiree une fois ou plus depuis que sa configuration a ete modifiee la derniere fois a l'aide de timerfd_settime() ou depuis la derniere lecture avec read(2) qui a reussi, alors le tampon fourni a read(2) renvoie un entier non signe sur 8 octets (uint64_t) qui contient le nombre d'expirations qui se sont produites. (La valeur renvoyee utilise l'ordre des octets de l'hote, c'est-a-dire l'ordre des octets natif pour les entiers sur la machine hote.) Si aucune expiration ne s'est produite au moment de l'appel a read(2), l'appel bloquera jusqu'a la prochaine expiration ou echouera avec l'erreur EAGAIN si le descripteur de fichier est en mode non bloquant (a l'aide de de l'operation F_SETFL de fcntl(2) pour regler l'attribut O_NONBLOCK). Un read(2) echouera avec l'erreur EINVAL si la taille du tampon fourni est de moins de 8 octets. Si l'horloge associee est soit CLOCK_REALTIME ou CLOCK_REALTIME_ALARM, si la minuterie est absolue (TFD_TIMER_ABSTIME) et si l'attribut TFD_TIMER_CANCEL_ON_SET a ete specifie lors de l'appel timerfd_settime(), alors l'appel a read(2) echoue avec l'erreur ECANCELED si l'horloge en temps reel subit une modification discontinue. (Cela permet a l'application qui lit de decouvrir ce type de modifications discontinues a l'horloge.) Si l'horloge associee est soit CLOCK_REALTIME ou CLOCK_REALTIME_ALARM, si la minuterie est absolue (TFD_TIMER_ABSTIME) et si l'attribut TFD_TIMER_CANCEL_ON_SET a ete specifie lors de l'appel timerfd_settime(), alors une modification negative discontinue a l'horloge (par exemple, clock_settime(2)) peut faire a que read(2) supprime le blocage, mais renvoie une valeur de 0 (c'est-a-dire qu'aucun octet n'est lu), si une modification d'horloge survient apres que le temps soit expire, mais avant le read(2) sur le descripteur de fichier. poll(2) select(2) (et similaire) Le descripteur de fichier est lisible (le parametre readfds de select(2) ; l'attribut POLLIN de poll(2)) si une expiration (ou plus) de la minuterie s'est produite. Le descripteur de fichier prend egalement en charge les autres interfaces de multiplexage de descripteurs de fichier : pselect(2), ppoll(2) et epoll(7). ioctl(2) La commande suivante specifique a timerfd est prise en charge : TFD_IOC_SET_TICKS (depuis Linux 3.17) Ajuste le nombre d'expirations de minuterie qui sont survenues. Le parametre est un pointeur vers un entier de 8 octets different de zero (uint64_t*) contenant le nouveau nombre d'expirations. Une fois que le nombre est defini, tout processus en attente de la minuterie est reveille. Le seul objectif de cette commande est de retablir les expirations dans l'objectif de points de verification ou de restauration. Cette operation est disponible seulement si le noyau a ete configure avec l'option CONFIG_CHECKPOINT_RESTORE. close(2) Quand le descripteur de fichier n'est plus necessaire il doit etre ferme. Quand tous les descripteurs de fichier associes au meme objet minuterie ont ete fermes, la minuterie est desarmee et ses ressources sont liberees par le noyau. Semantique de fork(2) Apres un fork(2), l'enfant herite d'une copie du descripteur de fichier cree par timerfd_create(). Le descripteur de fichier se refere au meme objet minuterie sous-jacent que le descripteur de fichier correspondant dans le parent, et un read(2) de l'enfant renverra les informations sur les expirations de la minuterie. Semantique de execve(2) Un descripteur de fichier cree par timerfd_create() est conserve au travers d'un execve(2), et continue a generer des expirations de minuterie si la minuterie a ete armee. VALEUR RENVOYEE S'il reussit, timerfd_create() renvoie un nouveau descripteur de fichier. En cas d'erreur, il renvoie -1 et errno est defini pour indiquer l'erreur. En cas de reussite, timerfd_settime() et timerfd_gettime() renvoient 0. Sinon ils renvoient -1 et definissent errno pour indiquer l'erreur. ERREURS timerfd_create() peut echouer avec les erreurs suivantes : EINVAL Le clockid n'est pas valable. EINVAL flags n'est pas correct ; ou, pour les versions de Linux 2.6.26 ou anterieures, flags n'est pas nul. EMFILE La limite du nombre de descripteurs de fichiers par processus a ete atteinte. ENFILE La limite du nombre total de fichiers ouverts pour le systeme entier a ete atteinte. ENODEV Impossible de monter (en interne) le peripherique anonyme d'inoeud. ENOMEM Pas assez de memoire noyau pour creer la minuterie. EPERM clockid etait CLOCK_REALTIME_ALARM ou CLOCK_BOOTTIME_ALARM, mais l'appelant n'a pas la capacite CAP_WAKE_ALARM. timerfd_settime() et timerfd_gettime() peuvent echouer avec les erreurs suivantes : EBADF fd n'est pas un descripteur de fichier valable. EFAULT new_value, old_value ou curr_value n'est pas un pointeur valable. EINVAL fd n'est pas un descripteur de fichier de minuterie valable. timerfd_settime() peut aussi echouer avec les erreurs suivantes : ECANCELED Voir NOTES EINVAL new_value n'est pas initialise correctement (un des champs tv_nsec est en dehors de l'intervalle allant de 0 a 999 999 999). EINVAL flags n'est pas correct. STANDARDS Linux. HISTORIQUE Linux 2.6.25, glibc 2.8. NOTES En supposant le scenario suivant pour une minuterie CLOCK_REALTIME ou CLOCK_REALTIME_ALARM creee avec timerfd_create() : (1) la minuterie a ete demarree (timerfd_settime()) avec les attributs TFD_TIMER_ABSTIME et TFD_TIMER_CANCEL_ON_SET ; (2) une modification discontinue (par exemple, settimeofday(2)) est ensuite appliquee a l'horloge CLOCK_REALTIME ; (3) l'appelant appelle une fois de plus timerfd_settime() pour rearmer la minuterie (sans executer prealablement un read(2) sur le descripteur de fichier). Dans ce cas les evenements suivants se produisent : - timerfd_settime() renvoie -1 avec errno defini a ECANCELED. (Cela permet a l'appelant de savoir que la minuterie precedente a ete affectee par une modification discontinue de l'horloge.) - La minuterie est rearmee avec succes avec les reglages fournis dans le second appel timerfd_settime(). (C'est probablement un accident d'implementation, mais ne sera pas corrige maintenant au cas ou des applications dependent de ce comportement.) BOGUES Actuellement, timerfd_create() prend en charge moins de types d'identifiant d'horloges que timer_create(2). EXEMPLES Le programme suivant cree une minuterie puis surveille sa progression. Le programme accepte jusqu'a trois parametres en ligne de commande. Le premier parametre specifie le nombre de secondes pour l'expiration initiale de la minuterie. Le deuxieme parametre specifie l'intervallse de la minuterie, en secondes. Le troisieme parametre specifie le nombre de fois que le programme doit permettre a la minuterie d'expirer avant de quitter. Le deuxieme et le troisieme parametre sont optionnels. La session interactive suivante montre l'utilisation de ce programme : $ a.out 3 1 100 0.000: timer started 3.000: read: 1; total=1 4.000: read: 1; total=2 ^Z # entrer Ctrl-Z pour suspendre le programme [1]+ Stopped ./timerfd3_demo 3 1 100 $ fg # Reprendre l'execution apres quelques secondes a.out 3 1 100 9.660: read: 5; total=7 10.000: read: 1; total=8 11.000: read: 1; total=9 ^C # entrer Ctrl-C pour suspendre le programme Source du programme #include #include #include #include #include #include #include static void print_elapsed_time(void) { int secs, nsecs; static int first_call = 1; struct timespec curr; static struct timespec start; if (first_call) { first_call = 0; if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) err(EXIT_FAILURE, "clock_gettime"); } if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) err(EXIT_FAILURE, "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[]) { int fd; ssize_t s; uint64_t exp, tot_exp, max_exp; struct timespec now; struct itimerspec new_value; if (argc != 2 && argc != 4) { fprintf(stderr, "%s init-secs [interval-secs max-exp]\n", argv[0]); exit(EXIT_FAILURE); } if (clock_gettime(CLOCK_REALTIME, &now) == -1) err(EXIT_FAILURE, "clock_gettime"); /* Creer une minuterie absolue CLOCK_REALTIME avec une expiration et un intervalle initiaux comme specifie en ligne de commande. */ new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]); new_value.it_value.tv_nsec = now.tv_nsec; if (argc == 2) { new_value.it_interval.tv_sec = 0; max_exp = 1; } else { new_value.it_interval.tv_sec = atoi(argv[2]); max_exp = atoi(argv[3]); } new_value.it_interval.tv_nsec = 0; fd = timerfd_create(CLOCK_REALTIME, 0); if (fd == -1) err(EXIT_FAILURE, "timerfd_create"); if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1) err(EXIT_FAILURE, "timerfd_settime"); print_elapsed_time(); printf("timer started\n"); for (tot_exp = 0; tot_exp < max_exp;) { s = read(fd, &exp, sizeof(uint64_t)); if (s != sizeof(uint64_t)) err(EXIT_FAILURE, "read"); tot_exp += exp; print_elapsed_time(); printf("read: %" PRIu64 "; total=%" PRIu64 "\n", exp, tot_exp); } exit(EXIT_SUCCESS); } VOIR AUSSI eventfd(2), poll(2), read(2), select(2), setitimer(2), signalfd(2), timer_create(2), timer_gettime(2), timer_settime(2), timespec(3), epoll(7), time(7) TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot , Cedric Boutillier , Frederic Hantrais et Jean-Pierre Giraud Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 timerfd_create(2)