X-Git-Url: https://git.saurik.com/apple/system_cmds.git/blobdiff_plain/1a7e3f61d38d679bba59130891c2031b5a0092b6..bd6521f0fc816ab056bc71376f9706a69b3b52c1:/KDBG/MachineThread.impl.hpp?ds=inline diff --git a/KDBG/MachineThread.impl.hpp b/KDBG/MachineThread.impl.hpp new file mode 100644 index 0000000..ed3297d --- /dev/null +++ b/KDBG/MachineThread.impl.hpp @@ -0,0 +1,99 @@ +// +// MachineThread.impl.hpp +// KDBG +// +// Created by James McIlree on 10/30/12. +// Copyright (c) 2014 Apple. All rights reserved. +// + +template +AbsTime MachineThread::blocked_in_timespan(AbsInterval timespan) const { + auto it = std::lower_bound(_blocked.begin(), _blocked.end(), AbsInterval(timespan.location(), AbsTime(1))); + // The lower bound will report that 0 is lower than [ 10, 20 ), need to check contains! + AbsTime blocked_time; + while (it != _blocked.end() && timespan.intersects(*it)) { + blocked_time += timespan.intersection_range(*it).length(); + ++it; + } + + return blocked_time; +} + +template +AbsTime MachineThread::next_blocked_after(AbsTime timestamp) const { + auto it = std::lower_bound(_blocked.begin(), _blocked.end(), AbsInterval(timestamp, AbsTime(1))); + // The lower bound will report that 0 is lower than [ 10, 20 ), need to check contains! + if (it != _blocked.end()) { + if (it->contains(timestamp)) + return timestamp; + + ASSERT(it->location() > timestamp, "Sanity"); + return it->location(); + } + + return _timespan.max(); +} + +template +const MachineVoucher* MachineThread::voucher(AbsTime timestamp) const { + ASSERT(_timespan.contains(timestamp), "Sanity"); + + auto it = std::upper_bound(_vouchers_by_time.begin(), _vouchers_by_time.end(), timestamp, AbsIntervalMaxVsAbsTimeComparator()); + + // The upper bound will report that 0 is lower than [ 10, 20 ), need to check contains! + if (it != _vouchers_by_time.end() && it->contains(timestamp)) { + return it->voucher(); + } + + return &Machine::UnsetVoucher; +} + +template +const MachineVoucher* MachineThread::last_voucher() const { + ASSERT(!_vouchers_by_time.empty(), "Sanity"); + return _vouchers_by_time.back().voucher(); +} + +#if !defined(NDEBUG) && !defined(NS_BLOCK_ASSERTIONS) +template +void MachineThread::validate() const { + ASSERT(_process, "Sanity"); + ASSERT(_process->timespan().contains(timespan()), "Sanity"); + + ASSERT(is_trange_vector_sorted_and_non_overlapping(_blocked), "Sanity"); + ASSERT(is_trange_vector_sorted_and_non_overlapping(_vm_faults), "Sanity"); + ASSERT(is_trange_vector_sorted_and_non_overlapping(_jetsam_activity), "Sanity"); + ASSERT(is_trange_vector_sorted_and_non_overlapping(_vouchers_by_time), "Sanity"); + + if (!_blocked.empty()) { + ASSERT(_timespan.contains(_blocked.front()), "Blocked interval not contained by thread timespan"); + ASSERT(_timespan.contains(_blocked.back()), "Blocked interval not contained by thread timespan"); + } + + if (!_vm_faults.empty()) { + ASSERT(_timespan.contains(_vm_faults.front()), "vm fault interval not contained by thread timespan"); + ASSERT(_timespan.contains(_vm_faults.back()), "vm_fault interval not contained by thread timespan"); + } + + if (!_jetsam_activity.empty()) { + ASSERT(_timespan.contains(_jetsam_activity.front()), "jetsam_activity interval not contained by thread timespan"); + ASSERT(_timespan.contains(_jetsam_activity.back()), "jetsam_activity interval not contained by thread timespan"); + } + + if (!_vouchers_by_time.empty()) { + ASSERT(_timespan.contains(_vouchers_by_time.front()), "vouchers_by_time interval not contained by thread timespan"); + ASSERT(_timespan.contains(_vouchers_by_time.back()), "vouchers_by_time interval not contained by thread timespan"); + } + + ASSERT(!_process->is_trace_terminated() || is_trace_terminated(), "Process is trace terminated but thread is live"); + + // Each thread should have at least one creation flag. + // Note that created by previous machine state is in addition to the + // actual create flag, so does not count + ASSERT(is_created_by_thread_map() || + is_created_by_trace_data_new_thread() || + is_created_by_unknown_tid_in_trace() || + is_created_by_fork_exec() || + is_created_by_exec(), "Should have at least one create flag"); +} +#endif