From 939600d2d4d2d04524301f4373d76dc3c693923a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Mon, 13 Mar 2023 22:11:13 +0100 Subject: [PATCH] Kernel: Use UnixDateTime wherever applicable "Wherever applicable" = most places, actually :^), especially for networking and filesystem timestamps. This includes changes to unzip, which uses DOSPackedTime, since that is changed for the FAT file systems. --- AK/DOSPackedTime.cpp | 6 +-- AK/DOSPackedTime.h | 2 +- Kernel/Arch/x86_64/RTC.cpp | 4 +- Kernel/Arch/x86_64/RTC.h | 2 +- Kernel/Devices/Audio/IntelHDA/Controller.cpp | 5 +- Kernel/FileSystem/DevPtsFS/Inode.cpp | 2 +- Kernel/FileSystem/Ext2FS/FileSystem.cpp | 4 +- Kernel/FileSystem/Ext2FS/Inode.cpp | 10 ++-- Kernel/FileSystem/Ext2FS/Inode.h | 2 +- Kernel/FileSystem/ISO9660FS/Inode.cpp | 14 ++---- Kernel/FileSystem/ISO9660FS/Inode.h | 4 +- Kernel/FileSystem/Inode.cpp | 2 +- Kernel/FileSystem/Inode.h | 2 +- Kernel/FileSystem/InodeMetadata.h | 8 ++-- Kernel/FileSystem/ProcFS/Inode.h | 2 +- Kernel/FileSystem/RAMFS/Inode.cpp | 2 +- Kernel/FileSystem/RAMFS/Inode.h | 2 +- Kernel/FileSystem/SysFS/Inode.cpp | 2 +- Kernel/FileSystem/SysFS/Inode.h | 2 +- Kernel/FileSystem/VirtualFileSystem.cpp | 6 +-- Kernel/Net/IPv4Socket.cpp | 6 +-- Kernel/Net/IPv4Socket.h | 8 ++-- Kernel/Net/LocalSocket.cpp | 2 +- Kernel/Net/LocalSocket.h | 2 +- Kernel/Net/NetworkAdapter.cpp | 2 +- Kernel/Net/NetworkAdapter.h | 6 +-- Kernel/Net/NetworkTask.cpp | 20 ++++---- Kernel/Net/Socket.cpp | 2 +- Kernel/Net/Socket.h | 2 +- Kernel/Net/TCPSocket.h | 4 +- Kernel/PerformanceManager.h | 2 +- Kernel/Process.cpp | 4 +- Kernel/Process.h | 2 +- Kernel/Syscalls/clock.cpp | 10 ++-- Kernel/Syscalls/socket.cpp | 2 +- Kernel/Syscalls/utime.cpp | 2 +- Kernel/TTY/SlavePTY.cpp | 2 +- Kernel/TTY/SlavePTY.h | 4 +- Kernel/Time/TimeManagement.cpp | 50 ++++++++++---------- Kernel/Time/TimeManagement.h | 23 ++++----- Userland/Utilities/unzip.cpp | 2 +- 41 files changed, 115 insertions(+), 125 deletions(-) diff --git a/AK/DOSPackedTime.cpp b/AK/DOSPackedTime.cpp index f964db14d2f..224db24c301 100644 --- a/AK/DOSPackedTime.cpp +++ b/AK/DOSPackedTime.cpp @@ -8,12 +8,12 @@ namespace AK { -Duration time_from_packed_dos(DOSPackedDate date, DOSPackedTime time) +UnixDateTime time_from_packed_dos(DOSPackedDate date, DOSPackedTime time) { if (date.value == 0) - return Duration(); + return UnixDateTime::from_unix_time_parts(first_dos_year, 1, 1, 0, 0, 0, 0); - return Duration::from_timestamp(first_dos_year + date.year, date.month, date.day, time.hour, time.minute, time.second * 2, 0); + return UnixDateTime::from_unix_time_parts(first_dos_year + date.year, date.month, date.day, time.hour, time.minute, time.second * 2, 0); } DOSPackedDate to_packed_dos_date(unsigned year, unsigned month, unsigned day) diff --git a/AK/DOSPackedTime.h b/AK/DOSPackedTime.h index dfce4114d8c..1b55a0917a4 100644 --- a/AK/DOSPackedTime.h +++ b/AK/DOSPackedTime.h @@ -33,7 +33,7 @@ static_assert(sizeof(DOSPackedDate) == 2); inline constexpr u16 first_dos_year = 1980; -Duration time_from_packed_dos(DOSPackedDate, DOSPackedTime); +UnixDateTime time_from_packed_dos(DOSPackedDate, DOSPackedTime); DOSPackedDate to_packed_dos_date(unsigned year, unsigned month, unsigned day); DOSPackedTime to_packed_dos_time(unsigned hour, unsigned minute, unsigned second); diff --git a/Kernel/Arch/x86_64/RTC.cpp b/Kernel/Arch/x86_64/RTC.cpp index d932e5b422a..788868f158a 100644 --- a/Kernel/Arch/x86_64/RTC.cpp +++ b/Kernel/Arch/x86_64/RTC.cpp @@ -19,9 +19,9 @@ void initialize() s_boot_time = now(); } -Duration boot_time() +UnixDateTime boot_time() { - return Duration::from_timespec({ s_boot_time, 0 }); + return UnixDateTime::from_seconds_since_epoch(s_boot_time); } static bool update_in_progress() diff --git a/Kernel/Arch/x86_64/RTC.h b/Kernel/Arch/x86_64/RTC.h index 859baa82d7d..32e81d5f093 100644 --- a/Kernel/Arch/x86_64/RTC.h +++ b/Kernel/Arch/x86_64/RTC.h @@ -13,6 +13,6 @@ namespace Kernel::RTC { void initialize(); time_t now(); -Duration boot_time(); +UnixDateTime boot_time(); } diff --git a/Kernel/Devices/Audio/IntelHDA/Controller.cpp b/Kernel/Devices/Audio/IntelHDA/Controller.cpp index 0588e47e461..cae6b6800bc 100644 --- a/Kernel/Devices/Audio/IntelHDA/Controller.cpp +++ b/Kernel/Devices/Audio/IntelHDA/Controller.cpp @@ -329,10 +329,11 @@ ErrorOr Controller::get_pcm_output_sample_rate(size_t channel_index) ErrorOr wait_until(size_t delay_in_microseconds, size_t timeout_in_microseconds, Function()> condition) { auto const& time_management = TimeManagement::the(); - u64 start_microseconds = time_management.now().to_microseconds(); + // FIXME: Use monotonic time instead. + u64 start_microseconds = time_management.now().offset_to_epoch().to_microseconds(); while (!TRY(condition())) { microseconds_delay(delay_in_microseconds); - if ((time_management.now().to_microseconds() - start_microseconds) >= timeout_in_microseconds) + if ((time_management.now().offset_to_epoch().to_microseconds() - start_microseconds) >= timeout_in_microseconds) return ETIMEDOUT; } return {}; diff --git a/Kernel/FileSystem/DevPtsFS/Inode.cpp b/Kernel/FileSystem/DevPtsFS/Inode.cpp index 419d73c5bc9..a84917e9947 100644 --- a/Kernel/FileSystem/DevPtsFS/Inode.cpp +++ b/Kernel/FileSystem/DevPtsFS/Inode.cpp @@ -38,7 +38,7 @@ InodeMetadata DevPtsFSInode::metadata() const { if (auto pty = m_pty.strong_ref()) { auto metadata = m_metadata; - metadata.mtime = Duration::from_timespec({ pty->time_of_last_write(), 0 }); + metadata.mtime = pty->time_of_last_write(); return metadata; } return m_metadata; diff --git a/Kernel/FileSystem/Ext2FS/FileSystem.cpp b/Kernel/FileSystem/Ext2FS/FileSystem.cpp index 02e56ea5aab..d5e1160f398 100644 --- a/Kernel/FileSystem/Ext2FS/FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FS/FileSystem.cpp @@ -471,7 +471,7 @@ ErrorOr> Ext2FS::create_inode(Ext2FSInode& parent_inode, St return ENOENT; ext2_inode e2inode {}; - auto now = kgettimeofday().to_truncated_seconds(); + auto now = kgettimeofday().truncated_seconds_since_epoch(); e2inode.i_mode = mode; e2inode.i_uid = uid.value(); e2inode.i_gid = gid.value(); @@ -572,7 +572,7 @@ ErrorOr Ext2FS::free_inode(Ext2FSInode& inode) // NOTE: After this point, the inode metadata is wiped. memset(&inode.m_raw_inode, 0, sizeof(ext2_inode)); - inode.m_raw_inode.i_dtime = kgettimeofday().to_truncated_seconds(); + inode.m_raw_inode.i_dtime = kgettimeofday().truncated_seconds_since_epoch(); TRY(write_ext2_inode(inode.index(), inode.m_raw_inode)); // Mark the inode as free. diff --git a/Kernel/FileSystem/Ext2FS/Inode.cpp b/Kernel/FileSystem/Ext2FS/Inode.cpp index dfd50f124d3..3c5dcaf8ac8 100644 --- a/Kernel/FileSystem/Ext2FS/Inode.cpp +++ b/Kernel/FileSystem/Ext2FS/Inode.cpp @@ -474,10 +474,10 @@ InodeMetadata Ext2FSInode::metadata() const metadata.uid = m_raw_inode.i_uid; metadata.gid = m_raw_inode.i_gid; metadata.link_count = m_raw_inode.i_links_count; - metadata.atime = Duration::from_timespec({ m_raw_inode.i_atime, 0 }); - metadata.ctime = Duration::from_timespec({ m_raw_inode.i_ctime, 0 }); - metadata.mtime = Duration::from_timespec({ m_raw_inode.i_mtime, 0 }); - metadata.dtime = Duration::from_timespec({ m_raw_inode.i_dtime, 0 }); + metadata.atime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_atime); + metadata.ctime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_ctime); + metadata.mtime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_mtime); + metadata.dtime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_dtime); metadata.block_size = fs().block_size(); metadata.block_count = m_raw_inode.i_blocks; @@ -985,7 +985,7 @@ ErrorOr> Ext2FSInode::lookup(StringView name) return fs().get_inode({ fsid(), inode_index }); } -ErrorOr Ext2FSInode::update_timestamps(Optional atime, Optional ctime, Optional mtime) +ErrorOr Ext2FSInode::update_timestamps(Optional atime, Optional ctime, Optional mtime) { MutexLocker locker(m_inode_lock); if (fs().is_readonly()) diff --git a/Kernel/FileSystem/Ext2FS/Inode.h b/Kernel/FileSystem/Ext2FS/Inode.h index cc6acab147f..048c4c55d08 100644 --- a/Kernel/FileSystem/Ext2FS/Inode.h +++ b/Kernel/FileSystem/Ext2FS/Inode.h @@ -37,7 +37,7 @@ private: virtual ErrorOr add_child(Inode& child, StringView name, mode_t) override; virtual ErrorOr remove_child(StringView name) override; virtual ErrorOr replace_child(StringView name, Inode& child) override; - virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime) override; + virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime) override; virtual ErrorOr increment_link_count() override; virtual ErrorOr decrement_link_count() override; virtual ErrorOr chmod(mode_t) override; diff --git a/Kernel/FileSystem/ISO9660FS/Inode.cpp b/Kernel/FileSystem/ISO9660FS/Inode.cpp index 2a1dc195fa0..3f2d4f121b9 100644 --- a/Kernel/FileSystem/ISO9660FS/Inode.cpp +++ b/Kernel/FileSystem/ISO9660FS/Inode.cpp @@ -145,7 +145,7 @@ ErrorOr ISO9660Inode::truncate(u64) return EROFS; } -ErrorOr ISO9660Inode::update_timestamps(Optional, Optional, Optional) +ErrorOr ISO9660Inode::update_timestamps(Optional, Optional, Optional) { return EROFS; } @@ -169,7 +169,7 @@ void ISO9660Inode::create_metadata() { u32 data_length = LittleEndian { m_record.data_length.little }; bool is_directory = has_flag(m_record.file_flags, ISO::FileFlags::Directory); - auto recorded_at = Duration::from_timespec({ parse_numerical_date_time(m_record.recording_date_and_time), 0 }); + auto recorded_at = parse_numerical_date_time(m_record.recording_date_and_time); m_metadata = { .inode = identifier(), @@ -189,16 +189,12 @@ void ISO9660Inode::create_metadata() }; } -time_t ISO9660Inode::parse_numerical_date_time(ISO::NumericalDateAndTime const& date) +UnixDateTime ISO9660Inode::parse_numerical_date_time(ISO::NumericalDateAndTime const& date) { i32 year_offset = date.years_since_1900 - 70; - return (year_offset * 60 * 60 * 24 * 30 * 12) - + (date.month * 60 * 60 * 24 * 30) - + (date.day * 60 * 60 * 24) - + (date.hour * 60 * 60) - + (date.minute * 60) - + date.second; + // FIXME: This ignores timezone information in date. + return UnixDateTime::from_unix_time_parts(year_offset, date.month, date.day, date.hour, date.minute, date.second, 0); } StringView ISO9660Inode::get_normalized_filename(ISO::DirectoryRecordHeader const& record, Bytes buffer) diff --git a/Kernel/FileSystem/ISO9660FS/Inode.h b/Kernel/FileSystem/ISO9660FS/Inode.h index 06ba006205c..dd11d742b18 100644 --- a/Kernel/FileSystem/ISO9660FS/Inode.h +++ b/Kernel/FileSystem/ISO9660FS/Inode.h @@ -32,7 +32,7 @@ public: virtual ErrorOr chmod(mode_t) override; virtual ErrorOr chown(UserID, GroupID) override; virtual ErrorOr truncate(u64) override; - virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime) override; + virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime) override; private: // HACK: The base ISO 9660 standard says the maximum filename length is 37 @@ -51,7 +51,7 @@ private: static StringView get_normalized_filename(ISO::DirectoryRecordHeader const& record, Bytes buffer); void create_metadata(); - time_t parse_numerical_date_time(ISO::NumericalDateAndTime const&); + UnixDateTime parse_numerical_date_time(ISO::NumericalDateAndTime const&); InodeMetadata m_metadata; ISO::DirectoryRecordHeader m_record; diff --git a/Kernel/FileSystem/Inode.cpp b/Kernel/FileSystem/Inode.cpp index 5e2809ef9ef..ddfd99e2a2d 100644 --- a/Kernel/FileSystem/Inode.cpp +++ b/Kernel/FileSystem/Inode.cpp @@ -115,7 +115,7 @@ ErrorOr Inode::read_until_filled_or_end(off_t offset, size_t length, Use return length - remaining_length; } -ErrorOr Inode::update_timestamps([[maybe_unused]] Optional atime, [[maybe_unused]] Optional ctime, [[maybe_unused]] Optional mtime) +ErrorOr Inode::update_timestamps([[maybe_unused]] Optional atime, [[maybe_unused]] Optional ctime, [[maybe_unused]] Optional mtime) { return ENOTIMPL; } diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h index 5bd7298c5f8..e0acae019ee 100644 --- a/Kernel/FileSystem/Inode.h +++ b/Kernel/FileSystem/Inode.h @@ -82,7 +82,7 @@ public: bool is_metadata_dirty() const { return m_metadata_dirty; } - virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime); + virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime); virtual ErrorOr increment_link_count(); virtual ErrorOr decrement_link_count(); diff --git a/Kernel/FileSystem/InodeMetadata.h b/Kernel/FileSystem/InodeMetadata.h index 6cd5e77e901..109bf0b7e4e 100644 --- a/Kernel/FileSystem/InodeMetadata.h +++ b/Kernel/FileSystem/InodeMetadata.h @@ -120,10 +120,10 @@ struct InodeMetadata { UserID uid { 0 }; GroupID gid { 0 }; nlink_t link_count { 0 }; - Duration atime {}; - Duration ctime {}; - Duration mtime {}; - Duration dtime {}; + UnixDateTime atime {}; + UnixDateTime ctime {}; + UnixDateTime mtime {}; + UnixDateTime dtime {}; blkcnt_t block_count { 0 }; blksize_t block_size { 0 }; MajorNumber major_device { 0 }; diff --git a/Kernel/FileSystem/ProcFS/Inode.h b/Kernel/FileSystem/ProcFS/Inode.h index 97ebb4fa922..f8517b5d99e 100644 --- a/Kernel/FileSystem/ProcFS/Inode.h +++ b/Kernel/FileSystem/ProcFS/Inode.h @@ -54,7 +54,7 @@ private: // ^Inode (Silent ignore handling) virtual ErrorOr flush_metadata() override { return {}; } - virtual ErrorOr update_timestamps(Optional, Optional, Optional) override { return {}; } + virtual ErrorOr update_timestamps(Optional, Optional, Optional) override { return {}; } // ^Inode virtual ErrorOr attach(OpenFileDescription& description) override; diff --git a/Kernel/FileSystem/RAMFS/Inode.cpp b/Kernel/FileSystem/RAMFS/Inode.cpp index 5de6cd654e4..e36d7e22063 100644 --- a/Kernel/FileSystem/RAMFS/Inode.cpp +++ b/Kernel/FileSystem/RAMFS/Inode.cpp @@ -381,7 +381,7 @@ ErrorOr RAMFSInode::truncate(u64 size) return {}; } -ErrorOr RAMFSInode::update_timestamps(Optional atime, Optional ctime, Optional mtime) +ErrorOr RAMFSInode::update_timestamps(Optional atime, Optional ctime, Optional mtime) { MutexLocker locker(m_inode_lock); diff --git a/Kernel/FileSystem/RAMFS/Inode.h b/Kernel/FileSystem/RAMFS/Inode.h index 2d6a07a2e3c..84892044f63 100644 --- a/Kernel/FileSystem/RAMFS/Inode.h +++ b/Kernel/FileSystem/RAMFS/Inode.h @@ -35,7 +35,7 @@ public: virtual ErrorOr chmod(mode_t) override; virtual ErrorOr chown(UserID, GroupID) override; virtual ErrorOr truncate(u64) override; - virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime) override; + virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime) override; private: RAMFSInode(RAMFS& fs, InodeMetadata const& metadata, LockWeakPtr parent); diff --git a/Kernel/FileSystem/SysFS/Inode.cpp b/Kernel/FileSystem/SysFS/Inode.cpp index daa42dff934..970fcfd0990 100644 --- a/Kernel/FileSystem/SysFS/Inode.cpp +++ b/Kernel/FileSystem/SysFS/Inode.cpp @@ -110,7 +110,7 @@ ErrorOr SysFSInode::truncate(u64 size) return m_associated_component->truncate(size); } -ErrorOr SysFSInode::update_timestamps(Optional, Optional, Optional) +ErrorOr SysFSInode::update_timestamps(Optional, Optional, Optional) { return {}; } diff --git a/Kernel/FileSystem/SysFS/Inode.h b/Kernel/FileSystem/SysFS/Inode.h index 172cd6290eb..ea834f45b25 100644 --- a/Kernel/FileSystem/SysFS/Inode.h +++ b/Kernel/FileSystem/SysFS/Inode.h @@ -35,7 +35,7 @@ protected: virtual ErrorOr chmod(mode_t) override; virtual ErrorOr chown(UserID, GroupID) override; virtual ErrorOr truncate(u64) override; - virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime) override; + virtual ErrorOr update_timestamps(Optional atime, Optional ctime, Optional mtime) override; virtual ErrorOr attach(OpenFileDescription& description) override final; virtual void did_seek(OpenFileDescription&, off_t) override final; diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 4a65e0cca9c..006e23fc888 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -306,7 +306,7 @@ ErrorOr VirtualFileSystem::utime(Credentials const& credentials, StringVie if (custody->is_readonly()) return EROFS; - TRY(inode.update_timestamps(Duration::from_timespec({ atime, 0 }), {}, Duration::from_timespec({ mtime, 0 }))); + TRY(inode.update_timestamps(UnixDateTime::from_seconds_since_epoch(atime), {}, UnixDateTime::from_seconds_since_epoch(mtime))); return {}; } @@ -326,9 +326,9 @@ ErrorOr VirtualFileSystem::do_utimens(Credentials const& credentials, Cust // NOTE: A standard ext2 inode cannot store nanosecond timestamps. TRY(inode.update_timestamps( - (atime.tv_nsec != UTIME_OMIT) ? Duration::from_timespec(atime) : Optional {}, + (atime.tv_nsec != UTIME_OMIT) ? UnixDateTime::from_unix_timespec(atime) : Optional {}, {}, - (mtime.tv_nsec != UTIME_OMIT) ? Duration::from_timespec(mtime) : Optional {})); + (mtime.tv_nsec != UTIME_OMIT) ? UnixDateTime::from_unix_timespec(mtime) : Optional {})); return {}; } diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 4094701265e..9b50137132d 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -287,7 +287,7 @@ ErrorOr IPv4Socket::receive_byte_buffered(OpenFileDescription& descripti return nreceived_or_error; } -ErrorOr IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace addr, Userspace addr_length, Duration& packet_timestamp, bool blocking) +ErrorOr IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace addr, Userspace addr_length, UnixDateTime& packet_timestamp, bool blocking) { MutexLocker locker(mutex()); ReceivedPacket taken_packet; @@ -382,7 +382,7 @@ ErrorOr IPv4Socket::receive_packet_buffered(OpenFileDescription& descrip return protocol_receive(packet->data->bytes(), buffer, buffer_length, flags); } -ErrorOr IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace user_addr, Userspace user_addr_length, Duration& packet_timestamp, bool blocking) +ErrorOr IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace user_addr, Userspace user_addr_length, UnixDateTime& packet_timestamp, bool blocking) { if (user_addr_length) { socklen_t addr_length; @@ -415,7 +415,7 @@ ErrorOr IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKer return total_nreceived; } -bool IPv4Socket::did_receive(IPv4Address const& source_address, u16 source_port, ReadonlyBytes packet, Duration const& packet_timestamp) +bool IPv4Socket::did_receive(IPv4Address const& source_address, u16 source_port, ReadonlyBytes packet, UnixDateTime const& packet_timestamp) { MutexLocker locker(mutex()); diff --git a/Kernel/Net/IPv4Socket.h b/Kernel/Net/IPv4Socket.h index 2518df798bc..29e425cd067 100644 --- a/Kernel/Net/IPv4Socket.h +++ b/Kernel/Net/IPv4Socket.h @@ -40,13 +40,13 @@ public: virtual bool can_read(OpenFileDescription const&, u64) const override; virtual bool can_write(OpenFileDescription const&, u64) const override; virtual ErrorOr sendto(OpenFileDescription&, UserOrKernelBuffer const&, size_t, int, Userspace, socklen_t) override; - virtual ErrorOr recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace, Userspace, Duration&, bool blocking) override; + virtual ErrorOr recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace, Userspace, UnixDateTime&, bool blocking) override; virtual ErrorOr setsockopt(int level, int option, Userspace, socklen_t) override; virtual ErrorOr getsockopt(OpenFileDescription&, int level, int option, Userspace, Userspace) override; virtual ErrorOr ioctl(OpenFileDescription&, unsigned request, Userspace arg) override; - bool did_receive(IPv4Address const& peer_address, u16 peer_port, ReadonlyBytes, Duration const&); + bool did_receive(IPv4Address const& peer_address, u16 peer_port, ReadonlyBytes, UnixDateTime const&); IPv4Address const& local_address() const { return m_local_address; } u16 local_port() const { return m_local_port; } @@ -99,7 +99,7 @@ private: virtual bool is_ipv4() const override { return true; } ErrorOr receive_byte_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace, Userspace, bool blocking); - ErrorOr receive_packet_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace, Userspace, Duration&, bool blocking); + ErrorOr receive_packet_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace, Userspace, UnixDateTime&, bool blocking); void set_can_read(bool); @@ -112,7 +112,7 @@ private: struct ReceivedPacket { IPv4Address peer_address; u16 peer_port; - Duration timestamp; + UnixDateTime timestamp; OwnPtr data; }; diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index fc625e0c44a..73cddd7c42f 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -333,7 +333,7 @@ DoubleBuffer* LocalSocket::send_buffer_for(OpenFileDescription& description) return nullptr; } -ErrorOr LocalSocket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace, Userspace, Duration&, bool blocking) +ErrorOr LocalSocket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace, Userspace, UnixDateTime&, bool blocking) { auto* socket_buffer = receive_buffer_for(description); if (!socket_buffer) diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h index a573248b0aa..971649db86b 100644 --- a/Kernel/Net/LocalSocket.h +++ b/Kernel/Net/LocalSocket.h @@ -47,7 +47,7 @@ public: virtual bool can_read(OpenFileDescription const&, u64) const override; virtual bool can_write(OpenFileDescription const&, u64) const override; virtual ErrorOr sendto(OpenFileDescription&, UserOrKernelBuffer const&, size_t, int, Userspace, socklen_t) override; - virtual ErrorOr recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace, Userspace, Duration&, bool blocking) override; + virtual ErrorOr recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace, Userspace, UnixDateTime&, bool blocking) override; virtual ErrorOr getsockopt(OpenFileDescription&, int level, int option, Userspace, Userspace) override; virtual ErrorOr ioctl(OpenFileDescription&, unsigned request, Userspace arg) override; virtual ErrorOr chown(Credentials const&, OpenFileDescription&, UserID, GroupID) override; diff --git a/Kernel/Net/NetworkAdapter.cpp b/Kernel/Net/NetworkAdapter.cpp index 3d219952674..d577cfc18a6 100644 --- a/Kernel/Net/NetworkAdapter.cpp +++ b/Kernel/Net/NetworkAdapter.cpp @@ -95,7 +95,7 @@ void NetworkAdapter::did_receive(ReadonlyBytes payload) on_receive(); } -size_t NetworkAdapter::dequeue_packet(u8* buffer, size_t buffer_size, Duration& packet_timestamp) +size_t NetworkAdapter::dequeue_packet(u8* buffer, size_t buffer_size, UnixDateTime& packet_timestamp) { InterruptDisabler disabler; if (m_packet_queue.is_empty()) diff --git a/Kernel/Net/NetworkAdapter.h b/Kernel/Net/NetworkAdapter.h index 7549e8d8f06..caec4a3be00 100644 --- a/Kernel/Net/NetworkAdapter.h +++ b/Kernel/Net/NetworkAdapter.h @@ -29,7 +29,7 @@ class NetworkAdapter; using NetworkByteBuffer = AK::Detail::ByteBuffer<1500>; struct PacketWithTimestamp final : public AtomicRefCounted { - PacketWithTimestamp(NonnullOwnPtr buffer, Duration timestamp) + PacketWithTimestamp(NonnullOwnPtr buffer, UnixDateTime timestamp) : buffer(move(buffer)) , timestamp(timestamp) { @@ -38,7 +38,7 @@ struct PacketWithTimestamp final : public AtomicRefCounted ReadonlyBytes bytes() { return buffer->bytes(); } NonnullOwnPtr buffer; - Duration timestamp; + UnixDateTime timestamp; IntrusiveListNode> packet_node; }; @@ -79,7 +79,7 @@ public: void send(MACAddress const&, ARPPacket const&); void fill_in_ipv4_header(PacketWithTimestamp&, IPv4Address const&, MACAddress const&, IPv4Address const&, IPv4Protocol, size_t, u8 type_of_service, u8 ttl); - size_t dequeue_packet(u8* buffer, size_t buffer_size, Duration& packet_timestamp); + size_t dequeue_packet(u8* buffer, size_t buffer_size, UnixDateTime& packet_timestamp); bool has_queued_packets() const { return !m_packet_queue.is_empty(); } diff --git a/Kernel/Net/NetworkTask.cpp b/Kernel/Net/NetworkTask.cpp index 2f6ad1b9bd7..39ffeef8eb3 100644 --- a/Kernel/Net/NetworkTask.cpp +++ b/Kernel/Net/NetworkTask.cpp @@ -26,10 +26,10 @@ namespace Kernel { static void handle_arp(EthernetFrameHeader const&, size_t frame_size); -static void handle_ipv4(EthernetFrameHeader const&, size_t frame_size, Duration const& packet_timestamp); -static void handle_icmp(EthernetFrameHeader const&, IPv4Packet const&, Duration const& packet_timestamp); -static void handle_udp(IPv4Packet const&, Duration const& packet_timestamp); -static void handle_tcp(IPv4Packet const&, Duration const& packet_timestamp); +static void handle_ipv4(EthernetFrameHeader const&, size_t frame_size, UnixDateTime const& packet_timestamp); +static void handle_icmp(EthernetFrameHeader const&, IPv4Packet const&, UnixDateTime const& packet_timestamp); +static void handle_udp(IPv4Packet const&, UnixDateTime const& packet_timestamp); +static void handle_tcp(IPv4Packet const&, UnixDateTime const& packet_timestamp); static void send_delayed_tcp_ack(TCPSocket& socket); static void send_tcp_rst(IPv4Packet const& ipv4_packet, TCPPacket const& tcp_packet, RefPtr adapter); static void flush_delayed_tcp_acks(); @@ -74,7 +74,7 @@ void NetworkTask_main(void*) }; }); - auto dequeue_packet = [&pending_packets](u8* buffer, size_t buffer_size, Duration& packet_timestamp) -> size_t { + auto dequeue_packet = [&pending_packets](u8* buffer, size_t buffer_size, UnixDateTime& packet_timestamp) -> size_t { if (pending_packets == 0) return 0; size_t packet_size = 0; @@ -94,7 +94,7 @@ void NetworkTask_main(void*) TODO(); auto buffer_region = region_or_error.release_value(); auto buffer = (u8*)buffer_region->vaddr().get(); - Duration packet_timestamp; + UnixDateTime packet_timestamp; for (;;) { flush_delayed_tcp_acks(); @@ -177,7 +177,7 @@ void handle_arp(EthernetFrameHeader const& eth, size_t frame_size) } } -void handle_ipv4(EthernetFrameHeader const& eth, size_t frame_size, Duration const& packet_timestamp) +void handle_ipv4(EthernetFrameHeader const& eth, size_t frame_size, UnixDateTime const& packet_timestamp) { constexpr size_t minimum_ipv4_frame_size = sizeof(EthernetFrameHeader) + sizeof(IPv4Packet); if (frame_size < minimum_ipv4_frame_size) { @@ -222,7 +222,7 @@ void handle_ipv4(EthernetFrameHeader const& eth, size_t frame_size, Duration con } } -void handle_icmp(EthernetFrameHeader const& eth, IPv4Packet const& ipv4_packet, Duration const& packet_timestamp) +void handle_icmp(EthernetFrameHeader const& eth, IPv4Packet const& ipv4_packet, UnixDateTime const& packet_timestamp) { auto& icmp_header = *static_cast(ipv4_packet.payload()); dbgln_if(ICMP_DEBUG, "handle_icmp: source={}, destination={}, type={:#02x}, code={:#02x}", ipv4_packet.source().to_string(), ipv4_packet.destination().to_string(), icmp_header.type(), icmp_header.code()); @@ -273,7 +273,7 @@ void handle_icmp(EthernetFrameHeader const& eth, IPv4Packet const& ipv4_packet, } } -void handle_udp(IPv4Packet const& ipv4_packet, Duration const& packet_timestamp) +void handle_udp(IPv4Packet const& ipv4_packet, UnixDateTime const& packet_timestamp) { if (ipv4_packet.payload_size() < sizeof(UDPPacket)) { dbgln("handle_udp: Packet too small ({}, need {})", ipv4_packet.payload_size(), sizeof(UDPPacket)); @@ -367,7 +367,7 @@ void send_tcp_rst(IPv4Packet const& ipv4_packet, TCPPacket const& tcp_packet, Re routing_decision.adapter->release_packet_buffer(*packet); } -void handle_tcp(IPv4Packet const& ipv4_packet, Duration const& packet_timestamp) +void handle_tcp(IPv4Packet const& ipv4_packet, UnixDateTime const& packet_timestamp) { if (ipv4_packet.payload_size() < sizeof(TCPPacket)) { dbgln("handle_tcp: IPv4 payload is too small to be a TCP packet ({}, need {})", ipv4_packet.payload_size(), sizeof(TCPPacket)); diff --git a/Kernel/Net/Socket.cpp b/Kernel/Net/Socket.cpp index 7ecda5b41dc..61b9034fa89 100644 --- a/Kernel/Net/Socket.cpp +++ b/Kernel/Net/Socket.cpp @@ -245,7 +245,7 @@ ErrorOr Socket::read(OpenFileDescription& description, u64, UserOrKernel { if (is_shut_down_for_reading()) return 0; - Duration t {}; + UnixDateTime t {}; return recvfrom(description, buffer, size, 0, {}, 0, t, description.is_blocking()); } diff --git a/Kernel/Net/Socket.h b/Kernel/Net/Socket.h index ebe42032a85..c18cccc40e9 100644 --- a/Kernel/Net/Socket.h +++ b/Kernel/Net/Socket.h @@ -79,7 +79,7 @@ public: virtual bool is_local() const { return false; } virtual bool is_ipv4() const { return false; } virtual ErrorOr sendto(OpenFileDescription&, UserOrKernelBuffer const&, size_t, int flags, Userspace, socklen_t) = 0; - virtual ErrorOr recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace, Userspace, Duration&, bool blocking) = 0; + virtual ErrorOr recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace, Userspace, UnixDateTime&, bool blocking) = 0; virtual ErrorOr setsockopt(int level, int option, Userspace, socklen_t); virtual ErrorOr getsockopt(OpenFileDescription&, int level, int option, Userspace, Userspace); diff --git a/Kernel/Net/TCPSocket.h b/Kernel/Net/TCPSocket.h index a110cdf421c..19b415ed132 100644 --- a/Kernel/Net/TCPSocket.h +++ b/Kernel/Net/TCPSocket.h @@ -216,11 +216,11 @@ private: u32 m_duplicate_acks { 0 }; u32 m_last_ack_number_sent { 0 }; - Duration m_last_ack_sent_time; + UnixDateTime m_last_ack_sent_time; // FIXME: Make this configurable (sysctl) static constexpr u32 maximum_retransmits = 5; - Duration m_last_retransmit_time; + UnixDateTime m_last_retransmit_time; u32 m_retransmit_attempts { 0 }; // FIXME: Parse window size TCP option from the peer diff --git a/Kernel/PerformanceManager.h b/Kernel/PerformanceManager.h index 6de5155739e..4bd55fde63f 100644 --- a/Kernel/PerformanceManager.h +++ b/Kernel/PerformanceManager.h @@ -164,7 +164,7 @@ public: static void timer_tick(RegisterState const& regs) { - static Duration last_wakeup; + static UnixDateTime last_wakeup; auto now = kgettimeofday(); constexpr auto ideal_interval = Duration::from_microseconds(1000'000 / OPTIMAL_PROFILE_TICKS_PER_SECOND_RATE); auto expected_wakeup = last_wakeup + ideal_interval; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index a597d7876ec..e8b80deead3 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -635,7 +635,7 @@ ErrorOr Process::OpenFileDescriptions::all return EMFILE; } -Duration kgettimeofday() +UnixDateTime kgettimeofday() { return TimeManagement::now(); } @@ -699,7 +699,7 @@ ErrorOr Process::dump_core() return {}; } auto coredump_path = TRY(name().with([&](auto& process_name) { - return KString::formatted("{}/{}_{}_{}", coredump_directory_path->view(), process_name->view(), pid().value(), kgettimeofday().to_truncated_seconds()); + return KString::formatted("{}/{}_{}_{}", coredump_directory_path->view(), process_name->view(), pid().value(), kgettimeofday().seconds_since_epoch()); })); auto coredump = TRY(Coredump::try_create(*this, coredump_path->view())); return coredump->write(); diff --git a/Kernel/Process.h b/Kernel/Process.h index e35fbb0a824..0d3053a30df 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -41,7 +41,7 @@ namespace Kernel { MutexProtected>& hostname(); -Duration kgettimeofday(); +UnixDateTime kgettimeofday(); #define ENUMERATE_PLEDGE_PROMISES \ __ENUMERATE_PLEDGE_PROMISE(stdio) \ diff --git a/Kernel/Syscalls/clock.cpp b/Kernel/Syscalls/clock.cpp index 8d574ab4ea9..04be07de116 100644 --- a/Kernel/Syscalls/clock.cpp +++ b/Kernel/Syscalls/clock.cpp @@ -44,7 +44,7 @@ ErrorOr Process::sys$clock_settime(clockid_t clock_id, Userspaceis_superuser()) return EPERM; - auto time = TRY(copy_time_from_user(user_ts)); + auto time = UnixDateTime::epoch() + TRY(copy_time_from_user(user_ts)); switch (clock_id) { case CLOCK_REALTIME: @@ -110,9 +110,8 @@ ErrorOr Process::sys$adjtime(Userspace user_delta, User { VERIFY_NO_PROCESS_BIG_LOCK(this); if (user_old_delta) { - timespec old_delta_ts = TimeManagement::the().remaining_epoch_time_adjustment(); - timeval old_delta; - timespec_to_timeval(old_delta_ts, old_delta); + auto old_delta_duration = TimeManagement::the().remaining_epoch_time_adjustment(); + auto old_delta = old_delta_duration.to_timeval(); TRY(copy_to_user(user_old_delta, &old_delta)); } @@ -123,8 +122,7 @@ ErrorOr Process::sys$adjtime(Userspace user_delta, User return EPERM; auto delta = TRY(copy_time_from_user(user_delta)); - // FIXME: Should use AK::Duration internally - TimeManagement::the().set_remaining_epoch_time_adjustment(delta.to_timespec()); + TimeManagement::the().set_remaining_epoch_time_adjustment(delta); } return 0; diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp index 10ab6748f69..0c1fdfddb7e 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -272,7 +272,7 @@ ErrorOr Process::sys$recvmsg(int sockfd, Userspace user return 0; auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len)); - Duration timestamp {}; + UnixDateTime timestamp {}; bool blocking = (flags & MSG_DONTWAIT) ? false : description->is_blocking(); auto result = socket.recvfrom(*description, data_buffer, iovs[0].iov_len, flags, user_addr, user_addr_length, timestamp, blocking); diff --git a/Kernel/Syscalls/utime.cpp b/Kernel/Syscalls/utime.cpp index 2c58a4b6938..322dd1251c5 100644 --- a/Kernel/Syscalls/utime.cpp +++ b/Kernel/Syscalls/utime.cpp @@ -19,7 +19,7 @@ ErrorOr Process::sys$utime(Userspace user_path, size_t pat if (user_buf) { TRY(copy_from_user(&buf, user_buf)); } else { - auto now = kgettimeofday().to_truncated_seconds(); + auto now = kgettimeofday().truncated_seconds_since_epoch(); // Not a bug! buf = { now, now }; } diff --git a/Kernel/TTY/SlavePTY.cpp b/Kernel/TTY/SlavePTY.cpp index 7d8550df3b8..8a5fab1a3c2 100644 --- a/Kernel/TTY/SlavePTY.cpp +++ b/Kernel/TTY/SlavePTY.cpp @@ -80,7 +80,7 @@ void SlavePTY::on_master_write(UserOrKernelBuffer const& buffer, size_t size) ErrorOr SlavePTY::on_tty_write(UserOrKernelBuffer const& data, size_t size) { - m_time_of_last_write = kgettimeofday().to_truncated_seconds(); + m_time_of_last_write = kgettimeofday(); return m_master->on_slave_write(data, size); } diff --git a/Kernel/TTY/SlavePTY.h b/Kernel/TTY/SlavePTY.h index 7161fc9082b..548a0d893f1 100644 --- a/Kernel/TTY/SlavePTY.h +++ b/Kernel/TTY/SlavePTY.h @@ -21,7 +21,7 @@ public: void on_master_write(UserOrKernelBuffer const&, size_t); unsigned index() const { return m_index; } - time_t time_of_last_write() const { return m_time_of_last_write; } + UnixDateTime time_of_last_write() const { return m_time_of_last_write; } virtual FileBlockerSet& blocker_set() override; @@ -45,7 +45,7 @@ private: SlavePTY(NonnullRefPtr, unsigned index); NonnullRefPtr const m_master; - time_t m_time_of_last_write { 0 }; + UnixDateTime m_time_of_last_write {}; unsigned m_index { 0 }; mutable IntrusiveListNode m_list_node; diff --git a/Kernel/Time/TimeManagement.cpp b/Kernel/Time/TimeManagement.cpp index 31cb2085b5f..d7c3c187164 100644 --- a/Kernel/Time/TimeManagement.cpp +++ b/Kernel/Time/TimeManagement.cpp @@ -87,9 +87,9 @@ Duration TimeManagement::current_time(clockid_t clock_id) const case CLOCK_MONOTONIC_RAW: return monotonic_time_raw(); case CLOCK_REALTIME: - return epoch_time(TimePrecision::Precise); + return epoch_time(TimePrecision::Precise).offset_to_epoch(); case CLOCK_REALTIME_COARSE: - return epoch_time(TimePrecision::Coarse); + return epoch_time(TimePrecision::Coarse).offset_to_epoch(); default: // Syscall entrypoint is missing a is_valid_clock_id(..) check? VERIFY_NOT_REACHED(); @@ -101,12 +101,13 @@ bool TimeManagement::is_system_timer(HardwareTimerBase const& timer) const return &timer == m_system_timer.ptr(); } -void TimeManagement::set_epoch_time(Duration ts) +void TimeManagement::set_epoch_time(UnixDateTime ts) { + // FIXME: The interrupt disabler intends to enforce atomic update of epoch time and remaining adjustment, + // but that sort of assumption is known to break on SMP. InterruptDisabler disabler; - // FIXME: Should use AK::Duration internally - m_epoch_time = ts.to_timespec(); - m_remaining_epoch_time_adjustment = { 0, 0 }; + m_epoch_time = ts; + m_remaining_epoch_time_adjustment = {}; } Duration TimeManagement::monotonic_time(TimePrecision precision) const @@ -147,16 +148,16 @@ Duration TimeManagement::monotonic_time(TimePrecision precision) const return Duration::from_timespec({ (i64)seconds, (i32)ns }); } -Duration TimeManagement::epoch_time(TimePrecision) const +UnixDateTime TimeManagement::epoch_time(TimePrecision) const { // TODO: Take into account precision - timespec ts; + UnixDateTime time; u32 update_iteration; do { update_iteration = m_update1.load(AK::MemoryOrder::memory_order_acquire); - ts = m_epoch_time; + time = m_epoch_time; } while (update_iteration != m_update2.load(AK::MemoryOrder::memory_order_acquire)); - return Duration::from_timespec(ts); + return time; } u64 TimeManagement::uptime_ms() const @@ -226,7 +227,7 @@ time_t TimeManagement::ticks_per_second() const return m_time_keeper_timer->ticks_per_second(); } -Duration TimeManagement::boot_time() +UnixDateTime TimeManagement::boot_time() { #if ARCH(X86_64) return RTC::boot_time(); @@ -252,14 +253,14 @@ UNMAP_AFTER_INIT TimeManagement::TimeManagement() if (ACPI::is_enabled()) { if (!ACPI::Parser::the()->x86_specific_flags().cmos_rtc_not_present) { RTC::initialize(); - m_epoch_time.tv_sec += boot_time().to_timespec().tv_sec; + m_epoch_time += boot_time().offset_to_epoch(); } else { dmesgln("ACPI: RTC CMOS Not present"); } } else { // We just assume that we can access RTC CMOS, if ACPI isn't usable. RTC::initialize(); - m_epoch_time.tv_sec += boot_time().to_timespec().tv_sec; + m_epoch_time += boot_time().offset_to_epoch(); } if (probe_non_legacy_hardware_timers) { if (!probe_and_set_x86_non_legacy_hardware_timers()) @@ -275,7 +276,7 @@ UNMAP_AFTER_INIT TimeManagement::TimeManagement() #endif } -Duration TimeManagement::now() +UnixDateTime TimeManagement::now() { return s_the.ptr()->epoch_time(); } @@ -437,7 +438,8 @@ void TimeManagement::increment_time_since_boot_hpet() m_seconds_since_boot = seconds_since_boot; m_ticks_this_second = ticks_this_second; // TODO: Apply m_remaining_epoch_time_adjustment - timespec_add(m_epoch_time, { (time_t)(delta_ns / 1000000000), (long)(delta_ns % 1000000000) }, m_epoch_time); + timespec time_adjustment = { (time_t)(delta_ns / 1000000000), (long)(delta_ns % 1000000000) }; + m_epoch_time += Duration::from_timespec(time_adjustment); m_update1.store(update_iteration + 1, AK::MemoryOrder::memory_order_release); @@ -483,20 +485,16 @@ void TimeManagement::increment_time_since_boot() // Compute time adjustment for adjtime. Let the clock run up to 1% fast or slow. // That way, adjtime can adjust up to 36 seconds per hour, without time getting very jumpy. // Once we have a smarter NTP service that also adjusts the frequency instead of just slewing time, maybe we can lower this. - long NanosPerTick = 1'000'000'000 / m_time_keeper_timer->frequency(); - time_t MaxSlewNanos = NanosPerTick / 100; + long nanos_per_tick = 1'000'000'000 / m_time_keeper_timer->frequency(); + time_t max_slew_nanos = nanos_per_tick / 100; u32 update_iteration = m_update2.fetch_add(1, AK::MemoryOrder::memory_order_acquire); - // Clamp twice, to make sure intermediate fits into a long. - long slew_nanos = clamp(clamp(m_remaining_epoch_time_adjustment.tv_sec, (time_t)-1, (time_t)1) * 1'000'000'000 + m_remaining_epoch_time_adjustment.tv_nsec, -MaxSlewNanos, MaxSlewNanos); - timespec slew_nanos_ts; - timespec_sub({ 0, slew_nanos }, { 0, 0 }, slew_nanos_ts); // Normalize tv_nsec to be positive. - timespec_sub(m_remaining_epoch_time_adjustment, slew_nanos_ts, m_remaining_epoch_time_adjustment); + auto slew_nanos = Duration::from_nanoseconds( + clamp(m_remaining_epoch_time_adjustment.to_nanoseconds(), -max_slew_nanos, max_slew_nanos)); + m_remaining_epoch_time_adjustment -= slew_nanos; - timespec epoch_tick = { .tv_sec = 0, .tv_nsec = NanosPerTick }; - epoch_tick.tv_nsec += slew_nanos; // No need for timespec_add(), guaranteed to be in range. - timespec_add(m_epoch_time, epoch_tick, m_epoch_time); + m_epoch_time += Duration::from_nanoseconds(nanos_per_tick + slew_nanos.to_nanoseconds()); if (++m_ticks_this_second >= m_time_keeper_timer->ticks_per_second()) { // FIXME: Synchronize with other clock somehow to prevent drifting apart. @@ -540,7 +538,7 @@ void TimeManagement::update_time_page() { auto& page = time_page(); u32 update_iteration = AK::atomic_fetch_add(&page.update2, 1u, AK::MemoryOrder::memory_order_acquire); - page.clocks[CLOCK_REALTIME_COARSE] = m_epoch_time; + page.clocks[CLOCK_REALTIME_COARSE] = m_epoch_time.to_timespec(); page.clocks[CLOCK_MONOTONIC_COARSE] = monotonic_time(TimePrecision::Coarse).to_timespec(); AK::atomic_store(&page.update1, update_iteration + 1u, AK::MemoryOrder::memory_order_release); } diff --git a/Kernel/Time/TimeManagement.h b/Kernel/Time/TimeManagement.h index 75c161559c0..278852c5bea 100644 --- a/Kernel/Time/TimeManagement.h +++ b/Kernel/Time/TimeManagement.h @@ -48,10 +48,10 @@ public: // TODO: implement return monotonic_time(TimePrecision::Precise); } - Duration epoch_time(TimePrecision = TimePrecision::Precise) const; - void set_epoch_time(Duration); + UnixDateTime epoch_time(TimePrecision = TimePrecision::Precise) const; + void set_epoch_time(UnixDateTime); time_t ticks_per_second() const; - static Duration boot_time(); + static UnixDateTime boot_time(); Duration clock_resolution() const; bool is_system_timer(HardwareTimerBase const&) const; @@ -64,14 +64,12 @@ public: bool disable_profile_timer(); u64 uptime_ms() const; - static Duration now(); + static UnixDateTime now(); - // FIXME: Should use AK::Duration internally - // FIXME: Also, most likely broken, because it does not check m_update[12] for in-progress updates. - timespec remaining_epoch_time_adjustment() const { return m_remaining_epoch_time_adjustment; } - // FIXME: Should use AK::Duration internally - // FIXME: Also, most likely broken, because it does not check m_update[12] for in-progress updates. - void set_remaining_epoch_time_adjustment(timespec const& adjustment) { m_remaining_epoch_time_adjustment = adjustment; } + // FIXME: Most likely broken, because it does not check m_update[12] for in-progress updates. + Duration remaining_epoch_time_adjustment() const { return m_remaining_epoch_time_adjustment; } + // FIXME: Most likely broken, because it does not check m_update[12] for in-progress updates. + void set_remaining_epoch_time_adjustment(Duration adjustment) { m_remaining_epoch_time_adjustment = adjustment; } bool can_query_precise_time() const { return m_can_query_precise_time; } @@ -102,9 +100,8 @@ private: Atomic m_update1 { 0 }; u32 m_ticks_this_second { 0 }; u64 m_seconds_since_boot { 0 }; - // FIXME: Should use AK::Duration internally - timespec m_epoch_time { 0, 0 }; - timespec m_remaining_epoch_time_adjustment { 0, 0 }; + UnixDateTime m_epoch_time {}; + Duration m_remaining_epoch_time_adjustment {}; Atomic m_update2 { 0 }; u32 m_time_ticks_per_second { 0 }; // may be different from interrupts/second (e.g. hpet) diff --git a/Userland/Utilities/unzip.cpp b/Userland/Utilities/unzip.cpp index e5dd6634830..95833bb6dd3 100644 --- a/Userland/Utilities/unzip.cpp +++ b/Userland/Utilities/unzip.cpp @@ -22,7 +22,7 @@ static ErrorOr adjust_modification_time(Archive::ZipMember const& zip_member) { auto time = time_from_packed_dos(zip_member.modification_date, zip_member.modification_time); - auto seconds = static_cast(time.to_seconds()); + auto seconds = static_cast(time.seconds_since_epoch()); struct utimbuf buf { .actime = seconds, .modtime = seconds