ATLAS Offline Software
Loading...
Searching...
No Matches
ClusterMessage.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
5
6#include <cstdint>
7
9 : ptr(rhs.ptr),
10 len(rhs.len),
11 align(rhs.align),
12 received(rhs.received),
13 evtNumber(rhs.evtNumber),
14 fileNumber(rhs.fileNumber) {
15 rhs.ptr = nullptr;
16 rhs.len = 0;
17 rhs.align = 0;
18 rhs.received = false;
19}
21 : ptr(reinterpret_cast<void*>((std::uint64_t(body[0]) << 32) +
22 std::uint64_t(body[1]))),
23 len((std::uint64_t(body[2]) << 32) + std::uint64_t(body[3])),
24 align((std::uint64_t(body[4]) << 32) + std::uint64_t(body[5])),
25 received(true),
26 evtNumber((std::uint64_t(body[6]) << 32) + std::uint64_t(body[7])),
27 fileNumber((std::uint64_t(body[8]) << 32) + std::uint64_t(body[9])) {}
28
30 if (received) {
31 std::free(ptr);
32 }
33}
34
36 DataDescr&& rhs) noexcept {
37 if (received) {
38 std::free(ptr); // release the object memory before assigning a new one
39 }
40 ptr = rhs.ptr;
41 len = rhs.len;
42 align = rhs.align;
43 received = rhs.received;
44 evtNumber = rhs.evtNumber;
45 fileNumber = rhs.fileNumber;
46 rhs.ptr = nullptr;
47 rhs.len = 0;
48 rhs.align = 0;
49 rhs.received = false;
50 rhs.evtNumber = 0;
51 rhs.fileNumber = 0;
52 return *this;
53}
54
56 : messageType(mType), payload(payload) {
57 if (mType != ClusterMessageType::FinalWorkerStatus &&
58 mType != ClusterMessageType::WorkerError) {
59 throw std::logic_error{std::format(
60 "Incorrect ClusterMessage constructor used for message type {}",
61 mType)};
62 }
63}
64
66 : messageType(mType), payload(payload) {
67 if (mType != ClusterMessageType::ProvideEvent) {
68 throw std::logic_error{std::format(
69 "Incorrect ClusterMessage constructor used for message type {}",
70 mType)};
71 }
72}
73
75 : messageType(mType), payload(std::move(payload)) {
76 if (mType != ClusterMessageType::Data) {
77 throw std::logic_error{std::format(
78 "Incorrect ClusterMessage constructor used for message type {}",
79 mType)};
80 }
81}
82
84 switch (mType) {
85 case ClusterMessageType::RequestEvent:
86 case ClusterMessageType::EventsDone:
87 case ClusterMessageType::EmergencyStop:
88 // OK
89 break;
90 default:
91 throw std::logic_error{std::format(
92 "Incorrect ClusterMessage constructor used for message type {}",
93 mType)};
94 }
95}
96
98
100 const auto& [header, body] = wire_msg;
101 messageType = static_cast<ClusterMessageType>(header[0]);
102 source = header[1];
103 if (body.has_value()) {
104 const auto& body_2 = *body;
105 if (messageType == ClusterMessageType::Data) {
106 payload = DataDescr(body_2);
107 } else {
108 WorkerStatus status{};
109 status.status = StatusCode(body_2[0]);
110 status.createdEvents = body_2[1];
111 status.finishedEvents = body_2[2];
112 status.skippedEvents = body_2[3];
113 payload = status;
114 }
115 } else {
116 if (messageType == ClusterMessageType::ProvideEvent) {
117 payload = int(header[2]);
118 }
119 }
120}
121
123 constexpr int max_tag = 16383;
124 constexpr std::uint64_t lower32 = 0xFFFFFFFF;
125
126 static thread_local int next_msg =
127 1; // This is only ever called from one thread per process
129 header[0] = std::uint32_t(messageType);
130 header[1] = source;
131 if (payload.index() == 3) {
132 next_msg = (next_msg % max_tag) + 1;
133 header[2] = next_msg;
134 WireMsgBody body{};
135 const auto& payload_local = std::get<DataDescr>(payload);
136 body[0] = std::uint32_t(std::uint64_t(payload_local.ptr) >> 32);
137 body[1] = std::uint32_t(std::uint64_t(payload_local.ptr) & lower32);
138 body[2] = std::uint32_t(std::uint64_t(payload_local.len) >> 32);
139 body[3] = std::uint32_t(std::uint64_t(payload_local.len) & lower32);
140 body[4] = std::uint32_t(std::uint64_t(payload_local.align) >> 32);
141 body[5] = std::uint32_t(std::uint64_t(payload_local.align) & lower32);
142 body[6] = std::uint32_t(std::uint64_t(payload_local.evtNumber) >> 32);
143 body[7] = std::uint32_t(std::uint64_t(payload_local.evtNumber) & lower32);
144 body[8] = std::uint32_t(std::uint64_t(payload_local.fileNumber) >> 32);
145 body[9] = std::uint32_t(std::uint64_t(payload_local.fileNumber) & lower32);
146 WireMsg msg{header, std::make_optional(body)};
147 return msg;
148 }
149 if (payload.index() == 2) {
150 next_msg = (next_msg % max_tag) + 1;
151 header[2] = next_msg;
152 WireMsgBody body{};
153 const auto& payload_local = std::get<WorkerStatus>(payload);
154 body[0] = static_cast<int>(payload_local.status.getCode());
155 body[1] = payload_local.createdEvents;
156 body[2] = payload_local.finishedEvents;
157 body[3] = payload_local.skippedEvents;
158 body[4] = body[5] = body[6] = body[7] = body[8] = body[9] = 0;
159 WireMsg msg{header, std::make_optional(body)};
160 return msg;
161 }
162 // else
163 if (payload.index() == 1) { // if we have an int payload
164 header[2] = std::get<int>(payload);
165 } else {
166 header[2] = 0;
167 }
168 WireMsg msg{header, std::nullopt};
169 return msg;
170}
ClusterMessageType
STL namespace.
DataDescr(const T *ptr, std::size_t count=1)
DataDescr & operator=(const DataDescr &)=delete
ClusterMessageType messageType
Payload_t payload
std::tuple< WireMsgHdr, std::optional< WireMsgBody > > WireMsg
std::array< std::uint32_t, 3 > WireMsgHdr
WireMsg wire_msg() const
std::array< std::uint32_t, 10 > WireMsgBody
MsgStream & msg
Definition testRead.cxx:32