diff --git a/CMakeLists.txt b/CMakeLists.txt index 010d74fc708..1ab790ffb8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ set(CMAKE_CXX_STANDARD ) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_SCAN_FOR_MODULES ON) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE -DATS_BUILD) diff --git a/include/iocore/eventsystem/EThread.h b/include/iocore/eventsystem/EThread.h index 9b6f64bfed0..f6a656a2cea 100644 --- a/include/iocore/eventsystem/EThread.h +++ b/include/iocore/eventsystem/EThread.h @@ -34,6 +34,8 @@ #include "iocore/eventsystem/ProtectedQueue.h" #include "tsutil/Histogram.h" +import tscore; + #if TS_USE_HWLOC struct hwloc_obj; using hwloc_obj_t = hwloc_obj *; diff --git a/include/iocore/eventsystem/Event.h b/include/iocore/eventsystem/Event.h index aef3db53aed..46e0906df0f 100644 --- a/include/iocore/eventsystem/Event.h +++ b/include/iocore/eventsystem/Event.h @@ -26,6 +26,8 @@ #include "iocore/eventsystem/Action.h" +import tscore; + // // Defines // diff --git a/include/iocore/eventsystem/EventProcessor.h b/include/iocore/eventsystem/EventProcessor.h index 82c4f2682a0..ddd7782003b 100644 --- a/include/iocore/eventsystem/EventProcessor.h +++ b/include/iocore/eventsystem/EventProcessor.h @@ -28,6 +28,8 @@ #include "iocore/eventsystem/Event.h" #include +import tscore; + #ifdef TS_MAX_THREADS_IN_EACH_THREAD_TYPE constexpr int MAX_THREADS_IN_EACH_TYPE = TS_MAX_THREADS_IN_EACH_THREAD_TYPE; #else diff --git a/include/iocore/eventsystem/Freer.h b/include/iocore/eventsystem/Freer.h index 51738e036a3..cad70cd3cd5 100644 --- a/include/iocore/eventsystem/Freer.h +++ b/include/iocore/eventsystem/Freer.h @@ -27,6 +27,8 @@ #include "tscore/ink_platform.h" #include "iocore/eventsystem/Tasks.h" +import tscore; + // Note that these should not be used for memory that wishes to retain // NUMA socket affinity. We'll potentially return these on an arbitrarily // selected processor/socket. diff --git a/include/iocore/eventsystem/Lock.h b/include/iocore/eventsystem/Lock.h index 031ee9ef1a4..da90afff9d5 100644 --- a/include/iocore/eventsystem/Lock.h +++ b/include/iocore/eventsystem/Lock.h @@ -27,6 +27,8 @@ #include "tscore/Diags.h" #include "iocore/eventsystem/Thread.h" +import tscore; + #define MAX_LOCK_TIME HRTIME_MSECONDS(200) #define THREAD_MUTEX_THREAD_HOLDING (-1024 * 1024) diff --git a/include/iocore/eventsystem/PriorityEventQueue.h b/include/iocore/eventsystem/PriorityEventQueue.h index 38ecdd5a075..617790510fa 100644 --- a/include/iocore/eventsystem/PriorityEventQueue.h +++ b/include/iocore/eventsystem/PriorityEventQueue.h @@ -26,6 +26,8 @@ #include "tscore/ink_platform.h" #include "iocore/eventsystem/Event.h" +import tscore; + // <5ms, 10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120 #define N_PQ_LIST 10 #define PQ_BUCKET_TIME(_i) (HRTIME_MSECONDS(5) << (_i)) @@ -115,7 +117,7 @@ struct PriorityEventQueue { return last_check_time + (PQ_BUCKET_TIME(i) / 2); } } - return last_check_time + HRTIME_FOREVER; + return last_check_time + HRTIME_FOREVERS(1); } PriorityEventQueue(); diff --git a/include/iocore/eventsystem/ProtectedQueue.h b/include/iocore/eventsystem/ProtectedQueue.h index bc1b3b2577b..31da2ced3c2 100644 --- a/include/iocore/eventsystem/ProtectedQueue.h +++ b/include/iocore/eventsystem/ProtectedQueue.h @@ -36,6 +36,9 @@ #include "tscore/ink_platform.h" #include "iocore/eventsystem/Event.h" + +import tscore; + struct ProtectedQueue { void enqueue(Event *e); void signal(); diff --git a/include/iocore/io_uring/IO_URING.h b/include/iocore/io_uring/IO_URING.h index c35d3c168a9..1bf1c547bb9 100644 --- a/include/iocore/io_uring/IO_URING.h +++ b/include/iocore/io_uring/IO_URING.h @@ -24,73 +24,9 @@ Linux io_uring helper library #pragma once #include -#include -#include "tscore/ink_hrtime.h" - -struct IOUringConfig { - int queue_entries = 32; - int sq_poll_ms = 0; - int attach_wq = 0; - int wq_bounded = 0; - int wq_unbounded = 0; -}; class IOUringCompletionHandler { public: virtual void handle_complete(io_uring_cqe *) = 0; }; - -class IOUringContext -{ -public: - IOUringContext(); - ~IOUringContext(); - - IOUringContext(const IOUringContext &) = delete; - - io_uring_sqe * - next_sqe(IOUringCompletionHandler *handler) - { - io_uring_sqe *result = io_uring_get_sqe(&ring); - if (result == nullptr) { - submit(); - result = io_uring_get_sqe(&ring); - } - if (result != nullptr) { - io_uring_sqe_set_data(result, handler); - } - return result; - } - - bool supports_op(int op) const; - - int set_wq_max_workers(unsigned int bounded, unsigned int unbounded); - std::pair get_wq_max_workers(); - - void submit(); - void service(); - void submit_and_wait(ink_hrtime ms); - - int register_eventfd(); - - // assigns the global iouring config - static void set_config(const IOUringConfig &); - static IOUringContext *local_context(); - static void set_main_queue(IOUringContext *); - static int get_main_queue_fd(); - - bool - valid() - { - return ring.ring_fd > 0; - } - -private: - io_uring ring = {}; - io_uring_probe *probe = nullptr; - int evfd = -1; - - void handle_cqe(io_uring_cqe *); - static IOUringConfig config; -}; diff --git a/include/iocore/net/NetTimeout.h b/include/iocore/net/NetTimeout.h index 8fefd578a5c..cc504e1de57 100644 --- a/include/iocore/net/NetTimeout.h +++ b/include/iocore/net/NetTimeout.h @@ -24,10 +24,11 @@ #pragma once #include "tscore/List.h" -#include "tscore/ink_hrtime.h" #include "iocore/eventsystem/EventSystem.h" +import tscore; + /** NetTimeout - handle active & inactive timeout */ diff --git a/include/iocore/net/TLSBasicSupport.h b/include/iocore/net/TLSBasicSupport.h index a0b17bae3d9..8f509504478 100644 --- a/include/iocore/net/TLSBasicSupport.h +++ b/include/iocore/net/TLSBasicSupport.h @@ -28,9 +28,10 @@ #include -#include "tscore/ink_hrtime.h" #include "iocore/net/SSLTypes.h" +import tscore; + using TLSHandle = SSL *; class TLSBasicSupport diff --git a/include/iocore/net/quic/QUICTypes.h b/include/iocore/net/quic/QUICTypes.h index 7517db2f33b..4395b19e7bd 100644 --- a/include/iocore/net/quic/QUICTypes.h +++ b/include/iocore/net/quic/QUICTypes.h @@ -24,7 +24,6 @@ #pragma once #include "iocore/net/NetVConnection.h" -#include "tscore/ink_hrtime.h" #include "tscore/ink_inet.h" #include @@ -35,6 +34,8 @@ #include #include +import tscore; + using QUICPacketNumber = uint64_t; using QUICVersion = uint32_t; using QUICStreamId = uint64_t; diff --git a/include/proxy/CacheControl.h b/include/proxy/CacheControl.h index fcd789634b3..cdad2faf789 100644 --- a/include/proxy/CacheControl.h +++ b/include/proxy/CacheControl.h @@ -38,11 +38,11 @@ struct RequestData; const int CC_UNSET_TIME = -1; -#define CACHE_CONTROL_TIMEOUT (HRTIME_HOUR * 1) +#define CACHE_CONTROL_TIMEOUT (HRTIME_HOURS(1)) // Use 10 second time for purify testing under low // load to verify memory allocation -// #define CACHE_CONTROL_TIMEOUT (HRTIME_SECOND*10) +// #define CACHE_CONTROL_TIMEOUT (HRTIME_SECONDS(10)) enum class CacheControlType { INVALID = 0, diff --git a/include/proxy/Milestones.h b/include/proxy/Milestones.h index 622b5738ae8..0677852b95b 100644 --- a/include/proxy/Milestones.h +++ b/include/proxy/Milestones.h @@ -24,10 +24,11 @@ #pragma once #include "ts/apidefs.h" -#include "tscore/ink_hrtime.h" #include +import tscore; + template class Milestones { public: diff --git a/include/proxy/PluginVC.h b/include/proxy/PluginVC.h index bfa8b1aa5b8..98985cbcb36 100644 --- a/include/proxy/PluginVC.h +++ b/include/proxy/PluginVC.h @@ -39,6 +39,8 @@ #include "iocore/net/NetVConnection.h" #include "tscore/ink_atomic.h" +import tscore; + class PluginVCCore; struct PluginVCState { diff --git a/include/proxy/ProxySession.h b/include/proxy/ProxySession.h index d3267045de6..d134807dcb1 100644 --- a/include/proxy/ProxySession.h +++ b/include/proxy/ProxySession.h @@ -33,6 +33,8 @@ #include "proxy/IPAllow.h" #include "tscore/SnowflakeID.h" +import tscore; + // Emit a debug message conditional on whether this particular client session // has debugging enabled. This should only be called from within a client session // member function. diff --git a/include/proxy/ProxyTransaction.h b/include/proxy/ProxyTransaction.h index b7be3d3ae31..6376d0bcb4e 100644 --- a/include/proxy/ProxyTransaction.h +++ b/include/proxy/ProxyTransaction.h @@ -26,6 +26,8 @@ #include "proxy/ProxySession.h" #include +import tscore; + class HttpSM; // Abstract Class for any transaction with-in the HttpSM diff --git a/include/proxy/http/HttpCacheSM.h b/include/proxy/http/HttpCacheSM.h index 41623103d65..567aa1c26ec 100644 --- a/include/proxy/http/HttpCacheSM.h +++ b/include/proxy/http/HttpCacheSM.h @@ -38,6 +38,8 @@ #include "proxy/hdrs/HTTP.h" #include "proxy/http/HttpConfig.h" +import tscore; + class HttpSM; class HttpCacheSM; diff --git a/include/proxy/http/HttpSM.h b/include/proxy/http/HttpSM.h index aad4a30cc6d..2b48fbf2aa1 100644 --- a/include/proxy/http/HttpSM.h +++ b/include/proxy/http/HttpSM.h @@ -53,6 +53,8 @@ #include "tscore/History.h" #include "tscore/PendingAction.h" +import tscore; + #define HTTP_API_CONTINUE (INK_API_EVENT_EVENTS_START + 0) #define HTTP_API_ERROR (INK_API_EVENT_EVENTS_START + 1) diff --git a/include/proxy/http/HttpTransact.h b/include/proxy/http/HttpTransact.h index 66e53a889d1..b9f387715be 100644 --- a/include/proxy/http/HttpTransact.h +++ b/include/proxy/http/HttpTransact.h @@ -51,6 +51,8 @@ #include #include +import tscore; + #define HTTP_OUR_VIA_MAX_LENGTH 1024 // 512-bytes for hostname+via string, 512-bytes for the debug info #define HTTP_RELEASE_ASSERT(X) ink_release_assert(X) diff --git a/include/proxy/http/HttpTunnel.h b/include/proxy/http/HttpTunnel.h index 961c3f6cdfa..3ef891685a5 100644 --- a/include/proxy/http/HttpTunnel.h +++ b/include/proxy/http/HttpTunnel.h @@ -34,6 +34,8 @@ #include "iocore/eventsystem/EventSystem.h" +import tscore; + // Get rid of any previous definition first... /leif #ifdef MAX_PRODUCERS #undef MAX_PRODUCERS diff --git a/include/proxy/http/PreWarmManager.h b/include/proxy/http/PreWarmManager.h index 3b2d453f650..df2bc054ceb 100644 --- a/include/proxy/http/PreWarmManager.h +++ b/include/proxy/http/PreWarmManager.h @@ -43,7 +43,6 @@ using ts::Metrics; // tscore #include "tscore/CryptoHash.h" -#include "tscore/ink_hrtime.h" #include #include @@ -54,6 +53,8 @@ using ts::Metrics; #include #include +import tscore; + // PreWarm::Dst and PreWarm::SPtrConstDst are defined in iocore. namespace PreWarm { diff --git a/include/proxy/http2/Http2CommonSession.h b/include/proxy/http2/Http2CommonSession.h index cb61107fe9c..9cf42cae5ba 100644 --- a/include/proxy/http2/Http2CommonSession.h +++ b/include/proxy/http2/Http2CommonSession.h @@ -30,6 +30,8 @@ #include "proxy/http2/Http2ConnectionState.h" #include "proxy/http2/Http2Frame.h" +import tscore; + // Name Edata Description // HTTP2_SESSION_EVENT_INIT Http2CommonSession * HTTP/2 session is born // HTTP2_SESSION_EVENT_FINI Http2CommonSession * HTTP/2 session is ended diff --git a/include/proxy/http2/Http2ConnectionState.h b/include/proxy/http2/Http2ConnectionState.h index 53054416d9e..2e55feaba91 100644 --- a/include/proxy/http2/Http2ConnectionState.h +++ b/include/proxy/http2/Http2ConnectionState.h @@ -32,7 +32,8 @@ #include "proxy/http2/HPACK.h" #include "proxy/http2/Http2Stream.h" #include "proxy/http2/Http2DependencyTree.h" -#include "tscore/FrequencyCounter.h" + +import tscore; class Http2CommonSession; class Http2Frame; diff --git a/include/proxy/http2/Http2Stream.h b/include/proxy/http2/Http2Stream.h index cb3f15505cb..56a7f59e032 100644 --- a/include/proxy/http2/Http2Stream.h +++ b/include/proxy/http2/Http2Stream.h @@ -32,6 +32,8 @@ #include "tscore/History.h" #include "proxy/Milestones.h" +import tscore; + class Http2Stream; class Http2ConnectionState; diff --git a/include/proxy/http3/Http3Transaction.h b/include/proxy/http3/Http3Transaction.h index 1b0eb48806c..56dac952e49 100644 --- a/include/proxy/http3/Http3Transaction.h +++ b/include/proxy/http3/Http3Transaction.h @@ -29,6 +29,8 @@ #include "proxy/http3/Http3FrameDispatcher.h" #include "proxy/http3/Http3FrameCollector.h" +import tscore; + class QUICStreamIO; class HQSession; class Http09Session; diff --git a/include/tscore/FrequencyCounter.h b/include/tscore/FrequencyCounter.h deleted file mode 100644 index f710096b416..00000000000 --- a/include/tscore/FrequencyCounter.h +++ /dev/null @@ -1,42 +0,0 @@ -/** @file - - FrequencyCounter - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -#pragma once - -#include -#include - -class FrequencyCounter -{ -public: - void increment(uint16_t amount = 1); - uint32_t get_count(); - virtual ~FrequencyCounter() {} - -protected: - uint16_t _count[2] = {0}; - ink_hrtime _last_update = 0; - -private: - virtual ink_hrtime _ink_get_hrtime(); -}; diff --git a/include/tscore/ink_hrtime.h b/include/tscore/ink_hrtime.h deleted file mode 100644 index bf12268b041..00000000000 --- a/include/tscore/ink_hrtime.h +++ /dev/null @@ -1,278 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/************************************************************************** - - ink_hrtime.h - - This file contains code supporting the Inktomi high-resolution timer. -**************************************************************************/ - -#pragma once - -#include "tscore/ink_config.h" -#include "tscore/ink_assert.h" -#include -#include -#include -#include -using ink_hrtime = int64_t; - -int squid_timestamp_to_buf(char *buf, unsigned int buf_size, long timestamp_sec, long timestamp_usec); -char *int64_to_str(char *buf, unsigned int buf_size, int64_t val, unsigned int *total_chars, unsigned int req_width = 0, - char pad_char = '0'); - -////////////////////////////////////////////////////////////////////////////// -// -// Factors to multiply units by to obtain corresponding ink_hrtime values. -// -////////////////////////////////////////////////////////////////////////////// - -#define HRTIME_FOREVER (10 * HRTIME_DECADE) -#define HRTIME_DECADE (10 * HRTIME_YEAR) -#define HRTIME_YEAR (365 * HRTIME_DAY + HRTIME_DAY / 4) -#define HRTIME_WEEK (7 * HRTIME_DAY) -#define HRTIME_DAY (24 * HRTIME_HOUR) -#define HRTIME_HOUR (60 * HRTIME_MINUTE) -#define HRTIME_MINUTE (60 * HRTIME_SECOND) -#define HRTIME_SECOND (1000 * HRTIME_MSECOND) -#define HRTIME_MSECOND (1000 * HRTIME_USECOND) -#define HRTIME_USECOND (1000 * HRTIME_NSECOND) -#define HRTIME_NSECOND (static_cast(1)) - -#define HRTIME_APPROX_SECONDS(_x) ((_x) >> 30) // off by 7.3% -#define HRTIME_APPROX_FACTOR (((float)(1 << 30)) / (((float)HRTIME_SECOND))) - -////////////////////////////////////////////////////////////////////////////// -// -// Map from units to ink_hrtime values -// -////////////////////////////////////////////////////////////////////////////// - -// simple macros - -#define HRTIME_YEARS(_x) ((_x) * HRTIME_YEAR) -#define HRTIME_WEEKS(_x) ((_x) * HRTIME_WEEK) -#define HRTIME_DAYS(_x) ((_x) * HRTIME_DAY) -#define HRTIME_HOURS(_x) ((_x) * HRTIME_HOUR) -#define HRTIME_MINUTES(_x) ((_x) * HRTIME_MINUTE) -#define HRTIME_SECONDS(_x) ((_x) * HRTIME_SECOND) -#define HRTIME_MSECONDS(_x) ((_x) * HRTIME_MSECOND) -#define HRTIME_USECONDS(_x) ((_x) * HRTIME_USECOND) -#define HRTIME_NSECONDS(_x) ((_x) * HRTIME_NSECOND) - -// gratuitous wrappers - -static inline ink_hrtime -ink_hrtime_from_years(unsigned int years) -{ - return (HRTIME_YEARS(years)); -} - -static inline ink_hrtime -ink_hrtime_from_weeks(unsigned int weeks) -{ - return (HRTIME_WEEKS(weeks)); -} - -static inline ink_hrtime -ink_hrtime_from_days(unsigned int days) -{ - return (HRTIME_DAYS(days)); -} - -static inline ink_hrtime -ink_hrtime_from_mins(unsigned int mins) -{ - return (HRTIME_MINUTES(mins)); -} - -static inline ink_hrtime -ink_hrtime_from_sec(unsigned int sec) -{ - return (HRTIME_SECONDS(sec)); -} - -static inline ink_hrtime -ink_hrtime_from_msec(unsigned int msec) -{ - return (HRTIME_MSECONDS(msec)); -} - -static inline ink_hrtime -ink_hrtime_from_usec(unsigned int usec) -{ - return (HRTIME_USECONDS(usec)); -} - -static inline ink_hrtime -ink_hrtime_from_nsec(unsigned int nsec) -{ - return (HRTIME_NSECONDS(nsec)); -} - -static inline ink_hrtime -ink_hrtime_from_timespec(const struct timespec *ts) -{ - return ink_hrtime_from_sec(ts->tv_sec) + ink_hrtime_from_nsec(ts->tv_nsec); -} - -static inline ink_hrtime -ink_hrtime_from_timeval(const struct timeval *tv) -{ - return ink_hrtime_from_sec(tv->tv_sec) + ink_hrtime_from_usec(tv->tv_usec); -} - -////////////////////////////////////////////////////////////////////////////// -// -// Map from ink_hrtime values to other units -// -////////////////////////////////////////////////////////////////////////////// - -static inline ink_hrtime -ink_hrtime_to_years(ink_hrtime t) -{ - return (t / HRTIME_YEAR); -} - -static inline ink_hrtime -ink_hrtime_to_weeks(ink_hrtime t) -{ - return (t / HRTIME_WEEK); -} - -static inline ink_hrtime -ink_hrtime_to_days(ink_hrtime t) -{ - return (t / HRTIME_DAY); -} - -static inline ink_hrtime -ink_hrtime_to_mins(ink_hrtime t) -{ - return (t / HRTIME_MINUTE); -} - -static inline ink_hrtime -ink_hrtime_to_sec(ink_hrtime t) -{ - return (t / HRTIME_SECOND); -} - -static inline ink_hrtime -ink_hrtime_to_msec(ink_hrtime t) -{ - return (t / HRTIME_MSECOND); -} - -static inline ink_hrtime -ink_hrtime_to_usec(ink_hrtime t) -{ - return (t / HRTIME_USECOND); -} - -static inline ink_hrtime -ink_hrtime_to_nsec(ink_hrtime t) -{ - return (t / HRTIME_NSECOND); -} - -static inline struct timespec -ink_hrtime_to_timespec(ink_hrtime t) -{ - struct timespec ts; - - ts.tv_sec = ink_hrtime_to_sec(t); - ts.tv_nsec = t % HRTIME_SECOND; - return (ts); -} - -static inline struct timeval -ink_hrtime_to_timeval(ink_hrtime t) -{ - int64_t usecs; - struct timeval tv; - - usecs = ink_hrtime_to_usec(t); - tv.tv_sec = usecs / 1000000; - tv.tv_usec = usecs % 1000000; - return (tv); -} - -/* - using Jan 1 1970 as the base year, instead of Jan 1 1601, - which translates to (365 + 0.25)369*24*60*60 seconds */ -#define NT_TIMEBASE_DIFFERENCE_100NSECS 116444736000000000i64 - -extern int gSystemClock; // 0 == CLOCK_REALTIME, the default - -static inline ink_hrtime -ink_get_hrtime() -{ -#if defined(freebsd) || HAVE_CLOCK_GETTIME - timespec ts; - clock_gettime(static_cast(gSystemClock), &ts); - return ink_hrtime_from_timespec(&ts); -#else - timeval tv; - gettimeofday(&tv, nullptr); - return ink_hrtime_from_timeval(&tv); -#endif -} - -static inline struct timeval -ink_gettimeofday() -{ - return ink_hrtime_to_timeval(ink_get_hrtime()); -} - -static inline int -ink_time() -{ - return static_cast(ink_hrtime_to_sec(ink_get_hrtime())); -} - -static inline int -ink_hrtime_diff_msec(ink_hrtime t1, ink_hrtime t2) -{ - return static_cast(ink_hrtime_to_msec(t1 - t2)); -} - -static inline ink_hrtime -ink_hrtime_diff(ink_hrtime t1, ink_hrtime t2) -{ - return (t1 - t2); -} - -static inline ink_hrtime -ink_hrtime_add(ink_hrtime t1, ink_hrtime t2) -{ - return (t1 + t2); -} - -static inline void -ink_hrtime_sleep(ink_hrtime delay) -{ - struct timespec ts = ink_hrtime_to_timespec(delay); - nanosleep(&ts, nullptr); -} diff --git a/include/tscore/ink_thread.h b/include/tscore/ink_thread.h index 16642b44da3..edd2904b3b6 100644 --- a/include/tscore/ink_thread.h +++ b/include/tscore/ink_thread.h @@ -28,7 +28,6 @@ #pragma once -#include "tscore/ink_hrtime.h" #include "tscore/ink_defs.h" #include diff --git a/include/tscore/ink_time.h b/include/tscore/ink_time.h index 2cd5512d0ff..7008301a51e 100644 --- a/include/tscore/ink_time.h +++ b/include/tscore/ink_time.h @@ -37,7 +37,6 @@ #include "tscore/ink_platform.h" #include "tscore/ink_defs.h" -#include "tscore/ink_hrtime.h" /*===========================================================================* diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index 3fe2b60cbc0..3f11bdc191e 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -27,7 +27,9 @@ set(TSAPI_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ts/ts.h ${PROJECT_SOURCE_ ) # OpenSSL needs to be listed in before PCRE and other libraries that can be found in the system default lib directory (See # #11511) -target_link_libraries(tsapi PRIVATE libswoc::libswoc yaml-cpp::yaml-cpp OpenSSL::SSL PCRE::PCRE PkgConfig::PCRE2) +target_link_libraries( + tsapi PRIVATE libswoc::libswoc yaml-cpp::yaml-cpp OpenSSL::SSL PCRE::PCRE PkgConfig::PCRE2 ts::tscore +) set_target_properties(tsapi PROPERTIES PUBLIC_HEADER "${TSAPI_PUBLIC_HEADERS}") # Items common between api and other ts libraries diff --git a/src/iocore/aio/AIO.cc b/src/iocore/aio/AIO.cc index 0f69f51d3ed..45771c15c18 100644 --- a/src/iocore/aio/AIO.cc +++ b/src/iocore/aio/AIO.cc @@ -37,14 +37,15 @@ #include "tscore/ink_hw.h" #endif -#if TS_USE_LINUX_IO_URING -#include "iocore/io_uring/IO_URING.h" -#endif - #ifdef AIO_FAULT_INJECTION #include "iocore/aio/AIO_fault_injection.h" #endif +#if TS_USE_LINUX_IO_URING +#include +import inkuring; +#endif + #define MAX_DISKS_POSSIBLE 100 // globals @@ -547,7 +548,6 @@ AIOThreadInfo::aio_thread_main(AIOThreadInfo *thr_info) } #if TS_USE_LINUX_IO_URING -#include "iocore/io_uring/IO_URING.h" namespace { diff --git a/src/iocore/cache/CacheDoc.cc b/src/iocore/cache/CacheDoc.cc index 0a79651f240..205ede9540a 100644 --- a/src/iocore/cache/CacheDoc.cc +++ b/src/iocore/cache/CacheDoc.cc @@ -25,10 +25,10 @@ #include "iocore/eventsystem/IOBuffer.h" -#include "tscore/ink_hrtime.h" - #include +import tscore; + namespace { @@ -80,7 +80,7 @@ void Doc::pin(std::uint32_t const pin_in_cache) { // coverity[Y2K38_SAFETY:FALSE] - this->pinned = static_cast(ink_get_hrtime() / HRTIME_SECOND) + pin_in_cache; + this->pinned = static_cast(ink_get_hrtime() / HRTIME_SECONDS(1)) + pin_in_cache; } void diff --git a/src/iocore/cache/CacheVC.cc b/src/iocore/cache/CacheVC.cc index 951678f2a49..95cbb5970c7 100644 --- a/src/iocore/cache/CacheVC.cc +++ b/src/iocore/cache/CacheVC.cc @@ -56,7 +56,6 @@ // tscore #include "tscore/ink_assert.h" -#include "tscore/ink_hrtime.h" #include "tscore/Ptr.h" // ts diff --git a/src/iocore/cache/CacheVC.h b/src/iocore/cache/CacheVC.h index 28ef804c6c2..83ec2756efd 100644 --- a/src/iocore/cache/CacheVC.h +++ b/src/iocore/cache/CacheVC.h @@ -33,12 +33,13 @@ #include "P_CacheDoc.h" #include "Stripe.h" #include "StripeSM.h" -#include "tscore/ink_hrtime.h" #include "tscore/List.h" #include "tscore/Ptr.h" #include +import tscore; + class Stripe; class HttpConfigAccessor; diff --git a/src/iocore/cache/RamCacheCLFUS.cc b/src/iocore/cache/RamCacheCLFUS.cc index 578852e6831..1c50f1a6bf8 100644 --- a/src/iocore/cache/RamCacheCLFUS.cc +++ b/src/iocore/cache/RamCacheCLFUS.cc @@ -218,7 +218,7 @@ RamCacheCLFUS::init(int64_t abytes, StripeSM *astripe) } this->_resize_hashtable(); if (cache_config_ram_cache_compress) { - eventProcessor.schedule_every(new RamCacheCLFUSCompressor(this), HRTIME_SECOND, ET_TASK); + eventProcessor.schedule_every(new RamCacheCLFUSCompressor(this), HRTIME_SECONDS(1), ET_TASK); } } diff --git a/src/iocore/cache/RegressionSM.cc b/src/iocore/cache/RegressionSM.cc index 8513773cbca..3f0b8ebbfd3 100644 --- a/src/iocore/cache/RegressionSM.cc +++ b/src/iocore/cache/RegressionSM.cc @@ -24,7 +24,7 @@ #include "RegressionSM.h" #include "iocore/eventsystem/EventProcessor.h" -#define REGRESSION_SM_RETRY (100 * HRTIME_MSECOND) +#define REGRESSION_SM_RETRY (HRTIME_MSECONDS(100)) void RegressionSM::set_status(int astatus) diff --git a/src/iocore/cache/StripeSM.cc b/src/iocore/cache/StripeSM.cc index 40a3877d2fa..cc2ba4858c3 100644 --- a/src/iocore/cache/StripeSM.cc +++ b/src/iocore/cache/StripeSM.cc @@ -49,7 +49,6 @@ #include "tscore/InkErrno.h" #include "tscore/Diags.h" #include "tscore/ink_assert.h" -#include "tscore/ink_hrtime.h" #include "tscore/List.h" #include @@ -57,6 +56,8 @@ #include #include +import tscore; + // These macros allow two incrementing unsigned values x and y to maintain // their ordering when one of them overflows, given that the values stay close to each other. #define UINT_WRAP_LTE(_x, _y) (((_y) - (_x)) < INT_MAX) // exploit overflow @@ -1166,7 +1167,7 @@ StripeSM::evacuateDocReadDone(int event, Event *e) goto Ldone; } // coverity[Y2K38_SAFETY:FALSE] - if ((b->f.pinned && !b->readers) && doc->pinned < static_cast(ink_get_hrtime() / HRTIME_SECOND)) { + if ((b->f.pinned && !b->readers) && doc->pinned < static_cast(ink_get_hrtime() / HRTIME_SECONDS(1))) { goto Ldone; } diff --git a/src/iocore/cache/unit_tests/test_doubles.h b/src/iocore/cache/unit_tests/test_doubles.h index e8ce779e3b1..d54bc41a377 100644 --- a/src/iocore/cache/unit_tests/test_doubles.h +++ b/src/iocore/cache/unit_tests/test_doubles.h @@ -27,7 +27,6 @@ #include "tscore/EventNotify.h" #include "tscore/ink_config.h" -#include "tscore/ink_hrtime.h" #if TS_USE_LINUX_IO_URING #include "iocore/io_uring/IO_URING.h" diff --git a/src/iocore/dns/DNS.cc b/src/iocore/dns/DNS.cc index 50cbcace804..17075a589bb 100644 --- a/src/iocore/dns/DNS.cc +++ b/src/iocore/dns/DNS.cc @@ -1412,7 +1412,7 @@ dns_result(DNSHandler *h, DNSEntry *e, HostEnt *ent, bool retry, bool tcp_retry) } if (!cancelled) { // ToDo: Should this possibly be send_time() ?? - ink_hrtime diff = (ink_get_hrtime() - e->submit_time) / HRTIME_MSECOND; + ink_hrtime diff = (ink_get_hrtime() - e->submit_time) / HRTIME_MSECONDS(1); // These are rolling averages, this requires that the lookup_fail/success counters are incremented later if (!ent || !ent->good) { @@ -1580,7 +1580,7 @@ dns_process(DNSHandler *handler, HostEnt *buf, int len) --(handler->in_flight); Metrics::Gauge::decrement(dns_rsb.in_flight); // These are rolling averages - ink_hrtime diff = (ink_get_hrtime() - e->send_time) / HRTIME_MSECOND; + ink_hrtime diff = (ink_get_hrtime() - e->send_time) / HRTIME_MSECONDS(1); Metrics::Counter::increment(dns_rsb.response_time, diff); diff --git a/src/iocore/dns/P_DNSProcessor.h b/src/iocore/dns/P_DNSProcessor.h index e11dc34df5f..2826840d9ca 100644 --- a/src/iocore/dns/P_DNSProcessor.h +++ b/src/iocore/dns/P_DNSProcessor.h @@ -35,7 +35,6 @@ #include "iocore/eventsystem/Event.h" #include "tscore/ink_apidefs.h" -#include "tscore/ink_hrtime.h" #include "tscore/ink_inet.h" #include "tscore/ink_rand.h" #include "tscore/ink_resolver.h" @@ -49,6 +48,8 @@ #include "tsutil/Metrics.h" +import tscore; + using ts::Metrics; #define MAX_NAMED 32 diff --git a/src/iocore/eventsystem/UnixEThread.cc b/src/iocore/eventsystem/UnixEThread.cc index cfcd889fbe7..9be1d048f82 100644 --- a/src/iocore/eventsystem/UnixEThread.cc +++ b/src/iocore/eventsystem/UnixEThread.cc @@ -229,7 +229,7 @@ EThread::execute_regular() ink_hrtime loop_finish_time; // Time at the end of the loop. // Track this so we can update on boundary crossing. - auto prev_slice = this->metrics.prev_slice(metrics._slice.data() + (ink_get_hrtime() / HRTIME_SECOND) % Metrics::N_SLICES); + auto prev_slice = this->metrics.prev_slice(metrics._slice.data() + (ink_get_hrtime() / HRTIME_SECONDS(1)) % Metrics::N_SLICES); int nq_count; int ev_count; @@ -245,7 +245,7 @@ EThread::execute_regular() nq_count = 0; // count # of elements put on negative queue. ev_count = 0; // # of events handled. - current_slice = metrics._slice.data() + (loop_start_time / HRTIME_SECOND) % Metrics::N_SLICES; + current_slice = metrics._slice.data() + (loop_start_time / HRTIME_SECONDS(1)) % Metrics::N_SLICES; metrics.current_slice.store(current_slice, std::memory_order_release); if (current_slice != prev_slice) { // I have observed multi-second event loops in production, making this necessary. [amc] @@ -289,7 +289,7 @@ EThread::execute_regular() ink_hrtime sleep_time = next_time - ink_get_hrtime(); if (sleep_time > 0) { if (EventQueueExternal.localQueue.empty()) { - sleep_time = std::min(sleep_time, HRTIME_MSECONDS(thread_max_heartbeat_mseconds)); + sleep_time = std::min(sleep_time, HRTIME_MSECONDS(thread_max_heartbeat_mseconds)); } else { // Because of a missed lock, Timed-Event and Negative-Event have been pushed into localQueue for retry in awhile. // Therefore, we have to set the limitation of sleep time in order to handle the next retry in time. diff --git a/src/iocore/hostdb/P_RefCountCache.h b/src/iocore/hostdb/P_RefCountCache.h index d7e16c87465..fdc4f520767 100644 --- a/src/iocore/hostdb/P_RefCountCache.h +++ b/src/iocore/hostdb/P_RefCountCache.h @@ -29,7 +29,6 @@ #include "tscore/Ptr.h" #include "tsutil/TsSharedMutex.h" #include "tscore/Version.h" -#include "tscore/ink_hrtime.h" #include "tscore/ink_time.h" #include "tsutil/Metrics.h" @@ -37,6 +36,8 @@ #include #include +import tscore; + using ts::Metrics; #define REFCOUNT_CACHE_EVENT_SYNC REFCOUNT_CACHE_EVENT_EVENTS_START diff --git a/src/iocore/io_uring/CMakeLists.txt b/src/iocore/io_uring/CMakeLists.txt index 6cec4d1e882..1b3cb8aa72a 100644 --- a/src/iocore/io_uring/CMakeLists.txt +++ b/src/iocore/io_uring/CMakeLists.txt @@ -15,9 +15,11 @@ # ####################### -add_library(inkuring STATIC io_uring.cc IOUringEventIO.cc) +add_library(inkuring STATIC context.cc) add_library(ts::inkuring ALIAS inkuring) +target_sources(inkuring PUBLIC FILE_SET CXX_MODULES FILES io_uring.cc) + target_link_libraries( inkuring PUBLIC ts::tscore uring @@ -26,6 +28,7 @@ target_link_libraries( if(BUILD_TESTING) add_executable(test_iouring unit_tests/test_diskIO.cc) + target_link_libraries(test_iouring PRIVATE inkuring libswoc::libswoc tsutil catch2::catch2) target_include_directories(test_iouring PRIVATE ${CATCH_INCLUDE_DIR}) diff --git a/src/iocore/io_uring/IOUringEventIO.cc b/src/iocore/io_uring/IOUringEventIO.cc deleted file mode 100644 index 15180c51806..00000000000 --- a/src/iocore/io_uring/IOUringEventIO.cc +++ /dev/null @@ -1,41 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -#include "iocore/io_uring/IOUringEventIO.h" -#if TS_USE_LINUX_IO_URING -#include "iocore/io_uring/IO_URING.h" - -int -IOUringEventIO::start(EventLoop l, IOUringContext *h) -{ - _h = h; - int fd = _h->register_eventfd(); - return start_common(l, fd, EVENTIO_READ); -} - -void -IOUringEventIO::process_event(int /* flags ATS_UNUSED */) -{ - _h->service(); -} -#endif diff --git a/src/iocore/io_uring/context.cc b/src/iocore/io_uring/context.cc new file mode 100644 index 00000000000..9e1324d6eb7 --- /dev/null +++ b/src/iocore/io_uring/context.cc @@ -0,0 +1,253 @@ +/** @file + +Linux io_uring helper library + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +module; + +#include "iocore/io_uring/IO_URING.h" + +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +module inkuring; + +import tscore; + +using ts::Metrics; + +std::atomic main_wq_fd; + +namespace +{ +DbgCtl dbg_ctl_io_uring{"io_uring"}; + +} // end anonymous namespace + +IOUringConfig IOUringContext::config; + +struct IOUringStatsBlock { + Metrics::Counter::AtomicType *io_uring_submitted; + Metrics::Counter::AtomicType *io_uring_completed; +}; + +static IOUringStatsBlock io_uring_rsb = []() { + return IOUringStatsBlock{Metrics::Counter::createPtr("proxy.process.io_uring.submitted"), + Metrics::Counter::createPtr("proxy.process.io_uring.completed")}; +}(); + +void +IOUringContext::set_config(const IOUringConfig &cfg) +{ + config = cfg; +} + +static io_uring_probe probe_unsupported = {}; +constexpr int MAX_SUPPORTED_OP_BEFORE_PROBE = 20; + +IOUringContext::IOUringContext() +{ + io_uring_params p{}; + + if (config.attach_wq > 0) { + int wq_fd = get_main_queue_fd(); + if (wq_fd > 0) { + p.flags = IORING_SETUP_ATTACH_WQ; + p.wq_fd = wq_fd; + } + } + + if (config.sq_poll_ms > 0) { + p.flags |= IORING_SETUP_SQPOLL; + p.sq_thread_idle = config.sq_poll_ms; + } + + int ret = io_uring_queue_init_params(config.queue_entries, &ring, &p); + if (ret < 0) { + char *err = strerror(-ret); + Dbg(dbg_ctl_io_uring, "io_uring_queue_init_params failed: (%d) %s", -ret, err); + ring.ring_fd = -1; + } else { + /* no sharing for non-fixed either */ + if (config.sq_poll_ms && !(p.features & IORING_FEAT_SQPOLL_NONFIXED)) { + Dbg(dbg_ctl_io_uring, "No SQPOLL sharing with nonfixed"); + } + } + + // Fetch the probe info so we can check for op support + probe = io_uring_get_probe_ring(&ring); + if (probe == nullptr) { + probe = &probe_unsupported; + } +} + +IOUringContext::~IOUringContext() +{ + if (evfd != -1) { + ::close(evfd); + evfd = -1; + } + if (probe != &probe_unsupported) { + io_uring_free_probe(probe); + } + io_uring_queue_exit(&ring); +} + +void +IOUringContext::set_main_queue(IOUringContext *dh) +{ + dh->set_wq_max_workers(config.wq_bounded, config.wq_unbounded); + main_wq_fd.store(dh->ring.ring_fd); +} + +int +IOUringContext::get_main_queue_fd() +{ + return main_wq_fd.load(); +} + +int +IOUringContext::set_wq_max_workers(unsigned int bounded, unsigned int unbounded) +{ + if (bounded == 0 && unbounded == 0) { + return 0; + } + unsigned int args[2] = {bounded, unbounded}; + int result = io_uring_register_iowq_max_workers(&ring, args); + return result; +} + +std::pair +IOUringContext::get_wq_max_workers() +{ + unsigned int args[2] = {0, 0}; + io_uring_register_iowq_max_workers(&ring, args); + return std::make_pair(args[0], args[1]); +} + +void +IOUringContext::submit() +{ + Metrics::Counter::increment(io_uring_rsb.io_uring_submitted, io_uring_submit(&ring)); +} + +void +IOUringContext::handle_cqe(io_uring_cqe *cqe) +{ + auto *op = reinterpret_cast(io_uring_cqe_get_data(cqe)); + + op->handle_complete(cqe); +} + +void +IOUringContext::service() +{ + io_uring_cqe *cqe = nullptr; + io_uring_peek_cqe(&ring, &cqe); + while (cqe) { + handle_cqe(cqe); + Metrics::Counter::increment(io_uring_rsb.io_uring_completed); + io_uring_cqe_seen(&ring, cqe); + + cqe = nullptr; + io_uring_peek_cqe(&ring, &cqe); + } + + if (evfd != -1) { + uint64_t val = 0; + ::read(evfd, &val, sizeof(val)); + } +} + +void +IOUringContext::submit_and_wait(ink_hrtime t) +{ + timespec ts = ink_hrtime_to_timespec(t); + __kernel_timespec timeout = {ts.tv_sec, ts.tv_nsec}; + io_uring_cqe *cqe = nullptr; + + int count = io_uring_submit_and_wait_timeout(&ring, &cqe, 1, &timeout, nullptr); + + Metrics::Counter::increment(io_uring_rsb.io_uring_submitted, count); + while (cqe) { + handle_cqe(cqe); + Metrics::Counter::increment(io_uring_rsb.io_uring_completed); + io_uring_cqe_seen(&ring, cqe); + + cqe = nullptr; + io_uring_peek_cqe(&ring, &cqe); + } +} + +int +IOUringContext::register_eventfd() +{ + if (evfd == -1) { + evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); + + io_uring_register_eventfd(&ring, evfd); + } + return evfd; +} + +IOUringContext * +IOUringContext::local_context() +{ + thread_local IOUringContext threadContext; + + return &threadContext; +} + +bool +IOUringContext::supports_op(int op) const +{ + // If we don't have a probe, we can only support the ops that were supported + // before the probe was added. + if (probe == &probe_unsupported) { + return op <= MAX_SUPPORTED_OP_BEFORE_PROBE; + } + + return io_uring_opcode_supported(probe, op); +} + +io_uring_sqe * +IOUringContext::next_sqe(IOUringCompletionHandler *handler) +{ + io_uring_sqe *result = io_uring_get_sqe(&ring); + if (result == nullptr) { + submit(); + result = io_uring_get_sqe(&ring); + } + if (result != nullptr) { + io_uring_sqe_set_data(result, handler); + } + return result; +} diff --git a/src/iocore/io_uring/io_uring.cc b/src/iocore/io_uring/io_uring.cc index 2815f494bb9..fbc357d08e5 100644 --- a/src/iocore/io_uring/io_uring.cc +++ b/src/iocore/io_uring/io_uring.cc @@ -21,210 +21,91 @@ Linux io_uring helper library limitations under the License. */ -#include -#include -#include -#include - -#include +module; #include "iocore/io_uring/IO_URING.h" -#include "tscore/ink_hrtime.h" -#include "tscore/Diags.h" -#include -using ts::Metrics; +#include -std::atomic main_wq_fd; +#include -namespace -{ -DbgCtl dbg_ctl_io_uring{"io_uring"}; +#include -} // end anonymous namespace +export module inkuring; -IOUringConfig IOUringContext::config; +import tscore; -struct IOUringStatsBlock { - Metrics::Counter::AtomicType *io_uring_submitted; - Metrics::Counter::AtomicType *io_uring_completed; +export struct IOUringConfig { + int queue_entries = 32; + int sq_poll_ms = 0; + int attach_wq = 0; + int wq_bounded = 0; + int wq_unbounded = 0; }; -static IOUringStatsBlock io_uring_rsb = []() { - return IOUringStatsBlock{Metrics::Counter::createPtr("proxy.process.io_uring.submitted"), - Metrics::Counter::createPtr("proxy.process.io_uring.completed")}; -}(); - -void -IOUringContext::set_config(const IOUringConfig &cfg) +export class IOUringContext { - config = cfg; -} +public: + IOUringContext(); + ~IOUringContext(); -static io_uring_probe probe_unsupported = {}; -constexpr int MAX_SUPPORTED_OP_BEFORE_PROBE = 20; + IOUringContext(const IOUringContext &) = delete; -IOUringContext::IOUringContext() -{ - io_uring_params p{}; - - if (config.attach_wq > 0) { - int wq_fd = get_main_queue_fd(); - if (wq_fd > 0) { - p.flags = IORING_SETUP_ATTACH_WQ; - p.wq_fd = wq_fd; - } - } + io_uring_sqe *next_sqe(IOUringCompletionHandler *handler); - if (config.sq_poll_ms > 0) { - p.flags |= IORING_SETUP_SQPOLL; - p.sq_thread_idle = config.sq_poll_ms; - } + bool supports_op(int op) const; - int ret = io_uring_queue_init_params(config.queue_entries, &ring, &p); - if (ret < 0) { - char *err = strerror(-ret); - Dbg(dbg_ctl_io_uring, "io_uring_queue_init_params failed: (%d) %s", -ret, err); - ring.ring_fd = -1; - } else { - /* no sharing for non-fixed either */ - if (config.sq_poll_ms && !(p.features & IORING_FEAT_SQPOLL_NONFIXED)) { - Dbg(dbg_ctl_io_uring, "No SQPOLL sharing with nonfixed"); - } - } + int set_wq_max_workers(unsigned int bounded, unsigned int unbounded); + std::pair get_wq_max_workers(); - // Fetch the probe info so we can check for op support - probe = io_uring_get_probe_ring(&ring); - if (probe == nullptr) { - probe = &probe_unsupported; - } -} + void submit(); + void service(); + void submit_and_wait(ink_hrtime ms); -IOUringContext::~IOUringContext() -{ - if (evfd != -1) { - ::close(evfd); - evfd = -1; - } - if (probe != &probe_unsupported) { - io_uring_free_probe(probe); - } - io_uring_queue_exit(&ring); -} + int register_eventfd(); -void -IOUringContext::set_main_queue(IOUringContext *dh) -{ - dh->set_wq_max_workers(config.wq_bounded, config.wq_unbounded); - main_wq_fd.store(dh->ring.ring_fd); -} - -int -IOUringContext::get_main_queue_fd() -{ - return main_wq_fd.load(); -} + // assigns the global iouring config + static void set_config(const IOUringConfig &); + static IOUringContext *local_context(); + static void set_main_queue(IOUringContext *); + static int get_main_queue_fd(); -int -IOUringContext::set_wq_max_workers(unsigned int bounded, unsigned int unbounded) -{ - if (bounded == 0 && unbounded == 0) { - return 0; + bool + valid() + { + return ring.ring_fd > 0; } - unsigned int args[2] = {bounded, unbounded}; - int result = io_uring_register_iowq_max_workers(&ring, args); - return result; -} - -std::pair -IOUringContext::get_wq_max_workers() -{ - unsigned int args[2] = {0, 0}; - io_uring_register_iowq_max_workers(&ring, args); - return std::make_pair(args[0], args[1]); -} - -void -IOUringContext::submit() -{ - Metrics::Counter::increment(io_uring_rsb.io_uring_submitted, io_uring_submit(&ring)); -} - -void -IOUringContext::handle_cqe(io_uring_cqe *cqe) -{ - auto *op = reinterpret_cast(io_uring_cqe_get_data(cqe)); - op->handle_complete(cqe); -} +private: + io_uring ring = {}; + io_uring_probe *probe = nullptr; + int evfd = -1; -void -IOUringContext::service() -{ - io_uring_cqe *cqe = nullptr; - io_uring_peek_cqe(&ring, &cqe); - while (cqe) { - handle_cqe(cqe); - Metrics::Counter::increment(io_uring_rsb.io_uring_completed); - io_uring_cqe_seen(&ring, cqe); - - cqe = nullptr; - io_uring_peek_cqe(&ring, &cqe); - } - - if (evfd != -1) { - uint64_t val = 0; - ::read(evfd, &val, sizeof(val)); - } -} + void handle_cqe(io_uring_cqe *); + static IOUringConfig config; +}; -void -IOUringContext::submit_and_wait(ink_hrtime t) +export class IOUringEventIO : public EventIO { - timespec ts = ink_hrtime_to_timespec(t); - __kernel_timespec timeout = {ts.tv_sec, ts.tv_nsec}; - io_uring_cqe *cqe = nullptr; +public: + IOUringEventIO() : EventIO() {} + int start(EventLoop l, IOUringContext *h); + void process_event(int flags) override; - int count = io_uring_submit_and_wait_timeout(&ring, &cqe, 1, &timeout, nullptr); - - Metrics::Counter::increment(io_uring_rsb.io_uring_submitted, count); - while (cqe) { - handle_cqe(cqe); - Metrics::Counter::increment(io_uring_rsb.io_uring_completed); - io_uring_cqe_seen(&ring, cqe); - - cqe = nullptr; - io_uring_peek_cqe(&ring, &cqe); - } -} +private: + IOUringContext *_h; +}; int -IOUringContext::register_eventfd() -{ - if (evfd == -1) { - evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); - - io_uring_register_eventfd(&ring, evfd); - } - return evfd; -} - -IOUringContext * -IOUringContext::local_context() +IOUringEventIO::start(EventLoop l, IOUringContext *h) { - thread_local IOUringContext threadContext; - - return &threadContext; + _h = h; + int fd = _h->register_eventfd(); + return start_common(l, fd, EVENTIO_READ); } -bool -IOUringContext::supports_op(int op) const +void +IOUringEventIO::process_event(int /* flags ATS_UNUSED */) { - // If we don't have a probe, we can only support the ops that were supported - // before the probe was added. - if (probe == &probe_unsupported) { - return op <= MAX_SUPPORTED_OP_BEFORE_PROBE; - } - - return io_uring_opcode_supported(probe, op); + _h->service(); } diff --git a/src/iocore/io_uring/unit_tests/test_diskIO.cc b/src/iocore/io_uring/unit_tests/test_diskIO.cc index cdbff2bf801..ce4ec15fbf1 100644 --- a/src/iocore/io_uring/unit_tests/test_diskIO.cc +++ b/src/iocore/io_uring/unit_tests/test_diskIO.cc @@ -27,14 +27,15 @@ #include "swoc/swoc_file.h" -#include "iocore/io_uring/IO_URING.h" +#include + +import inkuring; #include #include #include #include -#include "tscore/ink_hrtime.h" #include "tsutil/Metrics.h" using ts::Metrics; diff --git a/src/iocore/net/CMakeLists.txt b/src/iocore/net/CMakeLists.txt index 8d2a7c71876..b3df3505978 100644 --- a/src/iocore/net/CMakeLists.txt +++ b/src/iocore/net/CMakeLists.txt @@ -114,6 +114,7 @@ target_link_libraries( # Is this necessary? if(TS_USE_LINUX_IO_URING) target_link_libraries(inknet PUBLIC ts::inkuring) + set_target_properties(inknet PROPERTIES CXX_SCAN_FOR_MODULES ON) endif() if(BUILD_TESTING) diff --git a/src/iocore/net/NetHandler.cc b/src/iocore/net/NetHandler.cc index 3fd4b11fe32..c148005045d 100644 --- a/src/iocore/net/NetHandler.cc +++ b/src/iocore/net/NetHandler.cc @@ -25,12 +25,13 @@ #include "P_UnixNet.h" #include "iocore/net/NetHandler.h" #include "iocore/net/PollCont.h" -#if TS_USE_LINUX_IO_URING -#include "iocore/io_uring/IO_URING.h" -#endif #include +#if TS_USE_LINUX_IO_URING +import inkuring; +#endif + using namespace std::literals; namespace @@ -506,7 +507,7 @@ NetHandler::_close_ne(NetEvent *ne, ink_hrtime now, int &handle_event, int &clos if (!lock.is_locked()) { return; } - ink_hrtime diff = (now - (ne->next_inactivity_timeout_at - ne->inactivity_timeout_in)) / HRTIME_SECOND; + ink_hrtime diff = (now - (ne->next_inactivity_timeout_at - ne->inactivity_timeout_in)) / HRTIME_SECONDS(1); if (diff > 0) { total_idle_time += diff; ++total_idle_count; diff --git a/src/iocore/net/P_UDPNet.h b/src/iocore/net/P_UDPNet.h index 04af410c371..7bc66cac022 100644 --- a/src/iocore/net/P_UDPNet.h +++ b/src/iocore/net/P_UDPNet.h @@ -282,7 +282,7 @@ class PacketQueue } s = (s + 1) % N_SLOTS; } - return HRTIME_FOREVER; + return HRTIME_FOREVERS(1); } }; diff --git a/src/iocore/net/P_UnixNet.h b/src/iocore/net/P_UnixNet.h index 865f5b6c518..21a48ce2659 100644 --- a/src/iocore/net/P_UnixNet.h +++ b/src/iocore/net/P_UnixNet.h @@ -31,10 +31,6 @@ #include "iocore/net/NetHandler.h" #include "tscore/ink_sys_control.h" -#if TS_USE_LINUX_IO_URING -#include "iocore/io_uring/IOUringEventIO.h" -#endif - NetHandler *get_NetHandler(EThread *t); PollCont *get_PollCont(EThread *t); PollDescriptor *get_PollDescriptor(EThread *t); diff --git a/src/iocore/net/TLSBasicSupport.cc b/src/iocore/net/TLSBasicSupport.cc index 17adaa42dd3..fd772b33dd6 100644 --- a/src/iocore/net/TLSBasicSupport.cc +++ b/src/iocore/net/TLSBasicSupport.cc @@ -24,6 +24,7 @@ #include "SSLStats.h" #include "iocore/net/TLSBasicSupport.h" +#include #if defined(OPENSSL_IS_BORINGSSL) #include "tscore/Diags.h" // For Warning #endif // OPENSSL_IS_BORINGSSL diff --git a/src/iocore/net/UnixNet.cc b/src/iocore/net/UnixNet.cc index d26322a5a80..91b7f68c3af 100644 --- a/src/iocore/net/UnixNet.cc +++ b/src/iocore/net/UnixNet.cc @@ -25,10 +25,9 @@ #include "P_Net.h" #include "P_UnixNet.h" #include "iocore/net/AsyncSignalEventIO.h" -#include "tscore/ink_hrtime.h" #if TS_USE_LINUX_IO_URING -#include "iocore/io_uring/IO_URING.h" +import inkuring; #endif ink_hrtime last_throttle_warning; @@ -129,7 +128,7 @@ class InactivityCop : public Continuation } if (nh.keep_alive_queue.in(ne)) { // only stat if the connection is in keep-alive, there can be other inactivity timeouts - ink_hrtime diff = (now - (ne->next_inactivity_timeout_at - ne->inactivity_timeout_in)) / HRTIME_SECOND; + ink_hrtime diff = (now - (ne->next_inactivity_timeout_at - ne->inactivity_timeout_in)) / HRTIME_SECONDS(1); Metrics::Counter::increment(net_rsb.keep_alive_queue_timeout_total, diff); Metrics::Counter::increment(net_rsb.keep_alive_queue_timeout_count); } diff --git a/src/iocore/net/UnixUDPNet.cc b/src/iocore/net/UnixUDPNet.cc index 29a771ab1c0..2c4da78b6fe 100644 --- a/src/iocore/net/UnixUDPNet.cc +++ b/src/iocore/net/UnixUDPNet.cc @@ -43,9 +43,6 @@ #include "iocore/net/AsyncSignalEventIO.h" #include "iocore/net/Net.h" #include "iocore/eventsystem/UnixSocket.h" -#if TS_USE_LINUX_IO_URING -#include "iocore/io_uring/IO_URING.h" -#endif #include "tscore/ink_inet.h" #include "tscore/ink_sock.h" #include @@ -53,6 +50,10 @@ #include #endif +#if TS_USE_LINUX_IO_URING +import inkuring; +#endif + #ifndef UDP_SEGMENT // This is needed because old glibc may not have the constant even if Kernel supports it. #define UDP_SEGMENT 103 diff --git a/src/proxy/http/HttpTransact.cc b/src/proxy/http/HttpTransact.cc index 0fef997b91c..bb845689a62 100644 --- a/src/proxy/http/HttpTransact.cc +++ b/src/proxy/http/HttpTransact.cc @@ -8250,7 +8250,7 @@ HttpTransact::get_error_string(int erno) ink_time_t ink_local_time() { - return ink_get_hrtime() / HRTIME_SECOND; + return ink_get_hrtime() / HRTIME_SECONDS(1); } // @@ -8274,7 +8274,7 @@ HttpTransact::origin_server_connection_speed(ink_hrtime transfer_time, int64_t n { float bytes_per_hrtime = (transfer_time == 0) ? (nbytes) : (static_cast(nbytes) / static_cast(static_cast(transfer_time))); - int bytes_per_sec = static_cast(bytes_per_hrtime * HRTIME_SECOND); + int bytes_per_sec = static_cast(bytes_per_hrtime * HRTIME_SECONDS(1)); if (bytes_per_sec <= 100) { Metrics::Counter::increment(http_rsb.user_agent_speed_bytes_per_sec_100); @@ -8307,7 +8307,7 @@ HttpTransact::user_agent_connection_speed(ink_hrtime transfer_time, int64_t nbyt { float bytes_per_hrtime = (transfer_time == 0) ? (nbytes) : (static_cast(nbytes) / static_cast(static_cast(transfer_time))); - int64_t bytes_per_sec = static_cast(bytes_per_hrtime * HRTIME_SECOND); + int64_t bytes_per_sec = static_cast(bytes_per_hrtime * HRTIME_SECONDS(1)); if (bytes_per_sec <= 100) { Metrics::Counter::increment(http_rsb.origin_server_speed_bytes_per_sec_100); diff --git a/src/proxy/http2/Http2ConnectionState.cc b/src/proxy/http2/Http2ConnectionState.cc index 49e9cf8be7b..075e12b8451 100644 --- a/src/proxy/http2/Http2ConnectionState.cc +++ b/src/proxy/http2/Http2ConnectionState.cc @@ -37,7 +37,6 @@ #include "iocore/net/TLSSNISupport.h" #include "tscore/ink_assert.h" -#include "tscore/ink_hrtime.h" #include "tscore/ink_memory.h" #include "tsutil/PostScript.h" #include "tsutil/LocalBuffer.h" diff --git a/src/proxy/logging/Log.cc b/src/proxy/logging/Log.cc index c11ccd13096..fd2cad86a72 100644 --- a/src/proxy/logging/Log.cc +++ b/src/proxy/logging/Log.cc @@ -1125,7 +1125,7 @@ Log::init_when_enabled() // create the flush thread create_threads(); - eventProcessor.schedule_every(new PeriodicWakeup(preproc_threads, 1), HRTIME_SECOND, ET_CALL); + eventProcessor.schedule_every(new PeriodicWakeup(preproc_threads, 1), HRTIME_SECONDS(1), ET_CALL); init_status |= FULLY_INITIALIZED; } @@ -1419,11 +1419,11 @@ Log::flush_thread_main(void * /* args ATS_UNUSED */) // Time to work on periodic events?? // - now = ink_get_hrtime() / HRTIME_SECOND; + now = ink_get_hrtime() / HRTIME_SECONDS(1); if (now >= last_time + periodic_tasks_interval) { Dbg(dbg_ctl_log_preproc, "periodic tasks for %" PRId64, (int64_t)now); periodic_tasks(now); - last_time = ink_get_hrtime() / HRTIME_SECOND; + last_time = ink_get_hrtime() / HRTIME_SECONDS(1); } // wait for more work; a spurious wake-up is ok since we'll just diff --git a/src/proxy/logging/LogObject.cc b/src/proxy/logging/LogObject.cc index 37e89598b5e..7356372ea12 100644 --- a/src/proxy/logging/LogObject.cc +++ b/src/proxy/logging/LogObject.cc @@ -504,7 +504,7 @@ class ThreadLocalLogBufferManager : public Continuation if (period < 1) { period = 1; } - eventProcessor.schedule_every(this, period * HRTIME_SECOND, ET_CALL); + eventProcessor.schedule_every(this, period * HRTIME_SECONDS(1), ET_CALL); Dbg(dbg_ctl_log_config, "thread local buffer manager init: %d wakeup period", period); } @@ -1427,7 +1427,7 @@ REGRESSION_TEST(LogObjectManager_Transfer)(RegressionTest *t, int /* atype ATS_U box.check(mgr2.get_num_objects() == 4, "Testing that manager 2 has 4 objects"); rprintf(t, "running Log::periodoc_tasks()\n"); - Log::periodic_tasks(ink_get_hrtime() / HRTIME_SECOND); + Log::periodic_tasks(ink_get_hrtime() / HRTIME_SECONDS(1)); rprintf(t, "Log::periodoc_tasks() done\n"); } diff --git a/src/records/RecRawStats.cc b/src/records/RecRawStats.cc index 850c9fbc3c4..708a7ac058d 100644 --- a/src/records/RecRawStats.cc +++ b/src/records/RecRawStats.cc @@ -159,7 +159,7 @@ RecRawStatSyncHrTimeAvg(const char *name, RecDataT data_type, RecData *data, Rec r = 0.0f; } else { r = static_cast(static_cast(total.sum) / static_cast(total.count)); - r = r / static_cast(HRTIME_SECOND); + r = r / static_cast(HRTIME_SECONDS(1)); } RecDataSetFromFloat(data_type, data, r); diff --git a/src/traffic_server/traffic_server.cc b/src/traffic_server/traffic_server.cc index b9a49f4c256..8c4980c443b 100644 --- a/src/traffic_server/traffic_server.cc +++ b/src/traffic_server/traffic_server.cc @@ -133,6 +133,10 @@ extern "C" int plock(int); #include #endif +#if TS_USE_LINUX_IO_URING +import inkuring; +#endif + extern void load_config_file_callback(const char *parent_file, const char *remap_file); extern HttpBodyFactory *body_factory; @@ -1986,7 +1990,6 @@ main(int /* argc ATS_UNUSED */, const char **argv) #endif // Pick the system clock to choose, likely only on Linux. See . - extern int gSystemClock; // 0 == CLOCK_REALTIME, the default gSystemClock = RecGetRecordInt("proxy.config.system_clock").value_or(0); if (!command_flag) { // No need if we are going into command mode. @@ -2128,9 +2131,9 @@ main(int /* argc ATS_UNUSED */, const char **argv) // This means any spawn scheduling must be done before this point. eventProcessor.start(num_of_net_threads, stacksize); - eventProcessor.schedule_every(new SignalContinuation, HRTIME_MSECOND * 500, ET_CALL); - eventProcessor.schedule_every(new DiagsLogContinuation, HRTIME_SECOND, ET_TASK); - eventProcessor.schedule_every(new MemoryLimit, HRTIME_SECOND * 10, ET_TASK); + eventProcessor.schedule_every(new SignalContinuation, HRTIME_MSECONDS(500), ET_CALL); + eventProcessor.schedule_every(new DiagsLogContinuation, HRTIME_SECONDS(1), ET_TASK); + eventProcessor.schedule_every(new MemoryLimit, HRTIME_SECONDS(10), ET_TASK); RecRegisterConfigUpdateCb("proxy.config.dump_mem_info_frequency", init_memory_tracker, nullptr); init_memory_tracker(nullptr, RECD_NULL, RecData(), nullptr); @@ -2333,7 +2336,7 @@ main(int /* argc ATS_UNUSED */, const char **argv) while (!TSSystemState::is_event_system_shut_down()) { #if TS_USE_LINUX_IO_URING == 1 if (ur->valid()) { - ur->submit_and_wait(1 * HRTIME_SECOND); + ur->submit_and_wait(HRTIME_SECONDS(1)); } else { sleep(1); } diff --git a/src/tscore/CMakeLists.txt b/src/tscore/CMakeLists.txt index 8c9475305a6..c9d68e76883 100644 --- a/src/tscore/CMakeLists.txt +++ b/src/tscore/CMakeLists.txt @@ -41,7 +41,6 @@ add_library( Encoding.cc EventNotify.cc Extendible.cc - FrequencyCounter.cc Hash.cc HashFNV.cc HashSip.cc @@ -69,7 +68,6 @@ add_library( ink_defs.cc ink_error.cc ink_file.cc - ink_hrtime.cc ink_hw.cc ink_inet.cc ink_memory.cc @@ -98,6 +96,8 @@ add_library( ) add_library(ts::tscore ALIAS tscore) +target_sources(tscore PUBLIC FILE_SET CXX_MODULES FILES tscore.cc FrequencyCounter.cc ink_hrtime.cc) + # Some plugins link against ts::tscore and therefore need it to be compiled as # position independent. set_target_properties(tscore PROPERTIES POSITION_INDEPENDENT_CODE TRUE) diff --git a/src/tscore/Diags.cc b/src/tscore/Diags.cc index 2b9b09c3676..c73477fb645 100644 --- a/src/tscore/Diags.cc +++ b/src/tscore/Diags.cc @@ -43,7 +43,6 @@ #include "tscore/ink_error.h" #include "tscore/ink_assert.h" #include "tscore/ink_time.h" -#include "tscore/ink_hrtime.h" #include "tscore/ink_thread.h" #include "tscore/Regression.h" #include "tscore/Diags.h" diff --git a/src/tscore/EventNotify.cc b/src/tscore/EventNotify.cc index 26560a08f54..f5328d5f32d 100644 --- a/src/tscore/EventNotify.cc +++ b/src/tscore/EventNotify.cc @@ -27,8 +27,9 @@ Generic event notify mechanism among threads. **************************************************************************/ +module; + #include "tscore/EventNotify.h" -#include "tscore/ink_hrtime.h" #include "tscore/ink_defs.h" #if defined(HAVE_EVENTFD) && TS_USE_EPOLL == 1 @@ -37,6 +38,9 @@ #include #endif +module tscore; +import :hrtime; + EventNotify::EventNotify() { #if defined(HAVE_EVENTFD) && TS_USE_EPOLL == 1 diff --git a/src/tscore/FrequencyCounter.cc b/src/tscore/FrequencyCounter.cc index c7e76a25b80..a1597efb3d0 100644 --- a/src/tscore/FrequencyCounter.cc +++ b/src/tscore/FrequencyCounter.cc @@ -21,7 +21,28 @@ limitations under the License. */ -#include "tscore/FrequencyCounter.h" +module; + +#include + +export module tscore:frequency_counter; + +import :hrtime; + +export class FrequencyCounter +{ +public: + void increment(uint16_t amount = 1); + uint32_t get_count(); + virtual ~FrequencyCounter() {} + +protected: + uint16_t _count[2] = {0}; + ink_hrtime _last_update = 0; + +private: + virtual ink_hrtime _ink_get_hrtime(); +}; void FrequencyCounter::increment(uint16_t amount) diff --git a/src/tscore/SnowflakeID.cc b/src/tscore/SnowflakeID.cc index c828e3609db..b62d4678dc3 100644 --- a/src/tscore/SnowflakeID.cc +++ b/src/tscore/SnowflakeID.cc @@ -20,10 +20,11 @@ limitations under the License. */ +module; + #include "tscore/SnowflakeID.h" #include "tscore/Diags.h" #include "tscore/ink_base64.h" -#include "tscore/ink_hrtime.h" #include "tsutil/DbgCtl.h" #include @@ -32,6 +33,10 @@ #include #include +module tscore; + +import :hrtime; + std::atomic SnowflakeIDUtils::global_machine_id{0}; DbgCtl dbg_ctl_snowflake{"snowflake"}; diff --git a/src/tscore/ink_hrtime.cc b/src/tscore/ink_hrtime.cc index d5859ff2213..06a96cf59bc 100644 --- a/src/tscore/ink_hrtime.cc +++ b/src/tscore/ink_hrtime.cc @@ -28,8 +28,10 @@ This file contains code supporting the Inktomi high-resolution timer. **************************************************************************/ -#include "tscore/ink_hrtime.h" +module; + #include "tscore/ink_assert.h" +#include "tscore/ink_config.h" #include "tscore/ink_defs.h" #if defined(__FreeBSD__) @@ -40,10 +42,19 @@ #include #include -int gSystemClock = 0; // 0 == CLOCK_REALTIME, the default +#include +#include +#include + +export module tscore:hrtime; + +export using ink_hrtime = int64_t; + +export int gSystemClock = 0; // 0 == CLOCK_REALTIME, the default -char * -int64_to_str(char *buf, unsigned int buf_size, int64_t val, unsigned int *total_chars, unsigned int req_width, char pad_char) +export char * +int64_to_str(char *buf, unsigned int buf_size, int64_t val, unsigned int *total_chars, unsigned int req_width = 0, + char pad_char = '0') { const unsigned int local_buf_size = 32; char local_buf[local_buf_size]; @@ -178,3 +189,296 @@ squid_timestamp_to_buf(char *buf, unsigned int buf_size, long timestamp_sec, lon return res; } + +////////////////////////////////////////////////////////////////////////////// +// +// Factors to multiply units by to obtain corresponding ink_hrtime values. +// +////////////////////////////////////////////////////////////////////////////// + +#define HRTIME_FOREVER (10 * HRTIME_DECADE) +#define HRTIME_DECADE (10 * HRTIME_YEAR) +#define HRTIME_YEAR (365 * HRTIME_DAY + HRTIME_DAY / 4) +#define HRTIME_WEEK (7 * HRTIME_DAY) +#define HRTIME_DAY (24 * HRTIME_HOUR) +#define HRTIME_HOUR (60 * HRTIME_MINUTE) +#define HRTIME_MINUTE (60 * HRTIME_SECOND) +#define HRTIME_SECOND (1000 * HRTIME_MSECOND) +#define HRTIME_MSECOND (1000 * HRTIME_USECOND) +#define HRTIME_USECOND (1000 * HRTIME_NSECOND) +#define HRTIME_NSECOND (static_cast(1)) + +#define HRTIME_APPROX_SECONDS(_x) ((_x) >> 30) // off by 7.3% +#define HRTIME_APPROX_FACTOR (((float)(1 << 30)) / (((float)HRTIME_SECOND))) + +////////////////////////////////////////////////////////////////////////////// +// +// Map from units to ink_hrtime values +// +////////////////////////////////////////////////////////////////////////////// + +// simple macros + +export template +constexpr T +HRTIME_FOREVERS(T x) +{ + return x * HRTIME_FOREVER; +} + +export template +constexpr T +HRTIME_YEARS(T x) +{ + return x * HRTIME_YEAR; +} + +export template +constexpr T +HRTIME_WEEKS(T x) +{ + return x * HRTIME_WEEK; +} + +export template +constexpr T +HRTIME_DAYS(T x) +{ + return x * HRTIME_DAY; +} + +export template +constexpr T +HRTIME_HOURS(T x) +{ + return x * HRTIME_HOUR; +} + +export template +constexpr T +HRTIME_MINUTES(T x) +{ + return x * HRTIME_MINUTE; +} + +export template +constexpr T +HRTIME_SECONDS(T x) +{ + return x * HRTIME_SECOND; +} + +export template +constexpr T +HRTIME_MSECONDS(T x) +{ + return x * HRTIME_MSECOND; +} + +export template +constexpr T +HRTIME_USECONDS(T x) +{ + return x * HRTIME_USECOND; +} + +export template +constexpr T +HRTIME_NSECONDS(T x) +{ + return x * HRTIME_NSECOND; +} + +// gratuitous wrappers + +export ink_hrtime +ink_hrtime_from_years(unsigned int years) +{ + return (HRTIME_YEARS(years)); +} + +export ink_hrtime +ink_hrtime_from_weeks(unsigned int weeks) +{ + return (HRTIME_WEEKS(weeks)); +} + +export ink_hrtime +ink_hrtime_from_days(unsigned int days) +{ + return (HRTIME_DAYS(days)); +} + +export ink_hrtime +ink_hrtime_from_mins(unsigned int mins) +{ + return (HRTIME_MINUTES(mins)); +} + +export ink_hrtime +ink_hrtime_from_sec(unsigned int sec) +{ + return (HRTIME_SECONDS(sec)); +} + +export ink_hrtime +ink_hrtime_from_msec(unsigned int msec) +{ + return (HRTIME_MSECONDS(msec)); +} + +export ink_hrtime +ink_hrtime_from_usec(unsigned int usec) +{ + return (HRTIME_USECONDS(usec)); +} + +export ink_hrtime +ink_hrtime_from_nsec(unsigned int nsec) +{ + return (HRTIME_NSECONDS(nsec)); +} + +static inline ink_hrtime +ink_hrtime_from_timespec(const struct timespec *ts) +{ + return ink_hrtime_from_sec(ts->tv_sec) + ink_hrtime_from_nsec(ts->tv_nsec); +} + +static inline ink_hrtime +ink_hrtime_from_timeval(const struct timeval *tv) +{ + return ink_hrtime_from_sec(tv->tv_sec) + ink_hrtime_from_usec(tv->tv_usec); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Map from ink_hrtime values to other units +// +////////////////////////////////////////////////////////////////////////////// + +export ink_hrtime +ink_hrtime_to_years(ink_hrtime t) +{ + return (t / HRTIME_YEAR); +} + +export ink_hrtime +ink_hrtime_to_weeks(ink_hrtime t) +{ + return (t / HRTIME_WEEK); +} + +export ink_hrtime +ink_hrtime_to_days(ink_hrtime t) +{ + return (t / HRTIME_DAY); +} + +export ink_hrtime +ink_hrtime_to_mins(ink_hrtime t) +{ + return (t / HRTIME_MINUTE); +} + +export ink_hrtime +ink_hrtime_to_sec(ink_hrtime t) +{ + return (t / HRTIME_SECOND); +} + +export ink_hrtime +ink_hrtime_to_msec(ink_hrtime t) +{ + return (t / HRTIME_MSECOND); +} + +export ink_hrtime +ink_hrtime_to_usec(ink_hrtime t) +{ + return (t / HRTIME_USECOND); +} + +export ink_hrtime +ink_hrtime_to_nsec(ink_hrtime t) +{ + return (t / HRTIME_NSECOND); +} + +export struct timespec +ink_hrtime_to_timespec(ink_hrtime t) +{ + struct timespec ts; + + ts.tv_sec = ink_hrtime_to_sec(t); + ts.tv_nsec = t % HRTIME_SECOND; + return (ts); +} + +export struct timeval +ink_hrtime_to_timeval(ink_hrtime t) +{ + int64_t usecs; + struct timeval tv; + + usecs = ink_hrtime_to_usec(t); + tv.tv_sec = usecs / 1000000; + tv.tv_usec = usecs % 1000000; + return (tv); +} + +/* + using Jan 1 1970 as the base year, instead of Jan 1 1601, + which translates to (365 + 0.25)369*24*60*60 seconds */ +#define NT_TIMEBASE_DIFFERENCE_100NSECS 116444736000000000i64 + +export ink_hrtime +ink_get_hrtime() +{ +#if defined(freebsd) || HAVE_CLOCK_GETTIME + timespec ts; + clock_gettime(static_cast(gSystemClock), &ts); + return ink_hrtime_from_timespec(&ts); +#else + timeval tv; + gettimeofday(&tv, nullptr); + return ink_hrtime_from_timeval(&tv); +#endif +} + +export struct timeval +ink_gettimeofday() +{ + return ink_hrtime_to_timeval(ink_get_hrtime()); +} + +export int +ink_time() +{ + return static_cast(ink_hrtime_to_sec(ink_get_hrtime())); +} + +export int +ink_hrtime_diff_msec(ink_hrtime t1, ink_hrtime t2) +{ + return static_cast(ink_hrtime_to_msec(t1 - t2)); +} + +export ink_hrtime +ink_hrtime_diff(ink_hrtime t1, ink_hrtime t2) +{ + return (t1 - t2); +} + +export ink_hrtime +ink_hrtime_add(ink_hrtime t1, ink_hrtime t2) +{ + return (t1 + t2); +} + +export void +ink_hrtime_sleep(ink_hrtime delay) +{ + struct timespec ts = ink_hrtime_to_timespec(delay); + nanosleep(&ts, nullptr); +} diff --git a/include/iocore/io_uring/IOUringEventIO.h b/src/tscore/tscore.cc similarity index 71% rename from include/iocore/io_uring/IOUringEventIO.h rename to src/tscore/tscore.cc index f8582bd7400..8b7e636fe00 100644 --- a/include/iocore/io_uring/IOUringEventIO.h +++ b/src/tscore/tscore.cc @@ -21,20 +21,7 @@ limitations under the License. */ -#pragma once -#include "tscore/ink_config.h" -#if TS_USE_LINUX_IO_URING -#include "iocore/net/EventIO.h" +export module tscore; -class IOUringContext; -class IOUringEventIO : public EventIO -{ -public: - IOUringEventIO() : EventIO() {} - int start(EventLoop l, IOUringContext *h); - void process_event(int flags) override; - -private: - IOUringContext *_h; -}; -#endif +export import :frequency_counter; +export import :hrtime;