diff options
author | kleines Filmröllchen <filmroellchen@serenityos.org> | 2023-03-13 22:11:13 +0100 |
---|---|---|
committer | Jelle Raaijmakers <jelle@gmta.nl> | 2023-05-24 23:18:07 +0200 |
commit | 939600d2d4d2d04524301f4373d76dc3c693923a (patch) | |
tree | f290a9d0ae8ee366df2ba1c0066188cf7dbf189e | |
parent | c1323febc28c4d21b555b2449ec7473dc1c0d568 (diff) | |
download | serenity-939600d2d4d2d04524301f4373d76dc3c693923a.zip |
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.
41 files changed, 115 insertions, 125 deletions
diff --git a/AK/DOSPackedTime.cpp b/AK/DOSPackedTime.cpp index f964db14d2..224db24c30 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 dfce4114d8..1b55a0917a 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 d932e5b422..788868f158 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 859baa82d7..32e81d5f09 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 0588e47e46..cae6b6800b 100644 --- a/Kernel/Devices/Audio/IntelHDA/Controller.cpp +++ b/Kernel/Devices/Audio/IntelHDA/Controller.cpp @@ -329,10 +329,11 @@ ErrorOr<u32> Controller::get_pcm_output_sample_rate(size_t channel_index) ErrorOr<void> wait_until(size_t delay_in_microseconds, size_t timeout_in_microseconds, Function<ErrorOr<bool>()> 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 419d73c5bc..a84917e994 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 02e56ea5aa..d5e1160f39 100644 --- a/Kernel/FileSystem/Ext2FS/FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FS/FileSystem.cpp @@ -471,7 +471,7 @@ ErrorOr<NonnullRefPtr<Inode>> 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<void> 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 dfd50f124d..3c5dcaf8ac 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<NonnullRefPtr<Inode>> Ext2FSInode::lookup(StringView name) return fs().get_inode({ fsid(), inode_index }); } -ErrorOr<void> Ext2FSInode::update_timestamps(Optional<Duration> atime, Optional<Duration> ctime, Optional<Duration> mtime) +ErrorOr<void> Ext2FSInode::update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> 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 cc6acab147..048c4c55d0 100644 --- a/Kernel/FileSystem/Ext2FS/Inode.h +++ b/Kernel/FileSystem/Ext2FS/Inode.h @@ -37,7 +37,7 @@ private: virtual ErrorOr<void> add_child(Inode& child, StringView name, mode_t) override; virtual ErrorOr<void> remove_child(StringView name) override; virtual ErrorOr<void> replace_child(StringView name, Inode& child) override; - virtual ErrorOr<void> update_timestamps(Optional<Duration> atime, Optional<Duration> ctime, Optional<Duration> mtime) override; + virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override; virtual ErrorOr<void> increment_link_count() override; virtual ErrorOr<void> decrement_link_count() override; virtual ErrorOr<void> chmod(mode_t) override; diff --git a/Kernel/FileSystem/ISO9660FS/Inode.cpp b/Kernel/FileSystem/ISO9660FS/Inode.cpp index 2a1dc195fa..3f2d4f121b 100644 --- a/Kernel/FileSystem/ISO9660FS/Inode.cpp +++ b/Kernel/FileSystem/ISO9660FS/Inode.cpp @@ -145,7 +145,7 @@ ErrorOr<void> ISO9660Inode::truncate(u64) return EROFS; } -ErrorOr<void> ISO9660Inode::update_timestamps(Optional<Duration>, Optional<Duration>, Optional<Duration>) +ErrorOr<void> ISO9660Inode::update_timestamps(Optional<UnixDateTime>, Optional<UnixDateTime>, Optional<UnixDateTime>) { 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 06ba006205..dd11d742b1 100644 --- a/Kernel/FileSystem/ISO9660FS/Inode.h +++ b/Kernel/FileSystem/ISO9660FS/Inode.h @@ -32,7 +32,7 @@ public: virtual ErrorOr<void> chmod(mode_t) override; virtual ErrorOr<void> chown(UserID, GroupID) override; virtual ErrorOr<void> truncate(u64) override; - virtual ErrorOr<void> update_timestamps(Optional<Duration> atime, Optional<Duration> ctime, Optional<Duration> mtime) override; + virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> 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 5e2809ef9e..ddfd99e2a2 100644 --- a/Kernel/FileSystem/Inode.cpp +++ b/Kernel/FileSystem/Inode.cpp @@ -115,7 +115,7 @@ ErrorOr<size_t> Inode::read_until_filled_or_end(off_t offset, size_t length, Use return length - remaining_length; } -ErrorOr<void> Inode::update_timestamps([[maybe_unused]] Optional<Duration> atime, [[maybe_unused]] Optional<Duration> ctime, [[maybe_unused]] Optional<Duration> mtime) +ErrorOr<void> Inode::update_timestamps([[maybe_unused]] Optional<UnixDateTime> atime, [[maybe_unused]] Optional<UnixDateTime> ctime, [[maybe_unused]] Optional<UnixDateTime> mtime) { return ENOTIMPL; } diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h index 5bd7298c5f..e0acae019e 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<void> update_timestamps(Optional<Duration> atime, Optional<Duration> ctime, Optional<Duration> mtime); + virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime); virtual ErrorOr<void> increment_link_count(); virtual ErrorOr<void> decrement_link_count(); diff --git a/Kernel/FileSystem/InodeMetadata.h b/Kernel/FileSystem/InodeMetadata.h index 6cd5e77e90..109bf0b7e4 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 97ebb4fa92..f8517b5d99 100644 --- a/Kernel/FileSystem/ProcFS/Inode.h +++ b/Kernel/FileSystem/ProcFS/Inode.h @@ -54,7 +54,7 @@ private: // ^Inode (Silent ignore handling) virtual ErrorOr<void> flush_metadata() override { return {}; } - virtual ErrorOr<void> update_timestamps(Optional<Duration>, Optional<Duration>, Optional<Duration>) override { return {}; } + virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime>, Optional<UnixDateTime>, Optional<UnixDateTime>) override { return {}; } // ^Inode virtual ErrorOr<void> attach(OpenFileDescription& description) override; diff --git a/Kernel/FileSystem/RAMFS/Inode.cpp b/Kernel/FileSystem/RAMFS/Inode.cpp index 5de6cd654e..e36d7e2206 100644 --- a/Kernel/FileSystem/RAMFS/Inode.cpp +++ b/Kernel/FileSystem/RAMFS/Inode.cpp @@ -381,7 +381,7 @@ ErrorOr<void> RAMFSInode::truncate(u64 size) return {}; } -ErrorOr<void> RAMFSInode::update_timestamps(Optional<Duration> atime, Optional<Duration> ctime, Optional<Duration> mtime) +ErrorOr<void> RAMFSInode::update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) { MutexLocker locker(m_inode_lock); diff --git a/Kernel/FileSystem/RAMFS/Inode.h b/Kernel/FileSystem/RAMFS/Inode.h index 2d6a07a2e3..84892044f6 100644 --- a/Kernel/FileSystem/RAMFS/Inode.h +++ b/Kernel/FileSystem/RAMFS/Inode.h @@ -35,7 +35,7 @@ public: virtual ErrorOr<void> chmod(mode_t) override; virtual ErrorOr<void> chown(UserID, GroupID) override; virtual ErrorOr<void> truncate(u64) override; - virtual ErrorOr<void> update_timestamps(Optional<Duration> atime, Optional<Duration> ctime, Optional<Duration> mtime) override; + virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override; private: RAMFSInode(RAMFS& fs, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent); diff --git a/Kernel/FileSystem/SysFS/Inode.cpp b/Kernel/FileSystem/SysFS/Inode.cpp index daa42dff93..970fcfd099 100644 --- a/Kernel/FileSystem/SysFS/Inode.cpp +++ b/Kernel/FileSystem/SysFS/Inode.cpp @@ -110,7 +110,7 @@ ErrorOr<void> SysFSInode::truncate(u64 size) return m_associated_component->truncate(size); } -ErrorOr<void> SysFSInode::update_timestamps(Optional<Duration>, Optional<Duration>, Optional<Duration>) +ErrorOr<void> SysFSInode::update_timestamps(Optional<UnixDateTime>, Optional<UnixDateTime>, Optional<UnixDateTime>) { return {}; } diff --git a/Kernel/FileSystem/SysFS/Inode.h b/Kernel/FileSystem/SysFS/Inode.h index 172cd6290e..ea834f45b2 100644 --- a/Kernel/FileSystem/SysFS/Inode.h +++ b/Kernel/FileSystem/SysFS/Inode.h @@ -35,7 +35,7 @@ protected: virtual ErrorOr<void> chmod(mode_t) override; virtual ErrorOr<void> chown(UserID, GroupID) override; virtual ErrorOr<void> truncate(u64) override; - virtual ErrorOr<void> update_timestamps(Optional<Duration> atime, Optional<Duration> ctime, Optional<Duration> mtime) override; + virtual ErrorOr<void> update_timestamps(Optional<UnixDateTime> atime, Optional<UnixDateTime> ctime, Optional<UnixDateTime> mtime) override; virtual ErrorOr<void> 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 4a65e0cca9..006e23fc88 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -306,7 +306,7 @@ ErrorOr<void> 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<void> 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<Duration> {}, + (atime.tv_nsec != UTIME_OMIT) ? UnixDateTime::from_unix_timespec(atime) : Optional<UnixDateTime> {}, {}, - (mtime.tv_nsec != UTIME_OMIT) ? Duration::from_timespec(mtime) : Optional<Duration> {})); + (mtime.tv_nsec != UTIME_OMIT) ? UnixDateTime::from_unix_timespec(mtime) : Optional<UnixDateTime> {})); return {}; } diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 4094701265..9b50137132 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -287,7 +287,7 @@ ErrorOr<size_t> IPv4Socket::receive_byte_buffered(OpenFileDescription& descripti return nreceived_or_error; } -ErrorOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> addr, Userspace<socklen_t*> addr_length, Duration& packet_timestamp, bool blocking) +ErrorOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> addr, Userspace<socklen_t*> addr_length, UnixDateTime& packet_timestamp, bool blocking) { MutexLocker locker(mutex()); ReceivedPacket taken_packet; @@ -382,7 +382,7 @@ ErrorOr<size_t> IPv4Socket::receive_packet_buffered(OpenFileDescription& descrip return protocol_receive(packet->data->bytes(), buffer, buffer_length, flags); } -ErrorOr<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> user_addr, Userspace<socklen_t*> user_addr_length, Duration& packet_timestamp, bool blocking) +ErrorOr<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*> user_addr, Userspace<socklen_t*> user_addr_length, UnixDateTime& packet_timestamp, bool blocking) { if (user_addr_length) { socklen_t addr_length; @@ -415,7 +415,7 @@ ErrorOr<size_t> 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 2518df798b..29e425cd06 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<size_t> sendto(OpenFileDescription&, UserOrKernelBuffer const&, size_t, int, Userspace<sockaddr const*>, socklen_t) override; - virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Duration&, bool blocking) override; + virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, UnixDateTime&, bool blocking) override; virtual ErrorOr<void> setsockopt(int level, int option, Userspace<void const*>, socklen_t) override; virtual ErrorOr<void> getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override; virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> 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<size_t> receive_byte_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, bool blocking); - ErrorOr<size_t> receive_packet_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Duration&, bool blocking); + ErrorOr<size_t> receive_packet_buffered(OpenFileDescription&, UserOrKernelBuffer& buffer, size_t buffer_length, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, 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<KBuffer> data; }; diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index fc625e0c44..73cddd7c42 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<size_t> LocalSocket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace<sockaddr*>, Userspace<socklen_t*>, Duration&, bool blocking) +ErrorOr<size_t> LocalSocket::recvfrom(OpenFileDescription& description, UserOrKernelBuffer& buffer, size_t buffer_size, int, Userspace<sockaddr*>, Userspace<socklen_t*>, 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 a573248b0a..971649db86 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<size_t> sendto(OpenFileDescription&, UserOrKernelBuffer const&, size_t, int, Userspace<sockaddr const*>, socklen_t) override; - virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Duration&, bool blocking) override; + virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, UnixDateTime&, bool blocking) override; virtual ErrorOr<void> getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>) override; virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override; virtual ErrorOr<void> chown(Credentials const&, OpenFileDescription&, UserID, GroupID) override; diff --git a/Kernel/Net/NetworkAdapter.cpp b/Kernel/Net/NetworkAdapter.cpp index 3d21995267..d577cfc18a 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 7549e8d8f0..caec4a3be0 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> { - PacketWithTimestamp(NonnullOwnPtr<KBuffer> buffer, Duration timestamp) + PacketWithTimestamp(NonnullOwnPtr<KBuffer> buffer, UnixDateTime timestamp) : buffer(move(buffer)) , timestamp(timestamp) { @@ -38,7 +38,7 @@ struct PacketWithTimestamp final : public AtomicRefCounted<PacketWithTimestamp> ReadonlyBytes bytes() { return buffer->bytes(); } NonnullOwnPtr<KBuffer> buffer; - Duration timestamp; + UnixDateTime timestamp; IntrusiveListNode<PacketWithTimestamp, RefPtr<PacketWithTimestamp>> 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 2f6ad1b9bd..39ffeef8eb 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<NetworkAdapter> 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<ICMPHeader const*>(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 7ecda5b41d..61b9034fa8 100644 --- a/Kernel/Net/Socket.cpp +++ b/Kernel/Net/Socket.cpp @@ -245,7 +245,7 @@ ErrorOr<size_t> 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 ebe42032a8..c18cccc40e 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<size_t> sendto(OpenFileDescription&, UserOrKernelBuffer const&, size_t, int flags, Userspace<sockaddr const*>, socklen_t) = 0; - virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, Duration&, bool blocking) = 0; + virtual ErrorOr<size_t> recvfrom(OpenFileDescription&, UserOrKernelBuffer&, size_t, int flags, Userspace<sockaddr*>, Userspace<socklen_t*>, UnixDateTime&, bool blocking) = 0; virtual ErrorOr<void> setsockopt(int level, int option, Userspace<void const*>, socklen_t); virtual ErrorOr<void> getsockopt(OpenFileDescription&, int level, int option, Userspace<void*>, Userspace<socklen_t*>); diff --git a/Kernel/Net/TCPSocket.h b/Kernel/Net/TCPSocket.h index a110cdf421..19b415ed13 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 6de5155739..4bd55fde63 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 a597d7876e..e8b80deead 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -635,7 +635,7 @@ ErrorOr<Process::ScopedDescriptionAllocation> Process::OpenFileDescriptions::all return EMFILE; } -Duration kgettimeofday() +UnixDateTime kgettimeofday() { return TimeManagement::now(); } @@ -699,7 +699,7 @@ ErrorOr<void> 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 e35fbb0a82..0d3053a30d 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -41,7 +41,7 @@ namespace Kernel { MutexProtected<OwnPtr<KString>>& 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 8d574ab4ea..04be07de11 100644 --- a/Kernel/Syscalls/clock.cpp +++ b/Kernel/Syscalls/clock.cpp @@ -44,7 +44,7 @@ ErrorOr<FlatPtr> Process::sys$clock_settime(clockid_t clock_id, Userspace<timesp if (!credentials->is_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<FlatPtr> Process::sys$adjtime(Userspace<timeval const*> 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<FlatPtr> Process::sys$adjtime(Userspace<timeval const*> 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 10ab6748f6..0c1fdfddb7 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -272,7 +272,7 @@ ErrorOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> 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 2c58a4b693..322dd1251c 100644 --- a/Kernel/Syscalls/utime.cpp +++ b/Kernel/Syscalls/utime.cpp @@ -19,7 +19,7 @@ ErrorOr<FlatPtr> Process::sys$utime(Userspace<char const*> 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 7d8550df3b..8a5fab1a3c 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<size_t> 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 7161fc9082..548a0d893f 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<MasterPTY>, unsigned index); NonnullRefPtr<MasterPTY> const m_master; - time_t m_time_of_last_write { 0 }; + UnixDateTime m_time_of_last_write {}; unsigned m_index { 0 }; mutable IntrusiveListNode<SlavePTY> m_list_node; diff --git a/Kernel/Time/TimeManagement.cpp b/Kernel/Time/TimeManagement.cpp index 31cb2085b5..d7c3c18716 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 75c161559c..278852c5be 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<u32> 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<u32> 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 e5dd663483..95833bb6dd 100644 --- a/Userland/Utilities/unzip.cpp +++ b/Userland/Utilities/unzip.cpp @@ -22,7 +22,7 @@ static ErrorOr<void> 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_t>(time.to_seconds()); + auto seconds = static_cast<time_t>(time.seconds_since_epoch()); struct utimbuf buf { .actime = seconds, .modtime = seconds |