mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 20:42:43 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									c1323febc2
								
							
						
					
					
						commit
						939600d2d4
					
				
					 41 changed files with 115 additions and 125 deletions
				
			
		|  | @ -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) | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
|  | @ -13,6 +13,6 @@ namespace Kernel::RTC { | |||
| 
 | ||||
| void initialize(); | ||||
| time_t now(); | ||||
| Duration boot_time(); | ||||
| UnixDateTime boot_time(); | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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 {}; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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.
 | ||||
|  |  | |||
|  | @ -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()) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
|  | @ -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(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 }; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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 {}; | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 {}; | ||||
| } | ||||
|  |  | |||
|  | @ -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()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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()) | ||||
|  |  | |||
|  | @ -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(); } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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)); | ||||
|  |  | |||
|  | @ -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()); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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*>); | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ | |||
| namespace Kernel { | ||||
| 
 | ||||
| MutexProtected<OwnPtr<KString>>& hostname(); | ||||
| Duration kgettimeofday(); | ||||
| UnixDateTime kgettimeofday(); | ||||
| 
 | ||||
| #define ENUMERATE_PLEDGE_PROMISES         \ | ||||
|     __ENUMERATE_PLEDGE_PROMISE(stdio)     \ | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 }; | ||||
|     } | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  |  | |||
|  | @ -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)
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 kleines Filmröllchen
						kleines Filmröllchen