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 >= HMBDC_ATTACH_THRU_SHM_POOL_SIZE_THRESH;
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 constexpr Message* tmp =
nullptr;
396 return (
void*)tmp2 == (
void*)tmp;
411 return os <<
"StartAttachmentTrain " << m.inbandUnderlyingTypeTag
412 <<
' ' <<
' ' << m.segCount;
414 } __attribute__((aligned(8)));
420 uint16_t inbandUnderlyingTypeTag{0};
422 std::ostream& operator << (std::ostream& os,
MemorySeg const & m) {
423 return os <<
"MemorySeg " << m.seg <<
' ' << m.len <<
' ' << m.inbandUnderlyingTypeTag;
425 } __attribute__((packed));
427 template <MessageC Message>
431 template <
typename ShmAllocator>
434 assert(att.holdShmHandle<Message>());
435 if constexpr (Message::is_att_0cpyshm) {
437 att.shmHandle = allocator.getHandle(att.attachment);
439 auto shmAddr = allocator.allocate(att.len);
440 memcpy(shmAddr, att.attachment, att.len);
441 att.shmHandle = allocator.getHandle(shmAddr);
445 Message underlyingMessage;
447 template <MessageC M>
450 template <
typename ...Args>
452 : underlyingMessage(
std::forward<Args>(args)...) {}
453 using M =
typename std::decay<Message>::type;
454 static_assert(std::is_trivially_destructible<M>::value,
"cannot send message with dtor");
455 } __attribute__((aligned(8)));
461 std::ostream& operator << (std::ostream& os,
InBandMemorySeg const & m) {
462 return os <<
"MemorySegInBand";
464 } __attribute__((packed));
466 template<MessageC Message>
468 template <
typename ...Args>
471 , payload(std::forward<Args>(args)...) {
472 this->scratchpad().ipc.hd.inbandUnderlyingTypeTag
473 = payload.underlyingMessage.getTypeTag();
478 std::ostream& operator << (std::ostream& os
480 return os << static_cast<MessageHead const&>(w) <<
" *";
488 , payload(bytes, len) {
489 this->scratchpad().ipc.hd.inbandUnderlyingTypeTag = tag;
494 std::ostream& operator << (std::ostream& os
496 return os << static_cast<MessageHead const&>(w) <<
" *";
508 template <MessageC Message>
509 constexpr
bool typeTagMatch(uint16_t tag) {
510 if constexpr (Message::justBytes) {
511 return tag > LastSystemMessage::typeTag;
513 if constexpr (Message::hasRange) {
514 return tag >= Message::typeTagStart
515 && tag < Message::typeTagStart + Message::typeTagRange;
517 return tag == Message::typeTag;
523 hasMemoryAttachment::
524 map(
char const* fileName) {
528 fd = open(fileName, O_RDONLY);
530 len = (size_t)sb.st_size;
531 attachment = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
532 if (attachment == MAP_FAILED) {
533 HMBDC_THROW(std::runtime_error,
"map failed for " << fileName);
542 hasMemoryAttachment::
543 free(hasMemoryAttachment* a) {
544 ::free(a->attachment);
545 a->attachment =
nullptr;
552 munmap(a->attachment, a->len);
553 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:551
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:403
Definition: Message.hpp:457
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:504
Definition: Message.hpp:356
Definition: Message.hpp:263
Definition: Message.hpp:416
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:432
Definition: Message.hpp:428