]> git.saurik.com Git - apple/system_cmds.git/blobdiff - KDBG/MachineThread.impl.hpp
system_cmds-643.30.1.tar.gz
[apple/system_cmds.git] / KDBG / MachineThread.impl.hpp
diff --git a/KDBG/MachineThread.impl.hpp b/KDBG/MachineThread.impl.hpp
new file mode 100644 (file)
index 0000000..ed3297d
--- /dev/null
@@ -0,0 +1,99 @@
+//
+//  MachineThread.impl.hpp
+//  KDBG
+//
+//  Created by James McIlree on 10/30/12.
+//  Copyright (c) 2014 Apple. All rights reserved.
+//
+
+template <typename SIZE>
+AbsTime MachineThread<SIZE>::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 <typename SIZE>
+AbsTime MachineThread<SIZE>::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 <typename SIZE>
+const MachineVoucher<SIZE>* MachineThread<SIZE>::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<SIZE>::UnsetVoucher;
+}
+
+template <typename SIZE>
+const MachineVoucher<SIZE>* MachineThread<SIZE>::last_voucher() const {
+       ASSERT(!_vouchers_by_time.empty(), "Sanity");
+       return _vouchers_by_time.back().voucher();
+}
+
+#if !defined(NDEBUG) && !defined(NS_BLOCK_ASSERTIONS)
+template <typename SIZE>
+void MachineThread<SIZE>::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