]> git.saurik.com Git - apple/system_cmds.git/blame - KDBG/MachineThread.hpp
system_cmds-671.10.3.tar.gz
[apple/system_cmds.git] / KDBG / MachineThread.hpp
CommitLineData
bd6521f0
A
1//
2// MachineThread.hpp
3// KDBG
4//
5// Created by James McIlree on 10/26/12.
6// Copyright (c) 2014 Apple. All rights reserved.
7//
8
9template <typename SIZE> class MachineProcess;
10
11enum class kMachineThreadFlag : std::uint32_t {
12 CreatedByPreviousMachineState = 0x00000001,
13 CreatedByThreadMap = 0x00000002,
14 CreatedByTraceDataNewThread = 0x00000004,
15 CreatedByUnknownTidInTrace = 0x00000008,
16 CreatedByForkExecEvent = 0x00000010,
17 CreatedByExecEvent = 0x00000020,
18 IsMain = 0x00000040,
19 IsIdle = 0x00000080,
20 TraceTerminated = 0x00000200, // Set when a MACH_THREAD_TERMINATED is seen. This is definitive, no further trace events should reference this thread.
21};
22
23template <typename SIZE> class Machine;
24template <typename SIZE> class JetsamActivity;
25template <typename SIZE> class MachineVoucher;
26
27template <typename SIZE>
28class MachineThread {
29 protected:
30 uint32_t _flags;
31 typename SIZE::ptr_t _tid; // We're unlikely to ever look at K64 on a 32 bit machine, put this here as best chance to not increase struct size with useless padding bytes.
32 MachineProcess<SIZE>* _process;
33 AbsInterval _timespan;
34 AbsTime _begin_blocked;
35 AbsTime _begin_vm_fault;
36 AbsTime _begin_jetsam_activity;
37 uint32_t _begin_jetsam_activity_type;
38 std::vector<AbsInterval> _blocked;
39 std::vector<AbsInterval> _vm_faults;
40 std::vector<AbsInterval> _jetsam_activity;
41 std::vector<VoucherInterval<SIZE>> _vouchers_by_time;
42
43 //
44 // Mutable API
45 //
46 friend class Machine<SIZE>;
47 friend class MachineProcess<SIZE>;
48
49 MachineProcess<SIZE>& mutable_process() { return *_process; }
50
51 void set_flags(kMachineThreadFlag flags) { _flags |= (uint32_t)flags; }
52 void clear_flags(kMachineThreadFlag flags) { _flags &= ~(uint32_t)flags; }
53 bool is_flag_set(kMachineThreadFlag flag) const { return (_flags & (uint32_t)flag) > 0; }
54
55 // This can be discovered after the thread is created.
56 void set_is_idle_thread();
57 void set_trace_terminated(AbsTime timestamp);
58
59 void set_voucher(MachineVoucher<SIZE>* voucher, AbsTime timestamp);
60
61 //
62 // NOTE! Unrunnable/blocked isn't quite exact; it doesn't match
63 // the scheduler view of unrunnable/blocked.
64 //
65 // 1) If you're not blocked, you're runnable
66 // 2) A thread is considered "blocked" if the cpu it is on goes idle.
67 //
68 void make_runnable(AbsTime timestamp);
69 void make_unrunnable(AbsTime timestamp);
70
71 void begin_vm_fault(AbsTime timestamp);
72 void end_vm_fault(AbsTime timestamp);
73
74 void begin_jetsam_activity(uint32_t type, AbsTime timestamp);
75 void end_jetsam_activity(uint32_t type, AbsTime timestamp);
76
77 void add_io_activity(AbsInterval interval, uint32_t code, uint32_t page_count);
78
79 AbsTime blocked_in_timespan(AbsInterval timespan) const;
80 AbsTime next_blocked_after(AbsTime timestamp) const;
81
82 // This is called after all events have been processed, to flush any pending state
83 void post_initialize(AbsTime last_machine_timestamp);
84
85 public:
86 MachineThread(MachineProcess<SIZE>* process, typename SIZE::ptr_t tid, MachineVoucher<SIZE>* initial_voucher, AbsTime create_timestamp, kMachineThreadFlag flags) :
87 _flags((uint32_t)flags),
88 _tid(tid),
89 _process(process),
90 _timespan(create_timestamp, AbsTime(0)),
91 _begin_jetsam_activity_type(0)
92 {
93 ASSERT(_tid != 0, "Sanity");
94 ASSERT(_process, "Sanity");
95 ASSERT(initial_voucher, "Sanity");
96
97 _vouchers_by_time.emplace_back(initial_voucher, AbsInterval(create_timestamp, AbsTime::END_OF_TIME - create_timestamp));
98 }
99
100 typename SIZE::ptr_t tid() const { return _tid; }
101 AbsInterval timespan() const { return _timespan; }
102 const MachineProcess<SIZE>& process() const { return *_process; }
103 uint32_t flags() const { return _flags; }
104
105 const MachineVoucher<SIZE>* voucher(AbsTime timestamp) const;
106 const MachineVoucher<SIZE>* last_voucher() const;
107
108 const std::vector<AbsInterval>& vm_faults() const { return _vm_faults; }
109 const std::vector<AbsInterval>& jetsam_activity() const { return _jetsam_activity; }
110
111 bool is_created_by_previous_machine_state() const { return is_flag_set(kMachineThreadFlag::CreatedByPreviousMachineState); }
112 bool is_created_by_thread_map() const { return is_flag_set(kMachineThreadFlag::CreatedByThreadMap); }
113 bool is_created_by_trace_data_new_thread() const { return is_flag_set(kMachineThreadFlag::CreatedByTraceDataNewThread); }
114 bool is_created_by_unknown_tid_in_trace() const { return is_flag_set(kMachineThreadFlag::CreatedByUnknownTidInTrace); }
115 bool is_created_by_fork_exec() const { return is_flag_set(kMachineThreadFlag::CreatedByForkExecEvent); }
116 bool is_created_by_exec() const { return is_flag_set(kMachineThreadFlag::CreatedByExecEvent); }
117
118 bool is_idle_thread() const { return is_flag_set(kMachineThreadFlag::IsIdle); }
119 bool is_main_thread() const { return is_flag_set(kMachineThreadFlag::IsMain); }
120
121 bool is_trace_terminated() const { return is_flag_set(kMachineThreadFlag::TraceTerminated); }
122
123 DEBUG_ONLY(void validate() const;)
124};