1 #include "hmbdc/Copyright.hpp" 4 #include "hmbdc/time/Time.hpp" 5 #include "hmbdc/Config.hpp" 6 #include "hmbdc/app/Logger.hpp" 7 #include "hmbdc/Endian.hpp" 8 #include "hmbdc/MetaUtils.hpp" 9 #include "hmbdc/Exception.hpp" 11 #include <boost/interprocess/managed_shared_memory.hpp> 14 #include <type_traits> 20 namespace hmbdc {
namespace app {
45 #define MessageC typename 46 #define MessageTupleC typename 47 #define MessageForwardIterC typename 61 template <u
int16_t tag>
76 operator << (std::ostream & os,
hasTag const& t) {
77 return os <<
"hasTag=" << tag;
79 uint16_t constexpr getTypeTag()
const {
84 template <u
int16_t tagStart, u
int16_t rangeSize>
88 enum { size =
sizeof(
type)};
92 typeSortIndex = tagStart,
96 static constexpr uint16_t typeTagStart = tagStart;
97 static constexpr uint16_t typeTagRange = rangeSize;
100 : typeTagOffsetInRange(offset) {
101 if (offset >= typeTagRange) {
102 HMBDC_THROW(std::out_of_range, offset <<
" too big for typeTagRange=" << typeTagRange);
106 uint16_t getTypeTag()
const {
return typeTagStart + typeTagOffsetInRange; }
107 void resetTypeTagOffsetInRange(uint16_t newOffset) {
const_cast<XmitEndian<uint16_t>&
>(typeTagOffsetInRange) = newOffset;}
108 XmitEndian<uint16_t>
const typeTagOffsetInRange{0};
111 operator << (std::ostream & os, inTagRange
const& t) {
112 return os <<
"inTagRange tag=" << t.typeTagStart + t.typeTagOffsetInRange;
116 HMBDC_CLASS_HAS_DECLARE(hmbdcShmRefCount);
145 : afterConsumedCleanupFunc(nullptr)
146 , attachment(nullptr)
152 if (afterConsumedCleanupFunc) {
153 afterConsumedCleanupFunc(
this);
154 afterConsumedCleanupFunc =
nullptr;
155 attachment =
nullptr;
161 AfterConsumedCleanupFunc afterConsumedCleanupFunc;
168 boost::interprocess::managed_shared_memory
171 template <MessageC Message>
172 bool holdShmHandle()
const {
173 if constexpr (has_hmbdcShmRefCount<Message>::value) {
174 return Message::is_att_0cpyshm || len >= 1 * 1024 * 1024;
180 XmitEndian<size_t> len;
200 size_t map(
char const* fileName);
201 } __attribute__((aligned (8)));
218 template <
typename Message> Message&
get();
219 template <
typename Message> Message
const&
get()
const;
220 template <
typename Message>
void setPayload(Message
const&);
221 template <
typename Message,
typename ...Args>
void setPayloadInPlace(Args&& ... args);
231 char forbidden[
sizeof(pid_t)];
238 uint16_t inbandUnderlyingTypeTag : 16;
240 uint64_t inbandPayloadLen : 48;
242 uint64_t reserved : 48;
245 static_assert(
sizeof(Scratchpad) ==
sizeof(reserved2) +
sizeof(reserved),
"");
246 static_assert(
sizeof(Scratchpad::seq) ==
sizeof(reserved2) +
sizeof(reserved),
"");
247 Scratchpad& scratchpad() {
return *
reinterpret_cast<Scratchpad*
>(&reserved2);}
248 Scratchpad
const& scratchpad()
const{
return *
reinterpret_cast<Scratchpad const*
>(&reserved2);}
250 std::ostream& operator << (std::ostream& os,
MessageHead const & h) {
251 return os << h.scratchpad().reserved <<
' ' << h.typeTag;
254 template <MessageC Message>
255 static MessageHead const& retrieveFrom(Message
const& m) {
259 } __attribute__((packed));
260 static_assert(
sizeof(
MessageHead) == 8,
"pakcing issue?");
262 template <
typename Message>
264 template <
typename ...Args>
267 , payload(std::forward<Args>(args)...) {
270 if constexpr (std::is_base_of<hasMemoryAttachment, Message>::value) {
271 this->scratchpad().desc.flag = hasMemoryAttachment::flag;
273 if constexpr (Message::hasRange) {
274 this->typeTag = payload.getTypeTag();
276 this->typeTag = Message::typeTag;
289 std::ostream& operator << (std::ostream& os, MessageWrap<Message>
const & w) {
290 return os << static_cast<MessageHead const&>(w) <<
' ' << w.payload;
294 template <
typename Message>
300 template <
typename Message>
302 MessageHead::get()
const{
303 return static_cast<MessageWrap<Message> const*
>(
this)->payload;
306 template <
typename Message>
309 setPayload(Message
const& m) {
310 new (&get<Message>()) Message(m);
311 typeTag = Message::typeTag;
314 template <
typename Message,
typename ...Args>
317 setPayloadInPlace(Args&& ... args) {
318 new (&get<Message>()) Message(std::forward<Args>(args)...);
319 typeTag = Message::typeTag;
326 template <
size_t MaxStreamableSize>
329 char payload[MaxStreamableSize];
330 } __attribute__((__may_alias__, packed));
345 typeSortIndex = 65535,
349 JustBytes(
void const* bytesIn,
size_t len) {
350 memcpy(bytes, bytesIn, len);
358 : hmbdc_ctor_ts(time::SysTime::now()){}
365 std::ostream& operator << (std::ostream& os,
Trace const & t) {
366 return os << t.hmbdc_ctor_ts <<
' ' << t.hmbdc_net_queued_ts <<
' ' << t.hmbdc_dispatched_ts;
374 , payload(bytes, len) {
376 this->scratchpad().desc.flag = hasMemoryAttachment::flag;
382 std::ostream& operator << (std::ostream& os,
MessageWrap const & w) {
383 return os << static_cast<MessageHead const&>(w) <<
" *";
390 template <MessageC Message>
392 static bool constexpr value = [](){
393 if constexpr (std::is_base_of<hasMemoryAttachment, Message>::value) {
394 #if __GNUC_PREREQ(10,0) 395 return offsetof(Message, hasMemoryAttachment::attachment) == 0;
413 return os <<
"StartAttachmentTrain " << m.inbandUnderlyingTypeTag
414 <<
' ' <<
' ' << m.segCount;
416 } __attribute__((aligned(8)));
422 uint16_t inbandUnderlyingTypeTag{0};
424 std::ostream& operator << (std::ostream& os,
MemorySeg const & m) {
425 return os <<
"MemorySeg " << m.seg <<
' ' << m.len <<
' ' << m.inbandUnderlyingTypeTag;
427 } __attribute__((packed));
429 template <MessageC Message>
433 template <
typename ShmAllocator>
436 assert(att.holdShmHandle<Message>());
437 if constexpr (Message::is_att_0cpyshm) {
439 att.shmHandle = allocator.getHandle(att.attachment);
441 auto shmAddr = allocator.allocate(att.len);
442 memcpy(shmAddr, att.attachment, att.len);
443 att.shmHandle = allocator.getHandle(shmAddr);
447 Message underlyingMessage;
449 template <MessageC M>
452 template <
typename ...Args>
454 : underlyingMessage(
std::forward<Args>(args)...) {}
455 using M =
typename std::decay<Message>::type;
456 static_assert(std::is_trivially_destructible<M>::value,
"cannot send message with dtor");
457 } __attribute__((aligned(8)));
463 std::ostream& operator << (std::ostream& os,
InBandMemorySeg const & m) {
464 return os <<
"MemorySegInBand";
466 } __attribute__((packed));
468 template<MessageC Message>
470 template <
typename ...Args>
473 , payload(std::forward<Args>(args)...) {
474 this->scratchpad().ipc.hd.inbandUnderlyingTypeTag
475 = payload.underlyingMessage.getTypeTag();
480 std::ostream& operator << (std::ostream& os
482 return os << static_cast<MessageHead const&>(w) <<
" *";
490 , payload(bytes, len) {
491 this->scratchpad().ipc.hd.inbandUnderlyingTypeTag = tag;
496 std::ostream& operator << (std::ostream& os
498 return os << static_cast<MessageHead const&>(w) <<
" *";
510 template <MessageC Message>
511 constexpr
bool typeTagMatch(uint16_t tag) {
512 if constexpr (Message::justBytes) {
513 return tag > LastSystemMessage::typeTag;
515 if constexpr (Message::hasRange) {
516 return tag >= Message::typeTagStart
517 && tag < Message::typeTagStart + Message::typeTagRange;
519 return tag == Message::typeTag;
525 hasMemoryAttachment::
526 map(
char const* fileName) {
531 fd = open(fileName, O_RDONLY);
533 len = (size_t)sb.st_size;
534 attachment = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
535 if (attachment == MAP_FAILED) {
536 HMBDC_THROW(std::runtime_error,
"map failed for " << fileName);
545 hasMemoryAttachment::
547 ::free(a->attachment);
548 a->attachment =
nullptr;
555 munmap(a->attachment, a->len);
556 a->attachment =
nullptr;
Definition: Message.hpp:371
hasMemoryAttachment(char const *fileName)
file mapped memory
Definition: Message.hpp:144
Definition: Message.hpp:63
Definition: Message.hpp:86
boost::interprocess::managed_shared_memory ::handle_t shmHandle
Definition: Message.hpp:169
Definition: TypedString.hpp:84
each message type has 16 bit tag
Definition: Message.hpp:62
hasMemoryAttachment()
default ctor
Definition: Message.hpp:130
Definition: Message.hpp:327
Definition: Message.hpp:85
static void unmap(hasMemoryAttachment *)
Definition: Message.hpp:554
Definition: Message.hpp:322
Definition: Message.hpp:212
A special type of message only used on the receiving side.
Definition: Message.hpp:341
Definition: Message.hpp:405
Definition: Message.hpp:459
Definition: Message.hpp:391
__attribute__((packed)) desc
not usable when inbandUnderlyingTypeTag is used
hmbdc system messages use tag values less than this one
Definition: Message.hpp:506
Definition: Message.hpp:356
Definition: Message.hpp:263
Definition: Message.hpp:418
if a specific hmbdc network transport (for example tcpcast, rmcast, and rnetmap) supports message wit...
Definition: Message.hpp:125
uint64_t clientData[2]
byte size of the above
Definition: Message.hpp:183
void shmConvert(ShmAllocator &&allocator)
Definition: Message.hpp:434
Definition: Message.hpp:430