Fixed readme and added full event format
parent
f34e7e0dc5
commit
55d3a9baa3
|
@ -1,11 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#define START_OF_HEADER_MARKER 0xee1234ee
|
#define FRAGMENT_HEADER_MARKER 0xee1234ee
|
||||||
|
|
||||||
typedef struct Header {
|
typedef struct Header {
|
||||||
uint32_t startOfHeaderMarker = START_OF_HEADER_MARKER;
|
uint32_t startOfHeaderMarker = FRAGMENT_HEADER_MARKER;
|
||||||
uint32_t headerSize;
|
uint32_t headerSize;
|
||||||
uint32_t fragmentSize;
|
uint32_t fragmentSize;
|
||||||
uint32_t sourceIdentifier;
|
uint32_t sourceIdentifier;
|
||||||
|
@ -48,9 +50,36 @@ void encode_header(uint32_t *buffer, const Header &header) {
|
||||||
std::memcpy(&buffer[7], header.statusElementsArray, header.numberOfStatusElements * sizeof(uint32_t));
|
std::memcpy(&buffer[7], header.statusElementsArray, header.numberOfStatusElements * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void encode_fragment(uint32_t *buffer, const Fragment &fragment){
|
void encode_fragment(uint32_t *buffer, const Fragment &fragment){
|
||||||
encode_header(buffer, fragment.header);
|
encode_header(buffer, fragment.header);
|
||||||
std::memcpy(&buffer[fragment.header.headerSize], fragment.payloadElements, (fragment.header.fragmentSize - fragment.header.headerSize) * sizeof(uint32_t));
|
std::memcpy(&buffer[fragment.header.headerSize], fragment.payloadElements, (fragment.header.fragmentSize - fragment.header.headerSize) * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Fragment decode_fragment(uint32_t *buffer) {
|
||||||
|
Fragment fragment;
|
||||||
|
fragment.header.startOfHeaderMarker = buffer[0];
|
||||||
|
fragment.header.headerSize = buffer[1];
|
||||||
|
fragment.header.fragmentSize = buffer[2];
|
||||||
|
fragment.header.sourceIdentifier = buffer[3];
|
||||||
|
fragment.header.runNumber = buffer[4];
|
||||||
|
fragment.header.detectorEventNumber = buffer[5];
|
||||||
|
fragment.header.numberOfStatusElements = buffer[6];
|
||||||
|
|
||||||
|
uint32_t nStatusElements = fragment.header.numberOfStatusElements;
|
||||||
|
fragment.header.statusElementsArray = new uint32_t[nStatusElements];
|
||||||
|
for (int i = 1; i <= nStatusElements; i++) {
|
||||||
|
fragment.header.statusElementsArray[6+i] = buffer[6+i];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t payload_size = fragment.header.fragmentSize - fragment.header.headerSize;
|
||||||
|
fragment.payloadElements = new uint32_t[payload_size];
|
||||||
|
for (int i = 1; i <= payload_size; i++) {
|
||||||
|
fragment.payloadElements[6+nStatusElements+i] = buffer[6+nStatusElements+i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fragment_dataformat.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define FULL_EVENT_HEADER_MARKER 0xaa1234aa
|
||||||
|
|
||||||
|
typedef struct FullEvent {
|
||||||
|
uint32_t startOfHeaderMarker = FULL_EVENT_HEADER_MARKER;
|
||||||
|
uint32_t headerSize;
|
||||||
|
uint32_t eventSize;
|
||||||
|
uint32_t runNumber;
|
||||||
|
|
||||||
|
Fragment *fragmentsArray;
|
||||||
|
|
||||||
|
}FullEvent;
|
|
@ -3,4 +3,6 @@
|
||||||
### Motivation
|
### Motivation
|
||||||
Scope of this test is simply to verify that TCP communication with epoll doesen't mix data. In particular, it's important to verify that if one big chunk is sent, the TCP protocol doesen't split it into different events for level triggered epoll (ofc it's gonna be splitted due to buf size).
|
Scope of this test is simply to verify that TCP communication with epoll doesen't mix data. In particular, it's important to verify that if one big chunk is sent, the TCP protocol doesen't split it into different events for level triggered epoll (ofc it's gonna be splitted due to buf size).
|
||||||
|
|
||||||
The important thing is that if I send 1MB of data, it doesen't wake up 2 threads listening to the same fd just because TCP split the package (afaik that shouln't happen, but it's always better to verify, since [`epoll()` is fundamentally broken](https://idea.popcount.org/2017-02-20-epoll-is-fundamentally-broken-12/))
|
The important thing is that if I send 1MB of data, it doesen't wake up 2 threads listening to the same fd just because TCP split the package (afaik that shouln't happen, but it's always better to verify, since [`epoll()` is fundamentally broken](https://idea.popcount.org/2017-02-20-epoll-is-fundamentally-broken-12/)).
|
||||||
|
|
||||||
|
Tested on sending buffer of size 1000 (receiving size 8 2 threads) with simulation re-executed 1000 times -> no reordering. This approach should then be considered safe and used in the project.
|
||||||
|
|
Loading…
Reference in New Issue