]> git.saurik.com Git - apple/system_cmds.git/blob - KDBG/MachineThread.impl.hpp
ed3297d2ffeca470d4c27d817371c5a389074fb5
[apple/system_cmds.git] / KDBG / MachineThread.impl.hpp
1 //
2 // MachineThread.impl.hpp
3 // KDBG
4 //
5 // Created by James McIlree on 10/30/12.
6 // Copyright (c) 2014 Apple. All rights reserved.
7 //
8
9 template <typename SIZE>
10 AbsTime MachineThread<SIZE>::blocked_in_timespan(AbsInterval timespan) const {
11 auto it = std::lower_bound(_blocked.begin(), _blocked.end(), AbsInterval(timespan.location(), AbsTime(1)));
12 // The lower bound will report that 0 is lower than [ 10, 20 ), need to check contains!
13 AbsTime blocked_time;
14 while (it != _blocked.end() && timespan.intersects(*it)) {
15 blocked_time += timespan.intersection_range(*it).length();
16 ++it;
17 }
18
19 return blocked_time;
20 }
21
22 template <typename SIZE>
23 AbsTime MachineThread<SIZE>::next_blocked_after(AbsTime timestamp) const {
24 auto it = std::lower_bound(_blocked.begin(), _blocked.end(), AbsInterval(timestamp, AbsTime(1)));
25 // The lower bound will report that 0 is lower than [ 10, 20 ), need to check contains!
26 if (it != _blocked.end()) {
27 if (it->contains(timestamp))
28 return timestamp;
29
30 ASSERT(it->location() > timestamp, "Sanity");
31 return it->location();
32 }
33
34 return _timespan.max();
35 }
36
37 template <typename SIZE>
38 const MachineVoucher<SIZE>* MachineThread<SIZE>::voucher(AbsTime timestamp) const {
39 ASSERT(_timespan.contains(timestamp), "Sanity");
40
41 auto it = std::upper_bound(_vouchers_by_time.begin(), _vouchers_by_time.end(), timestamp, AbsIntervalMaxVsAbsTimeComparator());
42
43 // The upper bound will report that 0 is lower than [ 10, 20 ), need to check contains!
44 if (it != _vouchers_by_time.end() && it->contains(timestamp)) {
45 return it->voucher();
46 }
47
48 return &Machine<SIZE>::UnsetVoucher;
49 }
50
51 template <typename SIZE>
52 const MachineVoucher<SIZE>* MachineThread<SIZE>::last_voucher() const {
53 ASSERT(!_vouchers_by_time.empty(), "Sanity");
54 return _vouchers_by_time.back().voucher();
55 }
56
57 #if !defined(NDEBUG) && !defined(NS_BLOCK_ASSERTIONS)
58 template <typename SIZE>
59 void MachineThread<SIZE>::validate() const {
60 ASSERT(_process, "Sanity");
61 ASSERT(_process->timespan().contains(timespan()), "Sanity");
62
63 ASSERT(is_trange_vector_sorted_and_non_overlapping(_blocked), "Sanity");
64 ASSERT(is_trange_vector_sorted_and_non_overlapping(_vm_faults), "Sanity");
65 ASSERT(is_trange_vector_sorted_and_non_overlapping(_jetsam_activity), "Sanity");
66 ASSERT(is_trange_vector_sorted_and_non_overlapping(_vouchers_by_time), "Sanity");
67
68 if (!_blocked.empty()) {
69 ASSERT(_timespan.contains(_blocked.front()), "Blocked interval not contained by thread timespan");
70 ASSERT(_timespan.contains(_blocked.back()), "Blocked interval not contained by thread timespan");
71 }
72
73 if (!_vm_faults.empty()) {
74 ASSERT(_timespan.contains(_vm_faults.front()), "vm fault interval not contained by thread timespan");
75 ASSERT(_timespan.contains(_vm_faults.back()), "vm_fault interval not contained by thread timespan");
76 }
77
78 if (!_jetsam_activity.empty()) {
79 ASSERT(_timespan.contains(_jetsam_activity.front()), "jetsam_activity interval not contained by thread timespan");
80 ASSERT(_timespan.contains(_jetsam_activity.back()), "jetsam_activity interval not contained by thread timespan");
81 }
82
83 if (!_vouchers_by_time.empty()) {
84 ASSERT(_timespan.contains(_vouchers_by_time.front()), "vouchers_by_time interval not contained by thread timespan");
85 ASSERT(_timespan.contains(_vouchers_by_time.back()), "vouchers_by_time interval not contained by thread timespan");
86 }
87
88 ASSERT(!_process->is_trace_terminated() || is_trace_terminated(), "Process is trace terminated but thread is live");
89
90 // Each thread should have at least one creation flag.
91 // Note that created by previous machine state is in addition to the
92 // actual create flag, so does not count
93 ASSERT(is_created_by_thread_map() ||
94 is_created_by_trace_data_new_thread() ||
95 is_created_by_unknown_tid_in_trace() ||
96 is_created_by_fork_exec() ||
97 is_created_by_exec(), "Should have at least one create flag");
98 }
99 #endif