mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
Use spaces for indention of C++ comments
Signed-off-by: Steffen Vogel <post@steffenvogel.de>
This commit is contained in:
parent
3ab7b7f84d
commit
84617d71b1
47 changed files with 556 additions and 556 deletions
|
@ -138,15 +138,15 @@ static void *SendToIPPort(void *arg) {
|
|||
OpalSetAsyncSendIconError(0, SendID);
|
||||
|
||||
/* This next call allows the execution of the "asynchronous" process
|
||||
* to actually be synchronous with the model. To achieve this, you
|
||||
* should set the "Sending Mode" in the Async_Send block to
|
||||
* NEED_REPLY_BEFORE_NEXT_SEND or NEED_REPLY_NOW. This will force
|
||||
* the model to wait for this process to call this
|
||||
* OpalAsyncSendRequestDone function before continuing. */
|
||||
* to actually be synchronous with the model. To achieve this, you
|
||||
* should set the "Sending Mode" in the Async_Send block to
|
||||
* NEED_REPLY_BEFORE_NEXT_SEND or NEED_REPLY_NOW. This will force
|
||||
* the model to wait for this process to call this
|
||||
* OpalAsyncSendRequestDone function before continuing. */
|
||||
OpalAsyncSendRequestDone(SendID);
|
||||
|
||||
/* Before continuing, we make sure that the real-time model
|
||||
* has not been stopped. If it has, we quit. */
|
||||
* has not been stopped. If it has, we quit. */
|
||||
ModelState = OpalGetAsyncModelState();
|
||||
} while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP));
|
||||
|
||||
|
@ -271,7 +271,7 @@ static void *RecvFromIPPort(void *arg) {
|
|||
OpalSetAsyncRecvIconData(mdldata, mdldata_size, RecvID);
|
||||
|
||||
/* Before continuing, we make sure that the real-time model
|
||||
* has not been stopped. If it has, we quit. */
|
||||
* has not been stopped. If it has, we quit. */
|
||||
ModelState = OpalGetAsyncModelState();
|
||||
} while ((ModelState != STATE_RESET) && (ModelState != STATE_STOP));
|
||||
|
||||
|
@ -313,7 +313,7 @@ int main(int argc, char *argv[]) {
|
|||
AssignProcToCpu0();
|
||||
|
||||
/* Get IP Controler Parameters (ie: ip address, port number...) and
|
||||
* initialize the device on the QNX node. */
|
||||
* initialize the device on the QNX node. */
|
||||
memset(&IconCtrlStruct, 0, sizeof(IconCtrlStruct));
|
||||
|
||||
ret = OpalGetAsyncCtrlParameters(&IconCtrlStruct, sizeof(IconCtrlStruct));
|
||||
|
|
|
@ -153,9 +153,9 @@ int socket_recv(struct socket *s, char *data, int len, double timeout) {
|
|||
tv.tv_usec = (int)((timeout - tv.tv_sec) * 1000000);
|
||||
|
||||
/* Wait for a packet. We use select() to have a timeout. This is
|
||||
* necessary when reseting the model so we don't wait indefinitely
|
||||
* and prevent the process from exiting and freeing the port for
|
||||
* a future instance (model load). */
|
||||
* necessary when reseting the model so we don't wait indefinitely
|
||||
* and prevent the process from exiting and freeing the port for
|
||||
* a future instance (model load). */
|
||||
ret = select(s->sd + 1, &sd_set, (fd_set *)0, (fd_set *)0, &tv);
|
||||
switch (ret) {
|
||||
case -1: // Error
|
||||
|
@ -165,7 +165,7 @@ int socket_recv(struct socket *s, char *data, int len, double timeout) {
|
|||
default:
|
||||
if (!(FD_ISSET(s->sd, &sd_set))) {
|
||||
/* We received something, but it's not on "sd". Since sd is the only
|
||||
* descriptor in the set... */
|
||||
* descriptor in the set... */
|
||||
OpalPrint("%s: RecvPacket: God, is that You trying to reach me?\n",
|
||||
PROGNAME);
|
||||
return -1;
|
||||
|
|
|
@ -20,27 +20,27 @@ using namespace villas::gpu;
|
|||
__global__ void
|
||||
kernel_mailbox(volatile uint32_t *mailbox, volatile uint32_t* counter)
|
||||
{
|
||||
printf("[gpu] hello!\n");
|
||||
printf("[gpu] mailbox: %p\n", mailbox);
|
||||
printf("[gpu] hello!\n");
|
||||
printf("[gpu] mailbox: %p\n", mailbox);
|
||||
|
||||
printf("[kernel] started\n");
|
||||
printf("[kernel] started\n");
|
||||
|
||||
while (1) {
|
||||
if (*mailbox == 1) {
|
||||
*mailbox = 0;
|
||||
printf("[gpu] counter = %d\n", *counter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
if (*mailbox == 1) {
|
||||
*mailbox = 0;
|
||||
printf("[gpu] counter = %d\n", *counter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("[gpu] quit\n");
|
||||
printf("[gpu] quit\n");
|
||||
}
|
||||
|
||||
__global__ void
|
||||
kernel_memcpy(volatile uint8_t* dst, volatile uint8_t* src, size_t length)
|
||||
{
|
||||
while (length > 0) {
|
||||
*dst++ = *src++;
|
||||
length--;
|
||||
}
|
||||
while (length > 0) {
|
||||
*dst++ = *src++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ bool EMC::read(uint32_t offset, uint32_t length, uint8_t *data) {
|
|||
int ret;
|
||||
|
||||
/* Reset the Flash Device. This clears the ret registers and puts
|
||||
* the device in Read mode.
|
||||
*/
|
||||
* the device in Read mode.
|
||||
*/
|
||||
ret = XFlash_Reset(&xflash);
|
||||
if (ret != XST_SUCCESS)
|
||||
return false;
|
||||
|
@ -87,15 +87,15 @@ bool EMC::flash(uint32_t offset, uint32_t length, uint8_t *data) {
|
|||
uint32_t start = offset;
|
||||
|
||||
/* Reset the Flash Device. This clears the ret registers and puts
|
||||
* the device in Read mode. */
|
||||
* the device in Read mode. */
|
||||
ret = XFlash_Reset(&xflash);
|
||||
if (ret != XST_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Perform an unlock operation before the erase operation for the Intel
|
||||
* Flash. The erase operation will result in an error if the block is
|
||||
* locked. */
|
||||
* Flash. The erase operation will result in an error if the block is
|
||||
* locked. */
|
||||
if ((xflash.CommandSet == XFL_CMDSET_INTEL_STANDARD) ||
|
||||
(xflash.CommandSet == XFL_CMDSET_INTEL_EXTENDED) ||
|
||||
(xflash.CommandSet == XFL_CMDSET_INTEL_G18)) {
|
||||
|
|
|
@ -47,9 +47,9 @@ Test(fpga, dma, .description = "DMA") {
|
|||
size_t len = 4 * (1 << 10);
|
||||
|
||||
#if 0
|
||||
// Allocate memory to use with DMA
|
||||
auto src = HostDmaRam::getAllocator().allocate<char>(len);
|
||||
auto dst = HostDmaRam::getAllocator().allocate<char>(len);
|
||||
// Allocate memory to use with DMA
|
||||
auto src = HostDmaRam::getAllocator().allocate<char>(len);
|
||||
auto dst = HostDmaRam::getAllocator().allocate<char>(len);
|
||||
#elif 0
|
||||
// ... only works with IOMMU enabled currently
|
||||
|
||||
|
|
|
@ -19,40 +19,40 @@ gpu_rtds_rtt_kernel(volatile uint32_t* dataIn, volatile reg_doorbell_t* doorbell
|
|||
volatile uint32_t* dataOut, volatile villas::fpga::ip::ControlRegister* controlRegister,
|
||||
int* run)
|
||||
{
|
||||
printf("[gpu] gpu kernel go\n");
|
||||
printf("[gpu] gpu kernel go\n");
|
||||
|
||||
printf("dataIn: %p\n", dataIn);
|
||||
printf("doorbellIn: %p\n", doorbellIn);
|
||||
printf("dataOut: %p\n", dataOut);
|
||||
printf("control: %p\n", controlRegister);
|
||||
printf("run: %p\n", run);
|
||||
printf("dataIn: %p\n", dataIn);
|
||||
printf("doorbellIn: %p\n", doorbellIn);
|
||||
printf("dataOut: %p\n", dataOut);
|
||||
printf("control: %p\n", controlRegister);
|
||||
printf("run: %p\n", run);
|
||||
|
||||
// *run = reinterpret_cast<bool*>(malloc(sizeof(bool)));
|
||||
// **run = true;
|
||||
// *run = reinterpret_cast<bool*>(malloc(sizeof(bool)));
|
||||
// **run = true;
|
||||
|
||||
uint32_t last_seq;
|
||||
while (*run) {
|
||||
// wait for data
|
||||
// printf("[gpu] wait for data, last_seq=%u\n", last_seq);
|
||||
while (not (doorbellIn->is_valid and (last_seq != doorbellIn->seq_nr)) and *run);
|
||||
// printf("doorbell: 0x%08x\n", doorbellIn->value);
|
||||
uint32_t last_seq;
|
||||
while (*run) {
|
||||
// wait for data
|
||||
// printf("[gpu] wait for data, last_seq=%u\n", last_seq);
|
||||
while (not (doorbellIn->is_valid and (last_seq != doorbellIn->seq_nr)) and *run);
|
||||
// printf("doorbell: 0x%08x\n", doorbellIn->value);
|
||||
|
||||
last_seq = doorbellIn->seq_nr;
|
||||
last_seq = doorbellIn->seq_nr;
|
||||
|
||||
// printf("[gpu] copy data\n");
|
||||
for (size_t i = 0; i < doorbellIn->count; i++) {
|
||||
dataOut[i] = dataIn[i];
|
||||
}
|
||||
// printf("[gpu] copy data\n");
|
||||
for (size_t i = 0; i < doorbellIn->count; i++) {
|
||||
dataOut[i] = dataIn[i];
|
||||
}
|
||||
|
||||
// reset doorbell
|
||||
// printf("[gpu] reset doorbell\n");
|
||||
// doorbellIn->value = 0;
|
||||
// reset doorbell
|
||||
// printf("[gpu] reset doorbell\n");
|
||||
// doorbellIn->value = 0;
|
||||
|
||||
// printf("[gpu] signal go for gpu2rtds\n");
|
||||
controlRegister->ap_start = 1;
|
||||
}
|
||||
// printf("[gpu] signal go for gpu2rtds\n");
|
||||
controlRegister->ap_start = 1;
|
||||
}
|
||||
|
||||
printf("kernel done\n");
|
||||
printf("kernel done\n");
|
||||
}
|
||||
|
||||
static int* run = nullptr;
|
||||
|
@ -60,20 +60,20 @@ static int* run = nullptr;
|
|||
void gpu_rtds_rtt_start(volatile uint32_t* dataIn, volatile reg_doorbell_t* doorbellIn,
|
||||
volatile uint32_t* dataOut, volatile villas::fpga::ip::ControlRegister* controlRegister)
|
||||
{
|
||||
printf("run: %p\n", run);
|
||||
if (run == nullptr) {
|
||||
run = (int*)malloc(sizeof(uint32_t));
|
||||
cudaHostRegister(run, sizeof(uint32_t), 0);
|
||||
}
|
||||
printf("run: %p\n", run);
|
||||
printf("run: %p\n", run);
|
||||
if (run == nullptr) {
|
||||
run = (int*)malloc(sizeof(uint32_t));
|
||||
cudaHostRegister(run, sizeof(uint32_t), 0);
|
||||
}
|
||||
printf("run: %p\n", run);
|
||||
|
||||
*run = 1;
|
||||
gpu_rtds_rtt_kernel<<<1, 1>>>(dataIn, doorbellIn, dataOut, controlRegister, run);
|
||||
printf("[cpu] kernel launched\n");
|
||||
*run = 1;
|
||||
gpu_rtds_rtt_kernel<<<1, 1>>>(dataIn, doorbellIn, dataOut, controlRegister, run);
|
||||
printf("[cpu] kernel launched\n");
|
||||
}
|
||||
|
||||
void gpu_rtds_rtt_stop()
|
||||
{
|
||||
*run = 0;
|
||||
cudaDeviceSynchronize();
|
||||
*run = 0;
|
||||
cudaDeviceSynchronize();
|
||||
}
|
||||
|
|
|
@ -88,9 +88,9 @@ protected:
|
|||
|
||||
public:
|
||||
/* Initialize the API.
|
||||
*
|
||||
* Save references to list of paths / nodes for command execution.
|
||||
*/
|
||||
*
|
||||
* Save references to list of paths / nodes for command execution.
|
||||
*/
|
||||
Api(SuperNode *sn);
|
||||
~Api();
|
||||
|
||||
|
|
|
@ -62,30 +62,30 @@ public:
|
|||
virtual int scan(FILE *f, struct Sample *const smps[], unsigned cnt);
|
||||
|
||||
/* Print \p cnt samples from \p smps into buffer \p buf of length \p len.
|
||||
*
|
||||
* @param buf[out] The buffer which should be filled with serialized data.
|
||||
* @param len[in] The length of the buffer \p buf.
|
||||
* @param rbytes[out] The number of bytes which have been written to \p buf. Ignored if nullptr.
|
||||
* @param smps[in] The array of pointers to samples.
|
||||
* @param cnt[in] The number of pointers in the array \p smps.
|
||||
*
|
||||
* @retval >=0 The number of samples from \p smps which have been written into \p buf.
|
||||
* @retval <0 Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @param buf[out] The buffer which should be filled with serialized data.
|
||||
* @param len[in] The length of the buffer \p buf.
|
||||
* @param rbytes[out] The number of bytes which have been written to \p buf. Ignored if nullptr.
|
||||
* @param smps[in] The array of pointers to samples.
|
||||
* @param cnt[in] The number of pointers in the array \p smps.
|
||||
*
|
||||
* @retval >=0 The number of samples from \p smps which have been written into \p buf.
|
||||
* @retval <0 Something went wrong.
|
||||
*/
|
||||
virtual int sprint(char *buf, size_t len, size_t *wbytes,
|
||||
const struct Sample *const smps[], unsigned cnt) = 0;
|
||||
|
||||
/* Parse samples from the buffer \p buf with a length of \p len bytes.
|
||||
*
|
||||
* @param buf[in] The buffer of data which should be parsed / de-serialized.
|
||||
* @param len[in] The length of the buffer \p buf.
|
||||
* @param rbytes[out] The number of bytes which have been read from \p buf.
|
||||
* @param smps[out] The array of pointers to samples.
|
||||
* @param cnt[in] The number of pointers in the array \p smps.
|
||||
*
|
||||
* @retval >=0 The number of samples which have been parsed from \p buf and written into \p smps.
|
||||
* @retval <0 Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @param buf[in] The buffer of data which should be parsed / de-serialized.
|
||||
* @param len[in] The length of the buffer \p buf.
|
||||
* @param rbytes[out] The number of bytes which have been read from \p buf.
|
||||
* @param smps[out] The array of pointers to samples.
|
||||
* @param cnt[in] The number of pointers in the array \p smps.
|
||||
*
|
||||
* @retval >=0 The number of samples which have been parsed from \p buf and written into \p smps.
|
||||
* @retval <0 Something went wrong.
|
||||
*/
|
||||
virtual int sscan(const char *buf, size_t len, size_t *rbytes,
|
||||
struct Sample *const smps[], unsigned cnt) = 0;
|
||||
|
||||
|
|
|
@ -27,19 +27,19 @@ public:
|
|||
HookList() {}
|
||||
|
||||
/* Parses an object of hooks
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {
|
||||
* stats = {
|
||||
* output = "stdout"
|
||||
* },
|
||||
* skip_first = {
|
||||
* seconds = 10
|
||||
* },
|
||||
* hooks = [ "print" ]
|
||||
* }
|
||||
*/
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {
|
||||
* stats = {
|
||||
* output = "stdout"
|
||||
* },
|
||||
* skip_first = {
|
||||
* seconds = 10
|
||||
* },
|
||||
* hooks = [ "print" ]
|
||||
* }
|
||||
*/
|
||||
void parse(json_t *json, int mask, Path *p, Node *n);
|
||||
|
||||
void check();
|
||||
|
|
|
@ -60,50 +60,50 @@ public:
|
|||
~Interface();
|
||||
|
||||
/* Start interface.
|
||||
*
|
||||
* This setups traffic controls queue discs, network emulation and
|
||||
* maps interface IRQs according to affinity.
|
||||
*
|
||||
* @param i A pointer to the interface structure.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This setups traffic controls queue discs, network emulation and
|
||||
* maps interface IRQs according to affinity.
|
||||
*
|
||||
* @param i A pointer to the interface structure.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int start();
|
||||
|
||||
/* Stop interface
|
||||
*
|
||||
* This resets traffic qdiscs ant network emulation
|
||||
* and maps interface IRQs to all CPUs.
|
||||
*
|
||||
* @param i A pointer to the interface structure.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This resets traffic qdiscs ant network emulation
|
||||
* and maps interface IRQs to all CPUs.
|
||||
*
|
||||
* @param i A pointer to the interface structure.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int stop();
|
||||
|
||||
/* Find existing or create new interface instance on which packets for a certain destination
|
||||
* will leave the system.
|
||||
*/
|
||||
* will leave the system.
|
||||
*/
|
||||
static Interface *getEgress(struct sockaddr *sa, node::SuperNode *sn);
|
||||
|
||||
/* Get all IRQs for this interface.
|
||||
*
|
||||
* Only MSI IRQs are determined by looking at:
|
||||
* /sys/class/net/{ifname}/device/msi_irqs/
|
||||
*
|
||||
* @param i A pointer to the interface structure
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* Only MSI IRQs are determined by looking at:
|
||||
* /sys/class/net/{ifname}/device/msi_irqs/
|
||||
*
|
||||
* @param i A pointer to the interface structure
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int getIRQs();
|
||||
|
||||
/* Change the SMP affinity of NIC interrupts.
|
||||
*
|
||||
* @param i A pointer to the interface structure
|
||||
* @param affinity A mask specifying which cores should handle this interrupt.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @param i A pointer to the interface structure
|
||||
* @param affinity A mask specifying which cores should handle this interrupt.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int setAffinity(int affinity);
|
||||
|
||||
std::string getName() const;
|
||||
|
|
|
@ -50,9 +50,9 @@ public:
|
|||
enum Type type; // The mapping type. Selects one of the union fields below.
|
||||
|
||||
/* The number of values which is covered by this mapping entry.
|
||||
*
|
||||
* A value of 0 indicates that all remaining values starting from the offset of a sample should be mapped.
|
||||
*/
|
||||
*
|
||||
* A value of 0 indicates that all remaining values starting from the offset of a sample should be mapped.
|
||||
*/
|
||||
int length;
|
||||
unsigned offset; // Offset of this mapping entry within sample::data
|
||||
|
||||
|
|
|
@ -115,11 +115,11 @@ public:
|
|||
virtual int prepare();
|
||||
|
||||
/* Parse settings of a node.
|
||||
*
|
||||
* @param json A JSON object containing the configuration of the node.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @param json A JSON object containing the configuration of the node.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
virtual int parse(json_t *json);
|
||||
|
||||
// Validate node configuration.
|
||||
|
@ -148,54 +148,54 @@ public:
|
|||
virtual int restart();
|
||||
|
||||
/* Receive multiple messages at once.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* Messages are received with a single recvmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages will be stored in a circular buffer / array @p m.
|
||||
* Indexes used to address @p m will wrap around after len messages.
|
||||
* Some node-types might only support to receive one message at a time.
|
||||
*
|
||||
* @param smps An array of pointers to memory blocks where the function should store received samples.
|
||||
* @param cnt The number of samples that are allocated by the calling function.
|
||||
* @return The number of messages actually received.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* Messages are received with a single recvmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages will be stored in a circular buffer / array @p m.
|
||||
* Indexes used to address @p m will wrap around after len messages.
|
||||
* Some node-types might only support to receive one message at a time.
|
||||
*
|
||||
* @param smps An array of pointers to memory blocks where the function should store received samples.
|
||||
* @param cnt The number of samples that are allocated by the calling function.
|
||||
* @return The number of messages actually received.
|
||||
*/
|
||||
int read(struct Sample *smps[], unsigned cnt);
|
||||
|
||||
/* Send multiple messages in a single datagram / packet.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* Messages are sent with a single sendmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages have to be stored in a circular buffer / array m.
|
||||
* So the indexes will wrap around after len.
|
||||
*
|
||||
* @param smps An array of pointers to memory blocks where samples read from.
|
||||
* @param cnt The number of samples that are allocated by the calling function.
|
||||
* @return The number of messages actually sent.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* Messages are sent with a single sendmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages have to be stored in a circular buffer / array m.
|
||||
* So the indexes will wrap around after len.
|
||||
*
|
||||
* @param smps An array of pointers to memory blocks where samples read from.
|
||||
* @param cnt The number of samples that are allocated by the calling function.
|
||||
* @return The number of messages actually sent.
|
||||
*/
|
||||
int write(struct Sample *smps[], unsigned cnt);
|
||||
|
||||
// Reverse local and remote socket address.
|
||||
virtual int reverse() { return -1; }
|
||||
|
||||
/* Get a list of file descriptors on which the path should poll
|
||||
* to detect the availability of new samples which can be read.
|
||||
*/
|
||||
* to detect the availability of new samples which can be read.
|
||||
*/
|
||||
virtual std::vector<int> getPollFDs() { return {}; }
|
||||
|
||||
/* Get a list of socket file descriptors which are used by the node
|
||||
* To perform network IO. We use those to selectively apply network emulation
|
||||
*/
|
||||
* To perform network IO. We use those to selectively apply network emulation
|
||||
*/
|
||||
virtual std::vector<int> getNetemFDs() { return {}; }
|
||||
|
||||
/* Get the memory type which this node-type expects.
|
||||
*
|
||||
* This is useful for special node-types like Infiniband, GPUs & FPGAs
|
||||
* which require DMA-backed memory.
|
||||
*/
|
||||
*
|
||||
* This is useful for special node-types like Infiniband, GPUs & FPGAs
|
||||
* which require DMA-backed memory.
|
||||
*/
|
||||
virtual struct villas::node::memory::Type *getMemoryType() {
|
||||
return villas::node::memory::default_type;
|
||||
}
|
||||
|
@ -204,9 +204,9 @@ public:
|
|||
villas::node::NodeFactory *getFactory() const { return factory; }
|
||||
|
||||
/* Return a pointer to a string which should be used to print this node.
|
||||
*
|
||||
* @param n A pointer to the node structure.
|
||||
*/
|
||||
*
|
||||
* @param n A pointer to the node structure.
|
||||
*/
|
||||
std::string getNameShort() const { return name_short; }
|
||||
|
||||
// Return a pointer to a string which should be used to print this node.
|
||||
|
@ -223,15 +223,15 @@ public:
|
|||
}
|
||||
|
||||
/* Return a pointer to a string which should be used to print this node.
|
||||
*
|
||||
* @param n A pointer to the node structure.
|
||||
*/
|
||||
*
|
||||
* @param n A pointer to the node structure.
|
||||
*/
|
||||
const std::string &getNameLong();
|
||||
|
||||
/* Return a list of signals which are sent to this node.
|
||||
*
|
||||
* This list is derived from the path which uses the node as destination.
|
||||
*/
|
||||
*
|
||||
* This list is derived from the path which uses the node as destination.
|
||||
*/
|
||||
SignalList::Ptr getOutputSignals(bool after_hooks = true) const;
|
||||
SignalList::Ptr getInputSignals(bool after_hooks = true) const;
|
||||
|
||||
|
|
|
@ -49,11 +49,11 @@ public:
|
|||
|
||||
/* Parse node connection details.
|
||||
|
||||
*
|
||||
* @param json A JSON object containing the configuration of the node.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @param json A JSON object containing the configuration of the node.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
virtual int parse(json_t *json);
|
||||
|
||||
// Returns a string with a textual represenation of this node.
|
||||
|
@ -61,59 +61,59 @@ public:
|
|||
|
||||
/* Check the current node configuration for plausability and errors.
|
||||
|
||||
*
|
||||
* @retval 0 Success. Node configuration is good.
|
||||
* @retval <0 Error. The node configuration is bogus.
|
||||
*/
|
||||
*
|
||||
* @retval 0 Success. Node configuration is good.
|
||||
* @retval <0 Error. The node configuration is bogus.
|
||||
*/
|
||||
virtual int check();
|
||||
|
||||
virtual int prepare();
|
||||
|
||||
/* Start this node.
|
||||
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
virtual int start();
|
||||
|
||||
/* Stop this node.
|
||||
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
virtual int stop();
|
||||
|
||||
/* Restart this node.
|
||||
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
virtual int restart();
|
||||
|
||||
/* Pause this node.
|
||||
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
virtual int pause();
|
||||
|
||||
/* Resume this node.
|
||||
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
virtual int resume();
|
||||
|
||||
/* Reverse source and destination of a node.
|
||||
|
||||
*/
|
||||
*/
|
||||
virtual int reverse();
|
||||
|
||||
virtual std::vector<int> getPollFDs();
|
||||
|
|
|
@ -37,182 +37,182 @@ public:
|
|||
|
||||
struct {
|
||||
/* Global initialization per node type.
|
||||
*
|
||||
* This callback is invoked once per node-type.
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is invoked once per node-type.
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*start)(SuperNode *sn);
|
||||
|
||||
/* Global de-initialization per node type.
|
||||
*
|
||||
* This callback is invoked once per node-type.
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is invoked once per node-type.
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*stop)();
|
||||
} type;
|
||||
|
||||
/* Initialize a new node instance.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*init)(NodeCompat *n);
|
||||
|
||||
/* Free memory of an instance of this type.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
*/
|
||||
int (*destroy)(NodeCompat *n);
|
||||
|
||||
/* Parse node connection details.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param json A JSON object containing the configuration of the node.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param json A JSON object containing the configuration of the node.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*parse)(NodeCompat *n, json_t *json);
|
||||
|
||||
/* Check the current node configuration for plausability and errors.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Node configuration is good.
|
||||
* @retval <0 Error. The node configuration is bogus.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Node configuration is good.
|
||||
* @retval <0 Error. The node configuration is bogus.
|
||||
*/
|
||||
int (*check)(NodeCompat *n);
|
||||
|
||||
int (*prepare)(NodeCompat *n);
|
||||
|
||||
/* Returns a string with a textual represenation of this node.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @return A pointer to a dynamically allocated string. Must be freed().
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @return A pointer to a dynamically allocated string. Must be freed().
|
||||
*/
|
||||
char *(*print)(NodeCompat *n);
|
||||
|
||||
/* Start this node.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*start)(NodeCompat *n);
|
||||
|
||||
/* Restart this node.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*restart)(NodeCompat *n);
|
||||
|
||||
/* Stop this node.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*stop)(NodeCompat *n);
|
||||
|
||||
/* Pause this node.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*pause)(NodeCompat *n);
|
||||
|
||||
/* Resume this node.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*resume)(NodeCompat *n);
|
||||
|
||||
/* Receive multiple messages at once.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* Messages are received with a single recvmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages will be stored in a circular buffer / array @p m.
|
||||
* Indexes used to address @p m will wrap around after len messages.
|
||||
* Some node-types might only support to receive one message at a time.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param smps An array of pointers to memory blocks where the function should store received samples.
|
||||
* @param cnt The number of samples that are allocated by the calling function.
|
||||
* @param release The number of samples that should be released after read is called.
|
||||
* @return The number of messages actually received.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* Messages are received with a single recvmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages will be stored in a circular buffer / array @p m.
|
||||
* Indexes used to address @p m will wrap around after len messages.
|
||||
* Some node-types might only support to receive one message at a time.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param smps An array of pointers to memory blocks where the function should store received samples.
|
||||
* @param cnt The number of samples that are allocated by the calling function.
|
||||
* @param release The number of samples that should be released after read is called.
|
||||
* @return The number of messages actually received.
|
||||
*/
|
||||
int (*read)(NodeCompat *n, struct Sample *const smps[], unsigned cnt);
|
||||
|
||||
/* Send multiple messages in a single datagram / packet.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* Messages are sent with a single sendmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages have to be stored in a circular buffer / array m.
|
||||
* So the indexes will wrap around after len.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param smps An array of pointers to memory blocks where samples read from.
|
||||
* @param cnt The number of samples that are allocated by the calling function.
|
||||
* @param release The number of samples that should be released after write is called
|
||||
* @return The number of messages actually sent.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* Messages are sent with a single sendmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages have to be stored in a circular buffer / array m.
|
||||
* So the indexes will wrap around after len.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param smps An array of pointers to memory blocks where samples read from.
|
||||
* @param cnt The number of samples that are allocated by the calling function.
|
||||
* @param release The number of samples that should be released after write is called
|
||||
* @return The number of messages actually sent.
|
||||
*/
|
||||
int (*write)(NodeCompat *n, struct Sample *const smps[], unsigned cnt);
|
||||
|
||||
/* Reverse source and destination of a node.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
*/
|
||||
int (*reverse)(NodeCompat *n);
|
||||
|
||||
/* Get list of file descriptors which can be used by poll/select to detect the availability of new data.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @return The number of file descriptors which have been put into \p fds.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @return The number of file descriptors which have been put into \p fds.
|
||||
*/
|
||||
int (*poll_fds)(NodeCompat *n, int fds[]);
|
||||
|
||||
/* Get list of socket file descriptors for configuring network emulation.
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @return The number of file descriptors which have been put into \p sds.
|
||||
*/
|
||||
*
|
||||
* This callback is optional. It will only be called if non-null.
|
||||
*
|
||||
* @return The number of file descriptors which have been put into \p sds.
|
||||
*/
|
||||
int (*netem_fds)(NodeCompat *n, int sds[]);
|
||||
|
||||
// Return a memory allocator which should be used for sample pools passed to this node.
|
||||
|
|
|
@ -31,10 +31,10 @@ public:
|
|||
} direction;
|
||||
|
||||
/* The path which uses this node as a source/destination.
|
||||
*
|
||||
* Usually every node should be used only by a single path as destination.
|
||||
* Otherwise samples from different paths would be interleaved.
|
||||
*/
|
||||
*
|
||||
* Usually every node should be used only by a single path as destination.
|
||||
* Otherwise samples from different paths would be interleaved.
|
||||
*/
|
||||
Path *path;
|
||||
Node *node;
|
||||
|
||||
|
|
|
@ -29,15 +29,15 @@ public:
|
|||
Node *lookup(const uuid_t &uuid);
|
||||
|
||||
/* Parse an array or single node and checks if they exist in the "nodes" section.
|
||||
*
|
||||
* Examples:
|
||||
* out = [ "sintef", "scedu" ]
|
||||
* out = "acs"
|
||||
*
|
||||
* @param json A JSON array or string. See examples above.
|
||||
* @param nodes The nodes will be added to this list.
|
||||
* @param all This list contains all valid nodes.
|
||||
*/
|
||||
*
|
||||
* Examples:
|
||||
* out = [ "sintef", "scedu" ]
|
||||
* out = "acs"
|
||||
*
|
||||
* @param json A JSON array or string. See examples above.
|
||||
* @param nodes The nodes will be added to this list.
|
||||
* @param all This list contains all valid nodes.
|
||||
*/
|
||||
int parse(json_t *json, NodeList &all);
|
||||
|
||||
json_t *toJson() const;
|
||||
|
|
|
@ -42,8 +42,8 @@ public:
|
|||
ExampleNode(const uuid_t &id = {}, const std::string &name = "");
|
||||
|
||||
/* All of the following virtual-declared functions are optional.
|
||||
* Have a look at node.hpp/node.cpp for the default behaviour.
|
||||
*/
|
||||
* Have a look at node.hpp/node.cpp for the default behaviour.
|
||||
*/
|
||||
|
||||
virtual ~ExampleNode();
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ struct infiniband {
|
|||
unsigned available_recv_wrs;
|
||||
|
||||
/* Fixed number to substract from min. number available
|
||||
* WRs in receive queue */
|
||||
* WRs in receive queue */
|
||||
unsigned buffer_subtraction;
|
||||
|
||||
// Unrealiable connectionless data
|
||||
|
|
|
@ -75,15 +75,15 @@ struct Sample {
|
|||
} ts;
|
||||
|
||||
/* The sample signal values.
|
||||
*
|
||||
* This variable length array (VLA) extends over the end of struct Sample.
|
||||
* Make sure that pointers to struct Sample point to memory blocks of adequate size.
|
||||
* Use the SAMPLE_LENGTH() macro to calculate the required size.
|
||||
*
|
||||
* Metadata describing the details of signal values (such as name, unit, data type and more)
|
||||
* are stored in the struct Sample::signals list. Each entry in this list corresponedents
|
||||
* to an entry in the struct Sample::data array.
|
||||
*/
|
||||
*
|
||||
* This variable length array (VLA) extends over the end of struct Sample.
|
||||
* Make sure that pointers to struct Sample point to memory blocks of adequate size.
|
||||
* Use the SAMPLE_LENGTH() macro to calculate the required size.
|
||||
*
|
||||
* Metadata describing the details of signal values (such as name, unit, data type and more)
|
||||
* are stored in the struct Sample::signals list. Each entry in this list corresponedents
|
||||
* to an entry in the struct Sample::data array.
|
||||
*/
|
||||
union SignalData data[];
|
||||
};
|
||||
|
||||
|
|
|
@ -79,9 +79,9 @@ public:
|
|||
void parse(const std::string &name);
|
||||
|
||||
/* Parse super-node configuration.
|
||||
*
|
||||
* @param json A libjansson object which contains the configuration.
|
||||
*/
|
||||
*
|
||||
* @param json A libjansson object which contains the configuration.
|
||||
*/
|
||||
void parse(json_t *json);
|
||||
|
||||
// Check validity of super node configuration.
|
||||
|
|
|
@ -119,13 +119,13 @@ void Session::open(void *in, size_t len) {
|
|||
RequestFactory::create(this, uri, method, len));
|
||||
|
||||
/* This is an OPTIONS request.
|
||||
*
|
||||
* We immediatly send headers and close the connection
|
||||
* without waiting for a POST body */
|
||||
*
|
||||
* We immediatly send headers and close the connection
|
||||
* without waiting for a POST body */
|
||||
if (method == Method::OPTIONS)
|
||||
lws_callback_on_writable(wsi);
|
||||
/* This request has no body.
|
||||
* We can reply immediatly */
|
||||
* We can reply immediatly */
|
||||
else if (len == 0)
|
||||
api->pending.push(this);
|
||||
else {
|
||||
|
@ -217,10 +217,10 @@ int Session::protocolCallback(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
ret = s->writeable();
|
||||
|
||||
/*
|
||||
* HTTP/1.0 no keepalive: close network connection
|
||||
* HTTP/1.1 or HTTP1.0 + KA: wait / process next transaction
|
||||
* HTTP/2: stream ended, parent connection remains up
|
||||
*/
|
||||
* HTTP/1.0 no keepalive: close network connection
|
||||
* HTTP/1.1 or HTTP1.0 + KA: wait / process next transaction
|
||||
* HTTP/2: stream ended, parent connection remains up
|
||||
*/
|
||||
if (ret) {
|
||||
if (lws_http_transaction_completed(wsi))
|
||||
return -1;
|
||||
|
|
|
@ -283,7 +283,7 @@ int RawFormat::sscan(const char *buf, size_t len, size_t *rbytes,
|
|||
#endif
|
||||
|
||||
/* The raw format can not encode multiple samples in one buffer
|
||||
* as there is no support for framing. */
|
||||
* as there is no support for framing. */
|
||||
struct Sample *smp = smps[0];
|
||||
|
||||
int o = 0;
|
||||
|
|
|
@ -77,10 +77,10 @@ size_t VILLASHumanFormat::sscanLine(const char *buf, size_t len,
|
|||
smp->signals = signals;
|
||||
|
||||
/* Format: Seconds.NanoSeconds+Offset(SequenceNumber)Flags Value1 Value2 ...
|
||||
* RegEx: (\d+(?:\.\d+)?)([-+]\d+(?:\.\d+)?(?:e[+-]?\d+)?)?(?:\((\d+)\))?(F)?
|
||||
*
|
||||
* Please note that only the seconds and at least one value are mandatory
|
||||
*/
|
||||
* RegEx: (\d+(?:\.\d+)?)([-+]\d+(?:\.\d+)?(?:e[+-]?\d+)?)?(?:\((\d+)\))?(F)?
|
||||
*
|
||||
* Please note that only the seconds and at least one value are mandatory
|
||||
*/
|
||||
|
||||
// Mandatory: seconds
|
||||
smp->ts.origin.tv_sec = (uint32_t)strtoul(ptr, &end, 10);
|
||||
|
|
|
@ -39,12 +39,12 @@ public:
|
|||
delay_mov_sum(0), delay_mov_sum_sqrd(0), curr_count(0) {}
|
||||
|
||||
/* Hook to calculate jitter between GTNET-SKT GPS timestamp and Villas node NTP timestamp.
|
||||
*
|
||||
* Drawbacks: No protection for out of order packets. Default positive delay assumed,
|
||||
* so GPS timestamp should be earlier than NTP timestamp. If difference b/w NTP and GPS ts
|
||||
* is high (i.e. several mins depending on GPS_NTP_DELAY_WIN_SIZE),
|
||||
* the variance value will overrun the 64bit value.
|
||||
*/
|
||||
*
|
||||
* Drawbacks: No protection for out of order packets. Default positive delay assumed,
|
||||
* so GPS timestamp should be earlier than NTP timestamp. If difference b/w NTP and GPS ts
|
||||
* is high (i.e. several mins depending on GPS_NTP_DELAY_WIN_SIZE),
|
||||
* the variance value will overrun the 64bit value.
|
||||
*/
|
||||
virtual Hook::Reason process(struct Sample *smp) {
|
||||
assert(state == State::STARTED);
|
||||
|
||||
|
|
|
@ -548,15 +548,15 @@ void LuaHook::prepare() {
|
|||
lookupFunctions();
|
||||
|
||||
/* Check if we need to protect the Lua state with a mutex
|
||||
* This is the case if we have a periodic callback defined
|
||||
* As periodic() gets called from the main thread
|
||||
*/
|
||||
* This is the case if we have a periodic callback defined
|
||||
* As periodic() gets called from the main thread
|
||||
*/
|
||||
needsLocking = functions.periodic > 0;
|
||||
|
||||
// Prepare Lua process()
|
||||
if (functions.process) {
|
||||
/* We currently do not support the alteration of
|
||||
* signal metadata in process() */
|
||||
* signal metadata in process() */
|
||||
signalsProcessed = signals;
|
||||
}
|
||||
|
||||
|
|
|
@ -495,8 +495,8 @@ public:
|
|||
}
|
||||
|
||||
/*
|
||||
* This function generates the furie coeffients for the calculateDft function
|
||||
*/
|
||||
* This function generates the furie coeffients for the calculateDft function
|
||||
*/
|
||||
void generateDftMatrix() {
|
||||
using namespace std::complex_literals;
|
||||
|
||||
|
@ -510,13 +510,13 @@ public:
|
|||
}
|
||||
|
||||
/*
|
||||
* This function calculates the discrete furie transform of the input signal
|
||||
*/
|
||||
* This function calculates the discrete furie transform of the input signal
|
||||
*/
|
||||
void calculateDft(enum PaddingType padding, std::vector<double> &ringBuffer,
|
||||
std::vector<std::complex<double>> &results,
|
||||
unsigned ringBufferPos) {
|
||||
/* RingBuffer size needs to be equal to windowSize
|
||||
* prepare sample window The following parts can be combined */
|
||||
* prepare sample window The following parts can be combined */
|
||||
double tmpSmpWindow[windowSize];
|
||||
|
||||
for (unsigned i = 0; i < windowSize; i++)
|
||||
|
@ -544,8 +544,8 @@ public:
|
|||
}
|
||||
|
||||
/*
|
||||
* This function prepares the selected window coefficents
|
||||
*/
|
||||
* This function prepares the selected window coefficents
|
||||
*/
|
||||
void calculateWindow(enum WindowType windowTypeIn) {
|
||||
switch (windowTypeIn) {
|
||||
case WindowType::FLATTOP:
|
||||
|
@ -603,11 +603,11 @@ public:
|
|||
}
|
||||
|
||||
/*
|
||||
* This function is calculation the IpDFT based on the following paper:
|
||||
*
|
||||
* https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=7980868&tag=1
|
||||
*
|
||||
*/
|
||||
* This function is calculation the IpDFT based on the following paper:
|
||||
*
|
||||
* https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=7980868&tag=1
|
||||
*
|
||||
*/
|
||||
DftEstimate lpdftEstimation(const Point &a, const Point &b, const Point &c,
|
||||
unsigned maxFBin, double startFrequency,
|
||||
double frequencyResolution, double multiplier,
|
||||
|
@ -638,12 +638,12 @@ public:
|
|||
}
|
||||
|
||||
/*
|
||||
* This function is calculating the mximum based on a quadratic interpolation
|
||||
*
|
||||
* This function is based on the following paper:
|
||||
* https://mgasior.web.cern.ch/pap/biw2004.pdf (equation 10) (freq estimation)
|
||||
* https://dspguru.com/dsp/howtos/how-to-interpolate-fft-peak/
|
||||
*/
|
||||
* This function is calculating the mximum based on a quadratic interpolation
|
||||
*
|
||||
* This function is based on the following paper:
|
||||
* https://mgasior.web.cern.ch/pap/biw2004.pdf (equation 10) (freq estimation)
|
||||
* https://dspguru.com/dsp/howtos/how-to-interpolate-fft-peak/
|
||||
*/
|
||||
DftEstimate quadraticEstimation(const Point &a, const Point &b,
|
||||
const Point &c, unsigned maxFBin,
|
||||
double startFrequency,
|
||||
|
|
|
@ -33,7 +33,7 @@ int villas::kernel::tc::prio(Interface *i, struct rtnl_qdisc **qd,
|
|||
throw RuntimeError("Failed to load kernel module: sch_prio ({})", ret);
|
||||
|
||||
/* This is the default priomap used by the tc-prio qdisc
|
||||
* We will use the first 'bands' bands internally */
|
||||
* We will use the first 'bands' bands internally */
|
||||
uint8_t map[] = QDISC_PRIO_DEFAULT_PRIOMAP;
|
||||
for (unsigned i = 0; i < ARRAY_LEN(map); i++)
|
||||
map[i] += bands;
|
||||
|
|
|
@ -40,7 +40,7 @@ static struct Allocation *managed_alloc(size_t len, size_t alignment,
|
|||
uintptr_t uptr = (uintptr_t)cptr;
|
||||
|
||||
/* Check alignment first; leave a gap at start of block to assure
|
||||
* alignment if necessary */
|
||||
* alignment if necessary */
|
||||
uintptr_t rem = uptr % alignment;
|
||||
uintptr_t gap = 0;
|
||||
if (rem != 0) {
|
||||
|
@ -55,9 +55,9 @@ static struct Allocation *managed_alloc(size_t len, size_t alignment,
|
|||
if (avail >= len) {
|
||||
if (gap > sizeof(struct Block)) {
|
||||
/* The alignment gap is big enough to fit another block.
|
||||
* The original block descriptor is already at the correct
|
||||
* position, so we just change its len and create a new block
|
||||
* descriptor for the actual block we're handling. */
|
||||
* The original block descriptor is already at the correct
|
||||
* position, so we just change its len and create a new block
|
||||
* descriptor for the actual block we're handling. */
|
||||
block->length = gap - sizeof(struct Block);
|
||||
struct Block *newblock = (struct Block *)(cptr - sizeof(struct Block));
|
||||
newblock->prev = block;
|
||||
|
@ -68,7 +68,7 @@ static struct Allocation *managed_alloc(size_t len, size_t alignment,
|
|||
block = newblock;
|
||||
} else {
|
||||
/* The gap is too small to fit another block descriptor, so we
|
||||
* must account for the gap length in the block length. */
|
||||
* must account for the gap length in the block length. */
|
||||
block->length = len + gap;
|
||||
}
|
||||
|
||||
|
@ -86,8 +86,8 @@ static struct Allocation *managed_alloc(size_t len, size_t alignment,
|
|||
newblock->length = avail - len - sizeof(struct Block);
|
||||
} else {
|
||||
/* If this block was larger than the requested length, but only
|
||||
* by less than sizeof(struct Block), we may have wasted
|
||||
* memory by previous assignments to block->length. */
|
||||
* by less than sizeof(struct Block), we may have wasted
|
||||
* memory by previous assignments to block->length. */
|
||||
block->length = avail;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,9 +125,9 @@ static struct Allocation *mmap_alloc(size_t len, size_t alignment,
|
|||
}
|
||||
|
||||
/* We must make sure that len is a multiple of the page size
|
||||
*
|
||||
* See: https://lkml.org/lkml/2014/10/22/925
|
||||
*/
|
||||
*
|
||||
* See: https://lkml.org/lkml/2014/10/22/925
|
||||
*//
|
||||
ma->length = ALIGN(len, sz);
|
||||
ma->alignment = ALIGN(alignment, sz);
|
||||
ma->type = m;
|
||||
|
|
|
@ -421,7 +421,7 @@ json_t *Node::toJson() const {
|
|||
json_object_set_new(json_node, "status", status);
|
||||
|
||||
/* Add all additional fields of node here.
|
||||
* This can be used for metadata */
|
||||
* This can be used for metadata */
|
||||
json_object_update(json_node, config);
|
||||
|
||||
return json_node;
|
||||
|
|
|
@ -180,7 +180,7 @@ static int comedi_start_in(NodeCompat *n) {
|
|||
cmd.subdev = d->subdevice;
|
||||
|
||||
/* Make card send interrupts after every sample, not only when fifo is half
|
||||
* full (TODO: evaluate if this makes sense, leave as reminder) */
|
||||
* full (TODO: evaluate if this makes sense, leave as reminder) */
|
||||
//cmd.flags = TRIG_WAKE_EOS;
|
||||
|
||||
// Start right now
|
||||
|
|
|
@ -133,7 +133,7 @@ int ExampleNode::_read(struct Sample *smps[], unsigned cnt) {
|
|||
smps[0]->data[0].f = time_delta(&now, &start_time);
|
||||
|
||||
/* Dont forget to set other flags in struct Sample::flags
|
||||
* E.g. for sequence no, timestamps... */
|
||||
* E.g. for sequence no, timestamps... */
|
||||
smps[0]->flags = (int)SampleFlags::HAS_DATA;
|
||||
smps[0]->signals = getInputSignals(false);
|
||||
|
||||
|
|
|
@ -45,14 +45,14 @@ static void iec61850_sv_listener(SVSubscriber subscriber, void *ctx,
|
|||
}
|
||||
|
||||
/* Access to the data requires a priori knowledge of the data set.
|
||||
* For this example we assume a data set consisting of FLOAT32 values.
|
||||
* A FLOAT32 value is encoded as 4 bytes. You can find the first FLOAT32
|
||||
* value at byte position 0, the second value at byte position 4, the third
|
||||
* value at byte position 8, and so on.
|
||||
*
|
||||
* To prevent damages due configuration, please check the length of the
|
||||
* data block of the SV message before accessing the data.
|
||||
*/
|
||||
* For this example we assume a data set consisting of FLOAT32 values.
|
||||
* A FLOAT32 value is encoded as 4 bytes. You can find the first FLOAT32
|
||||
* value at byte position 0, the second value at byte position 4, the third
|
||||
* value at byte position 8, and so on.
|
||||
*
|
||||
* To prevent damages due configuration, please check the length of the
|
||||
* data block of the SV message before accessing the data.
|
||||
*/
|
||||
|
||||
smp = sample_alloc(&i->in.pool);
|
||||
if (!smp) {
|
||||
|
|
|
@ -362,7 +362,7 @@ int villas::node::ib_check(NodeCompat *n) {
|
|||
ib->qp_init.cap.max_recv_wr);
|
||||
|
||||
/* Set periodic signaling
|
||||
* This is done here, so that it uses the checked max_send_wr value */
|
||||
* This is done here, so that it uses the checked max_send_wr value */
|
||||
if (ib->periodic_signaling == 0)
|
||||
ib->periodic_signaling = ib->qp_init.cap.max_send_wr / 2;
|
||||
|
||||
|
@ -385,36 +385,36 @@ static void ib_create_bind_id(NodeCompat *n) {
|
|||
int ret;
|
||||
|
||||
/* Create rdma_cm_id
|
||||
*
|
||||
* The unreliable connected mode is officially not supported by the rdma_cm library. Only the Reliable
|
||||
* Connected mode (RDMA_PS_TCP) and the Unreliable Datagram mode (RDMA_PS_UDP). Although it is not officially
|
||||
* supported, it is possible to use it with a few small adaptions to the sourcecode. To enable the
|
||||
* support for UC connections follow the steps below:
|
||||
*
|
||||
* 1. git clone https://github.com/linux-rdma/rdma-core
|
||||
* 2. cd rdma-core
|
||||
* 2. Edit librdmacm/cma.c and remove the keyword 'static' in front of:
|
||||
*
|
||||
* static int rdma_create_id2(struct rdma_event_channel *channel,
|
||||
* struct rdma_cm_id **id, void *context,
|
||||
* enum rdma_port_space ps, enum ibv_qp_type qp_type)
|
||||
*
|
||||
* 3. Edit librdmacm/rdma_cma.h and add the following two entries to the file:
|
||||
*
|
||||
* #define RDMA_CMA_H_CUSTOM
|
||||
*
|
||||
* int rdma_create_id2(struct rdma_event_channel *channel,
|
||||
* struct rdma_cm_id **id, void *context,
|
||||
* enum rdma_port_space ps, enum ibv_qp_type qp_type);
|
||||
*
|
||||
* 4. Edit librdmacm/librdmacm.map and add a new line with:
|
||||
*
|
||||
* rdma_create_id2
|
||||
*
|
||||
* 5. ./build.sh
|
||||
* 6. cd build && sudo make install
|
||||
*
|
||||
*/
|
||||
*
|
||||
* The unreliable connected mode is officially not supported by the rdma_cm library. Only the Reliable
|
||||
* Connected mode (RDMA_PS_TCP) and the Unreliable Datagram mode (RDMA_PS_UDP). Although it is not officially
|
||||
* supported, it is possible to use it with a few small adaptions to the sourcecode. To enable the
|
||||
* support for UC connections follow the steps below:
|
||||
*
|
||||
* 1. git clone https://github.com/linux-rdma/rdma-core
|
||||
* 2. cd rdma-core
|
||||
* 2. Edit librdmacm/cma.c and remove the keyword 'static' in front of:
|
||||
*
|
||||
* static int rdma_create_id2(struct rdma_event_channel *channel,
|
||||
* struct rdma_cm_id **id, void *context,
|
||||
* enum rdma_port_space ps, enum ibv_qp_type qp_type)
|
||||
*
|
||||
* 3. Edit librdmacm/rdma_cma.h and add the following two entries to the file:
|
||||
*
|
||||
* #define RDMA_CMA_H_CUSTOM
|
||||
*
|
||||
* int rdma_create_id2(struct rdma_event_channel *channel,
|
||||
* struct rdma_cm_id **id, void *context,
|
||||
* enum rdma_port_space ps, enum ibv_qp_type qp_type);
|
||||
*
|
||||
* 4. Edit librdmacm/librdmacm.map and add a new line with:
|
||||
*
|
||||
* rdma_create_id2
|
||||
*
|
||||
* 5. ./build.sh
|
||||
* 6. cd build && sudo make install
|
||||
*
|
||||
*/
|
||||
#ifdef RDMA_CMA_H_CUSTOM
|
||||
ret = rdma_create_id2(ib->ctx.ec, &ib->ctx.id, nullptr, ib->conn.port_space,
|
||||
ib->qp_init.qp_type);
|
||||
|
@ -434,9 +434,9 @@ static void ib_create_bind_id(NodeCompat *n) {
|
|||
n->logger->debug("Bound rdma_cm_id to Infiniband device");
|
||||
|
||||
/* The ID will be overwritten for the target. If the event type is
|
||||
* RDMA_CM_EVENT_CONNECT_REQUEST, >then this references a new id for
|
||||
* that communication.
|
||||
*/
|
||||
* RDMA_CM_EVENT_CONNECT_REQUEST, >then this references a new id for
|
||||
* that communication.
|
||||
*/
|
||||
ib->ctx.listen_id = ib->ctx.id;
|
||||
}
|
||||
|
||||
|
@ -524,9 +524,9 @@ static void *ib_rdma_cm_event_thread(void *ctx) {
|
|||
ret = ib_connect_request(n, event->id);
|
||||
|
||||
/* A target UDP node will never really connect. In order to receive data,
|
||||
* we set it to connected after it answered the connection request
|
||||
* with rdma_connect.
|
||||
*/
|
||||
* we set it to connected after it answered the connection request
|
||||
* with rdma_connect.
|
||||
*/
|
||||
if (ib->conn.port_space == RDMA_PS_UDP && !ib->is_source)
|
||||
n->setState(State::CONNECTED);
|
||||
else
|
||||
|
@ -642,8 +642,8 @@ int villas::node::ib_start(NodeCompat *n) {
|
|||
}
|
||||
|
||||
/* Several events should occur on the event channel, to make
|
||||
* sure the nodes are succesfully connected.
|
||||
*/
|
||||
* sure the nodes are succesfully connected.
|
||||
*/
|
||||
n->logger->debug("Starting to monitor events on rdma_cm_id");
|
||||
|
||||
// Create thread to monitor rdma_cm_event channel
|
||||
|
@ -665,9 +665,9 @@ int villas::node::ib_stop(NodeCompat *n) {
|
|||
ib->stopThreads = 1;
|
||||
|
||||
/* Call RDMA disconnect function
|
||||
* Will flush all outstanding WRs to the Completion Queue and
|
||||
* will call RDMA_CM_EVENT_DISCONNECTED if that is done.
|
||||
*/
|
||||
* Will flush all outstanding WRs to the Completion Queue and
|
||||
* will call RDMA_CM_EVENT_DISCONNECTED if that is done.
|
||||
*/
|
||||
if (n->getState() == State::CONNECTED && ib->conn.port_space != RDMA_PS_UDP) {
|
||||
ret = rdma_disconnect(ib->ctx.id);
|
||||
|
||||
|
@ -727,8 +727,8 @@ int villas::node::ib_read(NodeCompat *n, struct Sample *const smps[],
|
|||
max_wr_post = cnt;
|
||||
|
||||
/* Poll Completion Queue
|
||||
* If we've already posted enough receive WRs, try to pull cnt
|
||||
*/
|
||||
* If we've already posted enough receive WRs, try to pull cnt
|
||||
*/
|
||||
if (ib->conn.available_recv_wrs >=
|
||||
(ib->qp_init.cap.max_recv_wr - ib->conn.buffer_subtraction)) {
|
||||
for (int i = 0;; i++) {
|
||||
|
@ -736,8 +736,8 @@ int villas::node::ib_read(NodeCompat *n, struct Sample *const smps[],
|
|||
pthread_testcancel();
|
||||
|
||||
/* If IB node disconnects or if it is still in State::PENDING_CONNECT, ib_read
|
||||
* should return immediately if this condition holds
|
||||
*/
|
||||
* should return immediately if this condition holds
|
||||
*/
|
||||
if (n->getState() != State::CONNECTED)
|
||||
return 0;
|
||||
|
||||
|
@ -756,10 +756,10 @@ int villas::node::ib_read(NodeCompat *n, struct Sample *const smps[],
|
|||
}
|
||||
|
||||
/* All samples (wcs * received + unposted) should be released. Let
|
||||
* *release be equal to allocated.
|
||||
*
|
||||
* This is set in the framework, before this function was called.
|
||||
*/
|
||||
* *release be equal to allocated.
|
||||
*
|
||||
* This is set in the framework, before this function was called.
|
||||
*/
|
||||
} else {
|
||||
ib->conn.available_recv_wrs += max_wr_post;
|
||||
|
||||
|
@ -839,9 +839,9 @@ int villas::node::ib_read(NodeCompat *n, struct Sample *const smps[],
|
|||
(int)wc[j].status);
|
||||
|
||||
/* 32 byte of meta data is always transferred. We should substract it.
|
||||
* Furthermore, in case of an unreliable connection, a 40 byte
|
||||
* global routing header is transferred. This should be substracted as well.
|
||||
*/
|
||||
* Furthermore, in case of an unreliable connection, a 40 byte
|
||||
* global routing header is transferred. This should be substracted as well.
|
||||
*/
|
||||
int correction =
|
||||
(ib->conn.port_space == RDMA_PS_UDP) ? META_GRH_SIZE : META_SIZE;
|
||||
|
||||
|
@ -916,11 +916,11 @@ int villas::node::ib_write(NodeCompat *n, struct Sample *const smps[],
|
|||
}
|
||||
|
||||
/* Check if data can be send inline
|
||||
* 32 byte meta data is always send.
|
||||
* Once every max_send_wr iterations a signal must be generated. Since we would need
|
||||
* an additional buffer if we were sending inlines with IBV_SEND_SIGNALED, we prefer
|
||||
* to send one samples every max_send_wr NOT inline (which thus generates a signal).
|
||||
*/
|
||||
* 32 byte meta data is always send.
|
||||
* Once every max_send_wr iterations a signal must be generated. Since we would need
|
||||
* an additional buffer if we were sending inlines with IBV_SEND_SIGNALED, we prefer
|
||||
* to send one samples every max_send_wr NOT inline (which thus generates a signal).
|
||||
*/
|
||||
int send_inline =
|
||||
((sge[sent][j - 1].length + META_SIZE) <
|
||||
ib->qp_init.cap.max_inline_data) &&
|
||||
|
@ -948,16 +948,16 @@ int villas::node::ib_write(NodeCompat *n, struct Sample *const smps[],
|
|||
n->logger->debug("Posted send Work Requests");
|
||||
|
||||
/* Reorder list. Place inline and unposted samples to the top
|
||||
* m will always be equal or smaller than *release
|
||||
*/
|
||||
* m will always be equal or smaller than *release
|
||||
*/
|
||||
for (unsigned m = 0; m < cnt; m++) {
|
||||
/* We can't use wr_id as identifier, since it is 0 for inline
|
||||
* elements
|
||||
*/
|
||||
* elements
|
||||
*/
|
||||
if (ret && (wr[m].sg_list == bad_wr->sg_list)) {
|
||||
/* The remaining work requests will be bad. Ripple through list
|
||||
* and prepare them to be released
|
||||
*/
|
||||
* and prepare them to be released
|
||||
*/
|
||||
n->logger->debug(
|
||||
"Bad WR occured with ID: {:#x} and S/G address: {:#x}: {}",
|
||||
bad_wr->wr_id, (void *)bad_wr->sg_list, ret);
|
||||
|
|
|
@ -449,7 +449,7 @@ int villas::node::kafka_stop(NodeCompat *n) {
|
|||
rd_kafka_err2str((rd_kafka_resp_err_t)ret));
|
||||
|
||||
/* If the output queue is still not empty there is an issue
|
||||
* with producing messages to the clusters. */
|
||||
* with producing messages to the clusters. */
|
||||
if (rd_kafka_outq_len(k->producer.client) > 0)
|
||||
n->logger->warn("{} message(s) were not delivered",
|
||||
rd_kafka_outq_len(k->producer.client));
|
||||
|
|
|
@ -279,16 +279,16 @@ int villas::node::opal_read(NodeCompat *n, struct Sample *const smps[],
|
|||
s->data[i].f = (float)data[i]; // OPAL provides double precission
|
||||
|
||||
/* This next call allows the execution of the "asynchronous" process
|
||||
* to actually be synchronous with the model. To achieve this, you
|
||||
* should set the "Sending Mode" in the Async_Send block to
|
||||
* NEED_REPLY_BEFORE_NEXT_SEND or NEED_REPLY_NOW. This will force
|
||||
* the model to wait for this process to call this
|
||||
* OpalAsyncSendRequestDone function before continuing. */
|
||||
* to actually be synchronous with the model. To achieve this, you
|
||||
* should set the "Sending Mode" in the Async_Send block to
|
||||
* NEED_REPLY_BEFORE_NEXT_SEND or NEED_REPLY_NOW. This will force
|
||||
* the model to wait for this process to call this
|
||||
* OpalAsyncSendRequestDone function before continuing. */
|
||||
if (o->reply)
|
||||
OpalAsyncSendRequestDone(o->sendID);
|
||||
|
||||
/* Before continuing, we make sure that the real-time model
|
||||
* has not been stopped. If it has, we quit. */
|
||||
* has not been stopped. If it has, we quit. */
|
||||
state = OpalGetAsyncModelState();
|
||||
if ((state == STATE_RESET) || (state == STATE_STOP))
|
||||
throw RuntimeError("OpalGetAsyncModelState(): Model stopped or resetted!");
|
||||
|
|
|
@ -262,7 +262,7 @@ int villas::node::redis_init(NodeCompat *n) {
|
|||
new (&r->key) std::string();
|
||||
|
||||
/* We need a timeout in order for RedisConnection::loop() to properly
|
||||
* terminate after the node is stopped */
|
||||
* terminate after the node is stopped */
|
||||
r->options.socket_timeout = std::chrono::milliseconds(500);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -141,7 +141,7 @@ int villas::node::shmem_read(NodeCompat *n, struct Sample *const smps[],
|
|||
|
||||
if (recv < 0) {
|
||||
/* This can only really mean that the other process has exited, so close
|
||||
* the interface to make sure the shared memory object is unlinked */
|
||||
* the interface to make sure the shared memory object is unlinked */
|
||||
|
||||
n->logger->info("Shared memory segment has been closed.");
|
||||
|
||||
|
|
|
@ -360,7 +360,7 @@ int villas::node::socket_read(NodeCompat *n, struct Sample *const smps[],
|
|||
}
|
||||
|
||||
/* SOCK_RAW IP sockets to not provide the IP protocol number via recvmsg()
|
||||
* So we simply set it ourself. */
|
||||
* So we simply set it ourself. */
|
||||
if (s->layer == SocketLayer::IP) {
|
||||
switch (src.sa.sa_family) {
|
||||
case AF_INET:
|
||||
|
|
|
@ -90,9 +90,9 @@ void SignalingClient::connectStatic(struct lws_sorted_usec_list *sul) {
|
|||
|
||||
if (!lws_client_connect_via_info(&c->info)) {
|
||||
/* Failed... schedule a retry... we can't use the _retry_wsi()
|
||||
* convenience wrapper api here because no valid wsi at this
|
||||
* point.
|
||||
*/
|
||||
* convenience wrapper api here because no valid wsi at this
|
||||
* point.
|
||||
*/
|
||||
if (lws_retry_sul_schedule(c->info.context, 0, sul, nullptr, connectStatic,
|
||||
&c->retry_count))
|
||||
c->logger->error("Signaling connection attempts exhausted");
|
||||
|
@ -167,14 +167,14 @@ do_retry:
|
|||
logger->info("Attempting to reconnect...");
|
||||
|
||||
/* Retry the connection to keep it nailed up
|
||||
*
|
||||
* For this example, we try to conceal any problem for one set of
|
||||
* backoff retries and then exit the app.
|
||||
*
|
||||
* If you set retry.conceal_count to be larger than the number of
|
||||
* elements in the backoff table, it will never give up and keep
|
||||
* retrying at the last backoff delay plus the random jitter amount.
|
||||
*/
|
||||
*
|
||||
* For this example, we try to conceal any problem for one set of
|
||||
* backoff retries and then exit the app.
|
||||
*
|
||||
* If you set retry.conceal_count to be larger than the number of
|
||||
* elements in the backoff table, it will never give up and keep
|
||||
* retrying at the last backoff delay plus the random jitter amount.
|
||||
*/
|
||||
if (lws_retry_sul_schedule_retry_wsi(wsi, &sul_helper.sul, connectStatic,
|
||||
&retry_count))
|
||||
logger->error("Signaling connection attempts exhausted");
|
||||
|
|
|
@ -143,12 +143,12 @@ int villas::node::websocket_protocol_cb(struct lws *wsi,
|
|||
else {
|
||||
c->mode = websocket_connection::Mode::SERVER;
|
||||
/* We use the URI to associate this connection to a node
|
||||
* and choose a protocol.
|
||||
*
|
||||
* Example: ws://example.com/node_1.json
|
||||
* Will select the node with the name 'node_1'
|
||||
* and format 'json'.
|
||||
*/
|
||||
* and choose a protocol.
|
||||
*
|
||||
* Example: ws://example.com/node_1.json
|
||||
* Will select the node with the name 'node_1'
|
||||
* and format 'json'.
|
||||
*/
|
||||
|
||||
// Get path of incoming request
|
||||
char *node, *format, *lasts;
|
||||
|
|
32
lib/path.cpp
32
lib/path.cpp
|
@ -182,11 +182,11 @@ void Path::prepare(NodeList &nodes) {
|
|||
ps = psm[n];
|
||||
else {
|
||||
/* Depending on weather the node belonging to this mapping is already
|
||||
* used by another path or not, we will create a master or secondary
|
||||
* path source.
|
||||
* A secondary path source uses an internal loopback node / queue
|
||||
* to forward samples from on path to another.
|
||||
*/
|
||||
* used by another path or not, we will create a master or secondary
|
||||
* path source.
|
||||
* A secondary path source uses an internal loopback node / queue
|
||||
* to forward samples from on path to another.
|
||||
*/
|
||||
bool isSecondary = n->sources.size() > 0;
|
||||
|
||||
// Create new path source
|
||||
|
@ -217,8 +217,8 @@ void Path::prepare(NodeList &nodes) {
|
|||
}
|
||||
|
||||
/* Get the real node backing this path source
|
||||
* In case of a secondary path source, its the internal loopback node!
|
||||
*/
|
||||
* In case of a secondary path source, its the internal loopback node!
|
||||
*/
|
||||
auto *rn = ps->getNode();
|
||||
|
||||
rn->sources.push_back(ps);
|
||||
|
@ -235,7 +235,7 @@ void Path::prepare(NodeList &nodes) {
|
|||
Signal::Ptr sig;
|
||||
|
||||
/* For data mappings we simple refer to the existing
|
||||
* signal descriptors of the source node. */
|
||||
* signal descriptors of the source node. */
|
||||
if (me->type == MappingEntry::Type::DATA) {
|
||||
sig = sigs->getByIndex(me->data.offset + j);
|
||||
if (!sig) {
|
||||
|
@ -546,11 +546,11 @@ void Path::start() {
|
|||
state = State::STARTED;
|
||||
|
||||
/* Start one thread per path for sending to destinations
|
||||
*
|
||||
* Special case: If the path only has a single source and this source
|
||||
* does not offer a file descriptor for polling, we will use a special
|
||||
* thread function.
|
||||
*/
|
||||
*
|
||||
* Special case: If the path only has a single source and this source
|
||||
* does not offer a file descriptor for polling, we will use a special
|
||||
* thread function.
|
||||
*/
|
||||
ret = pthread_create(&tid, nullptr, runWrapper, this);
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to create path thread");
|
||||
|
@ -571,9 +571,9 @@ void Path::stop() {
|
|||
state = State::STOPPING;
|
||||
|
||||
/* Cancel the thread in case is currently in a blocking syscall.
|
||||
*
|
||||
* We dont care if the thread has already been terminated.
|
||||
*/
|
||||
*
|
||||
* We dont care if the thread has already been terminated.
|
||||
*/
|
||||
ret = pthread_cancel(tid);
|
||||
if (ret && ret != ESRCH)
|
||||
throw RuntimeError("Failed to cancel path thread");
|
||||
|
|
|
@ -110,8 +110,8 @@ int PathSource::read(int i) {
|
|||
}
|
||||
|
||||
/* We reset the sample length after each restart of the simulation.
|
||||
* This is necessary for the test_rtt node to work properly.
|
||||
*/
|
||||
* This is necessary for the test_rtt node to work properly.
|
||||
*/
|
||||
if (tomux_smps[i]->flags & (int)SampleFlags::NEW_SIMULATION)
|
||||
muxed_smps[i]->length = 0;
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ retry:
|
|||
shm->write.shared = shared;
|
||||
|
||||
/* Post own semaphore and wait on the other one, so both processes know that
|
||||
* both regions are initialized */
|
||||
* both regions are initialized */
|
||||
sem_post(sem_own);
|
||||
sem_wait(sem_other);
|
||||
|
||||
|
|
|
@ -486,7 +486,7 @@ protected:
|
|||
usleep(0.1e6);
|
||||
|
||||
/* We are stopping the node here in order to unblock the receiving threads
|
||||
* Node::read() call and allow it to be joined(). */
|
||||
* Node::read() call and allow it to be joined(). */
|
||||
ret = node->stop();
|
||||
if (ret)
|
||||
throw RuntimeError("Failed to stop node {}: reason={}", node->getName(),
|
||||
|
|
|
@ -57,9 +57,9 @@ RelaySession *RelaySession::get(Relay *r, lws *wsi) {
|
|||
char uri[64];
|
||||
|
||||
/* We use the URI to associate this connection to a session
|
||||
* Example: ws://example.com/node_1
|
||||
* Will select the session with the name 'node_1'
|
||||
*/
|
||||
* Example: ws://example.com/node_1
|
||||
* Will select the session with the name 'node_1'
|
||||
*/
|
||||
|
||||
// Get path of incoming request
|
||||
lws_hdr_copy(wsi, uri, sizeof(uri), WSI_TOKEN_GET_URI);
|
||||
|
|
|
@ -58,10 +58,10 @@ protected:
|
|||
SuperNode sn;
|
||||
|
||||
/* File descriptor for Matlab results.
|
||||
* This allows you to write Matlab results in a seperate log file:
|
||||
*
|
||||
* ./test etc/example.conf rtt -f 3 3>> measurement_results.m
|
||||
*/
|
||||
* This allows you to write Matlab results in a seperate log file:
|
||||
*
|
||||
* ./test etc/example.conf rtt -f 3 3>> measurement_results.m
|
||||
*/
|
||||
int fd;
|
||||
|
||||
// Amount of messages which should be sent (default: -1 for unlimited)
|
||||
|
|
Loading…
Add table
Reference in a new issue