]> git.saurik.com Git - apple/system_cmds.git/blob - KDBG/MachineMachMsg.hpp
43f4f1db6e1ff9e40b4c2f66ba9280702db814e5
[apple/system_cmds.git] / KDBG / MachineMachMsg.hpp
1 //
2 // MachineMachMsg.hpp
3 // KDBG
4 //
5 // Created by James McIlree on 2/20/14.
6 // Copyright (c) 2014 Apple. All rights reserved.
7 //
8
9 #ifndef kernel_perf_cmds_MachineMachMsg_hpp
10 #define kernel_perf_cmds_MachineMachMsg_hpp
11
12 enum kMachineMachMsgFlag {
13 HasSender = 0x00000001,
14 HasReceiver = 0x00000002,
15 IsVoucherRefused = 0x00000004
16 };
17
18 template <typename SIZE>
19 class MachineMachMsg {
20 protected:
21
22 // POTENTIAL ISSUE:
23 //
24 // We could have a case where a sender queue's a message, then dies before the receiver picks it up.
25 // With a dead thread, the next MachineState will not include the tid, and then we'll be unable to look it up.
26
27 // NOTE NOTE NOTE!
28 //
29 // The instance vars are sorted by size to avoid wasting space.
30 // Don't change without good reason, and add new vars to the
31 // correct location!
32
33 /*
34 * ALWAYS 64b
35 */
36
37 AbsTime _send_time;
38 AbsTime _recv_time;
39
40 /*
41 * LP64 - HOST
42 *
43 * I'm going to assume the most common asymetric pattern is a 64 bit desktop
44 * looking at a 32 bit device...
45 */
46
47 MachineVoucher<SIZE>* _send_voucher;
48 MachineVoucher<SIZE>* _recv_voucher;
49
50 /*
51 * LP64 - SIZE
52 */
53
54 typename SIZE::ptr_t _send_tid;
55 typename SIZE::ptr_t _recv_tid;
56 typename SIZE::ptr_t _kmsg_addr;
57
58
59 /*
60 * ALWAYS 32b
61 */
62
63 uint32_t _id; // This is globally unique for EACH message.
64 uint32_t _send_msgh_bits; // msgh_bits is modified between send/recv
65 uint32_t _recv_msgh_bits;
66 uint32_t _flags;
67
68 public:
69 MachineMachMsg(uint32_t id,
70 typename SIZE::ptr_t kmsg_addr,
71 uint32_t flags,
72 AbsTime send_time,
73 typename SIZE::ptr_t send_tid,
74 uint32_t send_msgh_bits,
75 MachineVoucher<SIZE>* send_voucher,
76 AbsTime recv_time,
77 typename SIZE::ptr_t recv_tid,
78 uint32_t recv_msgh_bits,
79 MachineVoucher<SIZE>* recv_voucher) :
80 _send_time(send_time),
81 _recv_time(recv_time),
82 _send_voucher(send_voucher),
83 _recv_voucher(recv_voucher),
84 _send_tid(send_tid),
85 _recv_tid(recv_tid),
86 _kmsg_addr(kmsg_addr),
87 _id(id),
88 _send_msgh_bits(send_msgh_bits),
89 _recv_msgh_bits(recv_msgh_bits),
90 _flags(flags)
91 {
92 // Should always have a valid pointer, but may be Machine<SIZE>::NullVoucher
93 ASSERT(send_voucher, "Sanity");
94 ASSERT(recv_voucher, "Sanity");
95
96 ASSERT(send_voucher->is_unset() == (MACH_MSGH_BITS_VOUCHER(_send_msgh_bits) == MACH_MSGH_BITS_ZERO), "voucher state disagrees with msgh_bits");
97 ASSERT(recv_voucher->is_unset() == (MACH_MSGH_BITS_VOUCHER(_recv_msgh_bits) == MACH_MSGH_BITS_ZERO), "voucher state disagrees with msgh_bits");
98 }
99
100 bool has_sender() const { return (_flags & kMachineMachMsgFlag::HasSender) > 0; }
101 bool has_receiver() const { return (_flags & kMachineMachMsgFlag::HasReceiver) > 0; }
102
103 uint32_t id() const { return _id; }
104
105 typename SIZE::ptr_t send_tid() const { ASSERT(has_sender(), "No Sender"); return _send_tid; }
106 typename SIZE::ptr_t recv_tid() const { ASSERT(has_receiver(), "No Receiver"); return _recv_tid; }
107
108 AbsTime send_time() const { ASSERT(has_sender(), "No Sender"); return _send_time; }
109 AbsTime recv_time() const { ASSERT(has_receiver(), "No Receiver"); return _recv_time; }
110
111 MachineVoucher<SIZE>* send_voucher() const { ASSERT(has_sender(), "No Sender"); return _send_voucher; }
112 MachineVoucher<SIZE>* recv_voucher() const { ASSERT(has_receiver(), "No Receiver"); return _recv_voucher; }
113
114 uint32_t send_msgh_bits() const { ASSERT(has_sender(), "No Sender"); return _send_msgh_bits; }
115 uint32_t recv_msgh_bits() const { ASSERT(has_receiver(), "No Receiver"); return _recv_msgh_bits; }
116
117 bool is_voucher_refused() const { ASSERT(has_receiver(), "No Receiver"); return (_flags & kMachineMachMsgFlag::IsVoucherRefused) > 0; }
118
119 bool has_send_voucher() const { return has_sender() && MACH_MSGH_BITS_VOUCHER(_send_msgh_bits) != MACH_MSGH_BITS_ZERO; }
120 bool has_recv_voucher() const { return has_receiver() && MACH_MSGH_BITS_VOUCHER(_recv_msgh_bits) != MACH_MSGH_BITS_ZERO; }
121
122 bool has_non_null_send_voucher() const { return has_sender() && MACH_MSGH_BITS_VOUCHER(_send_msgh_bits) != MACH_MSGH_BITS_ZERO && !_send_voucher->is_null(); }
123 bool has_non_null_recv_voucher() const { return has_receiver() && MACH_MSGH_BITS_VOUCHER(_recv_msgh_bits) != MACH_MSGH_BITS_ZERO && !_recv_voucher->is_null(); }
124 };
125
126 #endif