ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev.c
(Generate patch)

Comparing libev/ev.c (file contents):
Revision 1.522 by root, Tue Dec 31 06:02:28 2019 UTC vs.
Revision 1.536 by root, Wed Aug 10 16:50:05 2022 UTC

1/* 1/*
2 * libev event processing core, watcher management 2 * libev event processing core, watcher management
3 * 3 *
4 * Copyright (c) 2007-2019 Marc Alexander Lehmann <libev@schmorp.de> 4 * Copyright (c) 2007-2020 Marc Alexander Lehmann <libev@schmorp.de>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without modifica- 7 * Redistribution and use in source and binary forms, with or without modifica-
8 * tion, are permitted provided that the following conditions are met: 8 * tion, are permitted provided that the following conditions are met:
9 * 9 *
34 * by deleting the provisions above and replace them with the notice 34 * by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL. If you do not delete the 35 * and other provisions required by the GPL. If you do not delete the
36 * provisions above, a recipient may use your version of this file under 36 * provisions above, a recipient may use your version of this file under
37 * either the BSD or the GPL. 37 * either the BSD or the GPL.
38 */ 38 */
39
40#pragma clang diagnostic ignored "-Wunused-value"
41#pragma clang diagnostic ignored "-Wcomment"
42#pragma clang diagnostic ignored "-Wextern-initializer"
39 43
40/* this big block deduces configuration from config.h */ 44/* this big block deduces configuration from config.h */
41#ifndef EV_STANDALONE 45#ifndef EV_STANDALONE
42# ifdef EV_CONFIG_H 46# ifdef EV_CONFIG_H
43# include EV_CONFIG_H 47# include EV_CONFIG_H
491# endif 495# endif
492#endif 496#endif
493 497
494#if EV_USE_IOURING 498#if EV_USE_IOURING
495# include <sys/syscall.h> 499# include <sys/syscall.h>
496# if !SYS_io_uring_setup && __linux && !__alpha 500# if !SYS_io_uring_register && __linux && !__alpha
497# define SYS_io_uring_setup 425 501# define SYS_io_uring_setup 425
498# define SYS_io_uring_enter 426 502# define SYS_io_uring_enter 426
499# define SYS_io_uring_wregister 427 503# define SYS_io_uring_register 427
500# endif 504# endif
501# if SYS_io_uring_setup && EV_USE_EPOLL /* iouring backend requires epoll backend */ 505# if SYS_io_uring_setup && EV_USE_EPOLL /* iouring backend requires epoll backend */
502# define EV_NEED_SYSCALL 1 506# define EV_NEED_SYSCALL 1
503# else 507# else
504# undef EV_USE_IOURING 508# undef EV_USE_IOURING
579#define MIN_INTERVAL 0.0001220703125 /* 1/2**13, good till 4000 */ 583#define MIN_INTERVAL 0.0001220703125 /* 1/2**13, good till 4000 */
580/*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */ 584/*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */
581 585
582#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ 586#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
583#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ 587#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */
588#define MAX_BLOCKTIME2 1500001.07 /* same, but when timerfd is used to detect jumps, also safe delay to not overflow */
584 589
585/* find a portable timestamp that is "always" in the future but fits into time_t. 590/* find a portable timestamp that is "always" in the future but fits into time_t.
586 * this is quite hard, and we are mostly guessing - we handle 32 bit signed/unsigned time_t, 591 * this is quite hard, and we are mostly guessing - we handle 32 bit signed/unsigned time_t,
587 * and sizes larger than 32 bit, and maybe the unlikely floating point time_t */ 592 * and sizes larger than 32 bit, and maybe the unlikely floating point time_t */
588#define EV_TSTAMP_HUGE \ 593#define EV_TSTAMP_HUGE \
603/* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */ 608/* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */
604/* ECB.H BEGIN */ 609/* ECB.H BEGIN */
605/* 610/*
606 * libecb - http://software.schmorp.de/pkg/libecb 611 * libecb - http://software.schmorp.de/pkg/libecb
607 * 612 *
608 * Copyright (©) 2009-2015 Marc Alexander Lehmann <libecb@schmorp.de> 613 * Copyright (©) 2009-2015,2018-2020 Marc Alexander Lehmann <libecb@schmorp.de>
609 * Copyright (©) 2011 Emanuele Giaquinta 614 * Copyright (©) 2011 Emanuele Giaquinta
610 * All rights reserved. 615 * All rights reserved.
611 * 616 *
612 * Redistribution and use in source and binary forms, with or without modifica- 617 * Redistribution and use in source and binary forms, with or without modifica-
613 * tion, are permitted provided that the following conditions are met: 618 * tion, are permitted provided that the following conditions are met:
644 649
645#ifndef ECB_H 650#ifndef ECB_H
646#define ECB_H 651#define ECB_H
647 652
648/* 16 bits major, 16 bits minor */ 653/* 16 bits major, 16 bits minor */
649#define ECB_VERSION 0x00010006 654#define ECB_VERSION 0x00010008
650 655
651#ifdef _WIN32 656#include <string.h> /* for memcpy */
657
658#if defined (_WIN32) && !defined (__MINGW32__)
652 typedef signed char int8_t; 659 typedef signed char int8_t;
653 typedef unsigned char uint8_t; 660 typedef unsigned char uint8_t;
661 typedef signed char int_fast8_t;
662 typedef unsigned char uint_fast8_t;
654 typedef signed short int16_t; 663 typedef signed short int16_t;
655 typedef unsigned short uint16_t; 664 typedef unsigned short uint16_t;
665 typedef signed int int_fast16_t;
666 typedef unsigned int uint_fast16_t;
656 typedef signed int int32_t; 667 typedef signed int int32_t;
657 typedef unsigned int uint32_t; 668 typedef unsigned int uint32_t;
669 typedef signed int int_fast32_t;
670 typedef unsigned int uint_fast32_t;
658 #if __GNUC__ 671 #if __GNUC__
659 typedef signed long long int64_t; 672 typedef signed long long int64_t;
660 typedef unsigned long long uint64_t; 673 typedef unsigned long long uint64_t;
661 #else /* _MSC_VER || __BORLANDC__ */ 674 #else /* _MSC_VER || __BORLANDC__ */
662 typedef signed __int64 int64_t; 675 typedef signed __int64 int64_t;
663 typedef unsigned __int64 uint64_t; 676 typedef unsigned __int64 uint64_t;
664 #endif 677 #endif
678 typedef int64_t int_fast64_t;
679 typedef uint64_t uint_fast64_t;
665 #ifdef _WIN64 680 #ifdef _WIN64
666 #define ECB_PTRSIZE 8 681 #define ECB_PTRSIZE 8
667 typedef uint64_t uintptr_t; 682 typedef uint64_t uintptr_t;
668 typedef int64_t intptr_t; 683 typedef int64_t intptr_t;
669 #else 684 #else
680 #endif 695 #endif
681#endif 696#endif
682 697
683#define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__) 698#define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__)
684#define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64) 699#define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64)
700
701#ifndef ECB_OPTIMIZE_SIZE
702 #if __OPTIMIZE_SIZE__
703 #define ECB_OPTIMIZE_SIZE 1
704 #else
705 #define ECB_OPTIMIZE_SIZE 0
706 #endif
707#endif
685 708
686/* work around x32 idiocy by defining proper macros */ 709/* work around x32 idiocy by defining proper macros */
687#if ECB_GCC_AMD64 || ECB_MSVC_AMD64 710#if ECB_GCC_AMD64 || ECB_MSVC_AMD64
688 #if _ILP32 711 #if _ILP32
689 #define ECB_AMD64_X32 1 712 #define ECB_AMD64_X32 1
1196ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); } 1219ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
1197ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); } 1220ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
1198ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); } 1221ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
1199ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); } 1222ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
1200 1223
1224#if ECB_CPP
1225
1226inline uint8_t ecb_ctz (uint8_t v) { return ecb_ctz32 (v); }
1227inline uint16_t ecb_ctz (uint16_t v) { return ecb_ctz32 (v); }
1228inline uint32_t ecb_ctz (uint32_t v) { return ecb_ctz32 (v); }
1229inline uint64_t ecb_ctz (uint64_t v) { return ecb_ctz64 (v); }
1230
1231inline bool ecb_is_pot (uint8_t v) { return ecb_is_pot32 (v); }
1232inline bool ecb_is_pot (uint16_t v) { return ecb_is_pot32 (v); }
1233inline bool ecb_is_pot (uint32_t v) { return ecb_is_pot32 (v); }
1234inline bool ecb_is_pot (uint64_t v) { return ecb_is_pot64 (v); }
1235
1236inline int ecb_ld (uint8_t v) { return ecb_ld32 (v); }
1237inline int ecb_ld (uint16_t v) { return ecb_ld32 (v); }
1238inline int ecb_ld (uint32_t v) { return ecb_ld32 (v); }
1239inline int ecb_ld (uint64_t v) { return ecb_ld64 (v); }
1240
1241inline int ecb_popcount (uint8_t v) { return ecb_popcount32 (v); }
1242inline int ecb_popcount (uint16_t v) { return ecb_popcount32 (v); }
1243inline int ecb_popcount (uint32_t v) { return ecb_popcount32 (v); }
1244inline int ecb_popcount (uint64_t v) { return ecb_popcount64 (v); }
1245
1246inline uint8_t ecb_bitrev (uint8_t v) { return ecb_bitrev8 (v); }
1247inline uint16_t ecb_bitrev (uint16_t v) { return ecb_bitrev16 (v); }
1248inline uint32_t ecb_bitrev (uint32_t v) { return ecb_bitrev32 (v); }
1249
1250inline uint8_t ecb_rotl (uint8_t v, unsigned int count) { return ecb_rotl8 (v, count); }
1251inline uint16_t ecb_rotl (uint16_t v, unsigned int count) { return ecb_rotl16 (v, count); }
1252inline uint32_t ecb_rotl (uint32_t v, unsigned int count) { return ecb_rotl32 (v, count); }
1253inline uint64_t ecb_rotl (uint64_t v, unsigned int count) { return ecb_rotl64 (v, count); }
1254
1255inline uint8_t ecb_rotr (uint8_t v, unsigned int count) { return ecb_rotr8 (v, count); }
1256inline uint16_t ecb_rotr (uint16_t v, unsigned int count) { return ecb_rotr16 (v, count); }
1257inline uint32_t ecb_rotr (uint32_t v, unsigned int count) { return ecb_rotr32 (v, count); }
1258inline uint64_t ecb_rotr (uint64_t v, unsigned int count) { return ecb_rotr64 (v, count); }
1259
1260#endif
1261
1201#if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64)) 1262#if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64))
1202 #if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16) 1263 #if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16)
1203 #define ecb_bswap16(x) __builtin_bswap16 (x) 1264 #define ecb_bswap16(x) __builtin_bswap16 (x)
1204 #else 1265 #else
1205 #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16) 1266 #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
1276ecb_inline ecb_const ecb_bool ecb_big_endian (void); 1337ecb_inline ecb_const ecb_bool ecb_big_endian (void);
1277ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11223344; } 1338ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11223344; }
1278ecb_inline ecb_const ecb_bool ecb_little_endian (void); 1339ecb_inline ecb_const ecb_bool ecb_little_endian (void);
1279ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; } 1340ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; }
1280 1341
1342/*****************************************************************************/
1343/* unaligned load/store */
1344
1345ecb_inline uint_fast16_t ecb_be_u16_to_host (uint_fast16_t v) { return ecb_little_endian () ? ecb_bswap16 (v) : v; }
1346ecb_inline uint_fast32_t ecb_be_u32_to_host (uint_fast32_t v) { return ecb_little_endian () ? ecb_bswap32 (v) : v; }
1347ecb_inline uint_fast64_t ecb_be_u64_to_host (uint_fast64_t v) { return ecb_little_endian () ? ecb_bswap64 (v) : v; }
1348
1349ecb_inline uint_fast16_t ecb_le_u16_to_host (uint_fast16_t v) { return ecb_big_endian () ? ecb_bswap16 (v) : v; }
1350ecb_inline uint_fast32_t ecb_le_u32_to_host (uint_fast32_t v) { return ecb_big_endian () ? ecb_bswap32 (v) : v; }
1351ecb_inline uint_fast64_t ecb_le_u64_to_host (uint_fast64_t v) { return ecb_big_endian () ? ecb_bswap64 (v) : v; }
1352
1353ecb_inline uint_fast16_t ecb_peek_u16_u (const void *ptr) { uint16_t v; memcpy (&v, ptr, sizeof (v)); return v; }
1354ecb_inline uint_fast32_t ecb_peek_u32_u (const void *ptr) { uint32_t v; memcpy (&v, ptr, sizeof (v)); return v; }
1355ecb_inline uint_fast64_t ecb_peek_u64_u (const void *ptr) { uint64_t v; memcpy (&v, ptr, sizeof (v)); return v; }
1356
1357ecb_inline uint_fast16_t ecb_peek_be_u16_u (const void *ptr) { return ecb_be_u16_to_host (ecb_peek_u16_u (ptr)); }
1358ecb_inline uint_fast32_t ecb_peek_be_u32_u (const void *ptr) { return ecb_be_u32_to_host (ecb_peek_u32_u (ptr)); }
1359ecb_inline uint_fast64_t ecb_peek_be_u64_u (const void *ptr) { return ecb_be_u64_to_host (ecb_peek_u64_u (ptr)); }
1360
1361ecb_inline uint_fast16_t ecb_peek_le_u16_u (const void *ptr) { return ecb_le_u16_to_host (ecb_peek_u16_u (ptr)); }
1362ecb_inline uint_fast32_t ecb_peek_le_u32_u (const void *ptr) { return ecb_le_u32_to_host (ecb_peek_u32_u (ptr)); }
1363ecb_inline uint_fast64_t ecb_peek_le_u64_u (const void *ptr) { return ecb_le_u64_to_host (ecb_peek_u64_u (ptr)); }
1364
1365ecb_inline uint_fast16_t ecb_host_to_be_u16 (uint_fast16_t v) { return ecb_little_endian () ? ecb_bswap16 (v) : v; }
1366ecb_inline uint_fast32_t ecb_host_to_be_u32 (uint_fast32_t v) { return ecb_little_endian () ? ecb_bswap32 (v) : v; }
1367ecb_inline uint_fast64_t ecb_host_to_be_u64 (uint_fast64_t v) { return ecb_little_endian () ? ecb_bswap64 (v) : v; }
1368
1369ecb_inline uint_fast16_t ecb_host_to_le_u16 (uint_fast16_t v) { return ecb_big_endian () ? ecb_bswap16 (v) : v; }
1370ecb_inline uint_fast32_t ecb_host_to_le_u32 (uint_fast32_t v) { return ecb_big_endian () ? ecb_bswap32 (v) : v; }
1371ecb_inline uint_fast64_t ecb_host_to_le_u64 (uint_fast64_t v) { return ecb_big_endian () ? ecb_bswap64 (v) : v; }
1372
1373ecb_inline void ecb_poke_u16_u (void *ptr, uint16_t v) { memcpy (ptr, &v, sizeof (v)); }
1374ecb_inline void ecb_poke_u32_u (void *ptr, uint32_t v) { memcpy (ptr, &v, sizeof (v)); }
1375ecb_inline void ecb_poke_u64_u (void *ptr, uint64_t v) { memcpy (ptr, &v, sizeof (v)); }
1376
1377ecb_inline void ecb_poke_be_u16_u (void *ptr, uint_fast16_t v) { ecb_poke_u16_u (ptr, ecb_host_to_be_u16 (v)); }
1378ecb_inline void ecb_poke_be_u32_u (void *ptr, uint_fast32_t v) { ecb_poke_u32_u (ptr, ecb_host_to_be_u32 (v)); }
1379ecb_inline void ecb_poke_be_u64_u (void *ptr, uint_fast64_t v) { ecb_poke_u64_u (ptr, ecb_host_to_be_u64 (v)); }
1380
1381ecb_inline void ecb_poke_le_u16_u (void *ptr, uint_fast16_t v) { ecb_poke_u16_u (ptr, ecb_host_to_le_u16 (v)); }
1382ecb_inline void ecb_poke_le_u32_u (void *ptr, uint_fast32_t v) { ecb_poke_u32_u (ptr, ecb_host_to_le_u32 (v)); }
1383ecb_inline void ecb_poke_le_u64_u (void *ptr, uint_fast64_t v) { ecb_poke_u64_u (ptr, ecb_host_to_le_u64 (v)); }
1384
1385#if ECB_CPP
1386
1387inline uint8_t ecb_bswap (uint8_t v) { return v; }
1388inline uint16_t ecb_bswap (uint16_t v) { return ecb_bswap16 (v); }
1389inline uint32_t ecb_bswap (uint32_t v) { return ecb_bswap32 (v); }
1390inline uint64_t ecb_bswap (uint64_t v) { return ecb_bswap64 (v); }
1391
1392template<typename T> inline T ecb_be_to_host (T v) { return ecb_little_endian () ? ecb_bswap (v) : v; }
1393template<typename T> inline T ecb_le_to_host (T v) { return ecb_big_endian () ? ecb_bswap (v) : v; }
1394template<typename T> inline T ecb_peek (const void *ptr) { return *(const T *)ptr; }
1395template<typename T> inline T ecb_peek_be (const void *ptr) { return ecb_be_to_host (ecb_peek <T> (ptr)); }
1396template<typename T> inline T ecb_peek_le (const void *ptr) { return ecb_le_to_host (ecb_peek <T> (ptr)); }
1397template<typename T> inline T ecb_peek_u (const void *ptr) { T v; memcpy (&v, ptr, sizeof (v)); return v; }
1398template<typename T> inline T ecb_peek_be_u (const void *ptr) { return ecb_be_to_host (ecb_peek_u<T> (ptr)); }
1399template<typename T> inline T ecb_peek_le_u (const void *ptr) { return ecb_le_to_host (ecb_peek_u<T> (ptr)); }
1400
1401template<typename T> inline T ecb_host_to_be (T v) { return ecb_little_endian () ? ecb_bswap (v) : v; }
1402template<typename T> inline T ecb_host_to_le (T v) { return ecb_big_endian () ? ecb_bswap (v) : v; }
1403template<typename T> inline void ecb_poke (void *ptr, T v) { *(T *)ptr = v; }
1404template<typename T> inline void ecb_poke_be (void *ptr, T v) { return ecb_poke <T> (ptr, ecb_host_to_be (v)); }
1405template<typename T> inline void ecb_poke_le (void *ptr, T v) { return ecb_poke <T> (ptr, ecb_host_to_le (v)); }
1406template<typename T> inline void ecb_poke_u (void *ptr, T v) { memcpy (ptr, &v, sizeof (v)); }
1407template<typename T> inline void ecb_poke_be_u (void *ptr, T v) { return ecb_poke_u<T> (ptr, ecb_host_to_be (v)); }
1408template<typename T> inline void ecb_poke_le_u (void *ptr, T v) { return ecb_poke_u<T> (ptr, ecb_host_to_le (v)); }
1409
1410#endif
1411
1412/*****************************************************************************/
1413
1281#if ECB_GCC_VERSION(3,0) || ECB_C99 1414#if ECB_GCC_VERSION(3,0) || ECB_C99
1282 #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) 1415 #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
1283#else 1416#else
1284 #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n))) 1417 #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
1285#endif 1418#endif
1308 return N; 1441 return N;
1309 } 1442 }
1310#else 1443#else
1311 #define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) 1444 #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
1312#endif 1445#endif
1446
1447/*****************************************************************************/
1313 1448
1314ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x); 1449ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x);
1315ecb_function_ ecb_const uint32_t 1450ecb_function_ ecb_const uint32_t
1316ecb_binary16_to_binary32 (uint32_t x) 1451ecb_binary16_to_binary32 (uint32_t x)
1317{ 1452{
1426 || defined __sh__ \ 1561 || defined __sh__ \
1427 || defined _M_IX86 || defined ECB_MSVC_AMD64 || defined _M_IA64 \ 1562 || defined _M_IX86 || defined ECB_MSVC_AMD64 || defined _M_IA64 \
1428 || (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \ 1563 || (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \
1429 || defined __aarch64__ 1564 || defined __aarch64__
1430 #define ECB_STDFP 1 1565 #define ECB_STDFP 1
1431 #include <string.h> /* for memcpy */
1432#else 1566#else
1433 #define ECB_STDFP 0 1567 #define ECB_STDFP 0
1434#endif 1568#endif
1435 1569
1436#ifndef ECB_NO_LIBM 1570#ifndef ECB_NO_LIBM
2264{ 2398{
2265 int i; 2399 int i;
2266 2400
2267 /* most backends do not modify the fdchanges list in backend_modfiy. 2401 /* most backends do not modify the fdchanges list in backend_modfiy.
2268 * except io_uring, which has fixed-size buffers which might force us 2402 * except io_uring, which has fixed-size buffers which might force us
2269 * to handle events in backend_modify, causing fdchangesd to be amended, 2403 * to handle events in backend_modify, causing fdchanges to be amended,
2270 * which could result in an endless loop. 2404 * which could result in an endless loop.
2271 * to avoid this, we do not dynamically handle fds that were added 2405 * to avoid this, we do not dynamically handle fds that were added
2272 * during fd_reify. that menas thast for those backends, fdchangecnt 2406 * during fd_reify. that means that for those backends, fdchangecnt
2273 * might be non-zero during poll, which must cause them to not block. 2407 * might be non-zero during poll, which must cause them to not block.
2274 * to not put too much of a burden on other backends, this detail 2408 * to not put too much of a burden on other backends, this detail
2275 * needs to be handled in the backend. 2409 * needs to be handled in the backend.
2276 */ 2410 */
2277 int changecnt = fdchangecnt; 2411 int changecnt = fdchangecnt;
2341inline_size 2475inline_size
2342void 2476void
2343fd_change (EV_P_ int fd, int flags) 2477fd_change (EV_P_ int fd, int flags)
2344{ 2478{
2345 unsigned char reify = anfds [fd].reify; 2479 unsigned char reify = anfds [fd].reify;
2346 anfds [fd].reify |= flags; 2480 anfds [fd].reify = reify | flags;
2347 2481
2348 if (ecb_expect_true (!reify)) 2482 if (ecb_expect_true (!reify))
2349 { 2483 {
2350 ++fdchangecnt; 2484 ++fdchangecnt;
2351 array_needsize (int, fdchanges, fdchangemax, fdchangecnt, array_needsize_noinit); 2485 array_needsize (int, fdchanges, fdchangemax, fdchangecnt, array_needsize_noinit);
2903static void 3037static void
2904timerfdcb (EV_P_ ev_io *iow, int revents) 3038timerfdcb (EV_P_ ev_io *iow, int revents)
2905{ 3039{
2906 struct itimerspec its = { 0 }; 3040 struct itimerspec its = { 0 };
2907 3041
2908 /* since we can't easily come zup with a (portable) maximum value of time_t, 3042 its.it_value.tv_sec = ev_rt_now + (int)MAX_BLOCKTIME2;
2909 * we wake up once per month, which hopefully is rare enough to not
2910 * be a problem. */
2911 its.it_value.tv_sec = ev_rt_now + 86400 * 30;
2912 timerfd_settime (timerfd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &its, 0); 3043 timerfd_settime (timerfd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &its, 0);
2913 3044
2914 ev_rt_now = ev_time (); 3045 ev_rt_now = ev_time ();
2915 /* periodics_reschedule only needs ev_rt_now */ 3046 /* periodics_reschedule only needs ev_rt_now */
2916 /* but maybe in the future we want the full treatment. */ 3047 /* but maybe in the future we want the full treatment. */
2917 /* 3048 /*
2918 now_floor = EV_TS_CONST (0.); 3049 now_floor = EV_TS_CONST (0.);
2919 time_update (EV_A_ EV_TSTAMP_HUGE); 3050 time_update (EV_A_ EV_TSTAMP_HUGE);
2920 */ 3051 */
3052#if EV_PERIODIC_ENABLE
2921 periodics_reschedule (EV_A); 3053 periodics_reschedule (EV_A);
3054#endif
2922} 3055}
2923 3056
2924ecb_noinline ecb_cold 3057ecb_noinline ecb_cold
2925static void 3058static void
2926evtimerfd_init (EV_P) 3059evtimerfd_init (EV_P)
3036 3169
3037 /* TODO: linuxaio is very experimental */ 3170 /* TODO: linuxaio is very experimental */
3038#if !EV_RECOMMEND_LINUXAIO 3171#if !EV_RECOMMEND_LINUXAIO
3039 flags &= ~EVBACKEND_LINUXAIO; 3172 flags &= ~EVBACKEND_LINUXAIO;
3040#endif 3173#endif
3041 /* TODO: linuxaio is super experimental */ 3174 /* TODO: iouring is super experimental */
3042#if !EV_RECOMMEND_IOURING 3175#if !EV_RECOMMEND_IOURING
3043 flags &= ~EVBACKEND_IOURING; 3176 flags &= ~EVBACKEND_IOURING;
3044#endif 3177#endif
3045 3178
3046 return flags; 3179 return flags;
3963 4096
3964 if (ecb_expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) 4097 if (ecb_expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped)))
3965 { 4098 {
3966 waittime = EV_TS_CONST (MAX_BLOCKTIME); 4099 waittime = EV_TS_CONST (MAX_BLOCKTIME);
3967 4100
4101#if EV_USE_MONOTONIC
4102 if (ecb_expect_true (have_monotonic))
4103 {
4104#if EV_USE_TIMERFD
4105 /* sleep a lot longer when we can reliably detect timejumps */
4106 if (ecb_expect_true (timerfd != -1))
4107 waittime = EV_TS_CONST (MAX_BLOCKTIME2);
4108#endif
4109#if !EV_PERIODIC_ENABLE
4110 /* without periodics but with monotonic clock there is no need */
4111 /* for any time jump detection, so sleep longer */
4112 waittime = EV_TS_CONST (MAX_BLOCKTIME2);
4113#endif
4114 }
4115#endif
4116
3968 if (timercnt) 4117 if (timercnt)
3969 { 4118 {
3970 ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now; 4119 ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now;
3971 if (waittime > to) waittime = to; 4120 if (waittime > to) waittime = to;
3972 } 4121 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines