5 // Created by James McIlree on 2/20/14.
6 // Copyright (c) 2014 Apple. All rights reserved.
9 #ifndef kernel_perf_cmds_NurseryMachMsg_hpp
10 #define kernel_perf_cmds_NurseryMachMsg_hpp
12 enum class kNurseryMachMsgState : std::uint32_t {
19 template <typename SIZE>
20 class NurseryMachMsg {
23 MachineVoucher<SIZE>* _send_voucher;
25 typename SIZE::ptr_t _send_tid;
26 typename SIZE::ptr_t _kmsg_addr;
28 uint32_t _id; // This is globally unique for EACH message.
29 uint32_t _send_msgh_id;
30 uint32_t _send_msgh_bits; // msgh_bits is modified between send/recv
31 kNurseryMachMsgState _state;
33 // These are intptr_t's so they can be set to -1, indicating "no index"
34 intptr_t _send_event_index;
37 static uint32_t message_id();
39 NurseryMachMsg(typename SIZE::ptr_t kmsg_addr) :
40 _kmsg_addr(kmsg_addr),
41 _state(kNurseryMachMsgState::Uninitialized)
45 void send(uintptr_t index, AbsTime time, typename SIZE::ptr_t tid, typename SIZE::ptr_t kmsg_addr, uint32_t msgh_bits, uint32_t msgh_id, MachineVoucher<SIZE>* voucher);
47 kNurseryMachMsgState state() const { return _state; }
48 void set_state(kNurseryMachMsgState state) { _state = state; }
50 AbsTime send_time() const { return _send_time; }
51 typename SIZE::ptr_t send_tid() const { return _send_tid; }
53 typename SIZE::ptr_t kmsg_addr() const { return _kmsg_addr; }
54 MachineVoucher<SIZE>* send_voucher() const { return _send_voucher; }
56 uint32_t id() const { return _id; }
57 uint32_t send_msgh_id() const { return _send_msgh_id; }
58 uint32_t send_msgh_bits() const { return _send_msgh_bits; }
60 void set_send_event_index(intptr_t value) { _send_event_index = value; }
61 intptr_t send_event_index() const { return _send_event_index; }
64 template <typename SIZE>
65 uint32_t NurseryMachMsg<SIZE>::message_id() {
66 static uint32_t message_id = 1;
67 return OSAtomicIncrement32Barrier((volatile int32_t*)&message_id);
70 template <typename SIZE>
71 void NurseryMachMsg<SIZE>::send(uintptr_t index, AbsTime time, typename SIZE::ptr_t tid, typename SIZE::ptr_t kmsg_addr, uint32_t msgh_bits, uint32_t msgh_id, MachineVoucher<SIZE>* voucher) {
72 ASSERT(_state == kNurseryMachMsgState::Uninitialized || _state == kNurseryMachMsgState::Free, "Calling send when msg is not in Uninitialized/Free state");
73 ASSERT(kmsg_addr == _kmsg_addr, "Sanity");
75 ASSERT(tid, "Sanity");
76 ASSERT(msgh_bits, "Sanity");
78 _id = NurseryMachMsg::message_id();
80 _send_event_index = index;
83 // _kmsg_addr = kmsg_addr;
84 _send_msgh_bits = msgh_bits;
85 _send_msgh_id = msgh_id;
86 _send_voucher = voucher;