Compare commits

..

21 Commits
main ... dev

Author SHA1 Message Date
MasterRoby3 db138d1b60 Final Commit 2023-09-27 17:47:46 +02:00
MasterRoby3 b466eeb563 Fixed memory management issues and starvation 2023-09-18 02:44:36 +02:00
MasterRoby3 727d20466e Fixed bug on concurrency for incoming connections 2023-09-08 23:07:55 +02:00
MasterRoby3 6809c61148 Fixed bugs 2023-09-08 11:41:42 +02:00
MasterRoby3 c1bfb07196 Added integration for event building in main envent builder file 2023-09-04 01:30:07 +02:00
MasterRoby3 583d6fdae0 Backup added 2023-09-03 21:20:58 +02:00
MasterRoby3 55d3a9baa3 Fixed readme and added full event format 2023-08-29 01:11:38 +02:00
MasterRoby3 f34e7e0dc5 Added a ControlledQueue class for max size implementation and timeout management 2023-08-28 01:35:30 +02:00
MasterRoby3 ac02149c6d Fully implemented multi_th test and got test results 2023-08-27 21:40:36 +02:00
MasterRoby3 a287ea3d92 Added epoll test on thread safety 2023-08-27 16:18:17 +02:00
MasterRoby3 50234b1d13 Finished connection method and fully implemented threads 2023-08-27 16:11:01 +02:00
MasterRoby3 14795161ec Various changes and extended preliminary testing 2023-08-21 23:39:16 +02:00
MasterRoby3 11e3f51a3a Additions to test select(), incoplete and w/errors 2023-08-10 20:11:45 +02:00
MasterRoby3 23b42c58fa Completed network communication and updated header format. TODO multiple clients 2023-08-09 23:10:42 +02:00
MasterRoby3 09a7b2528b Added encoding functionalities, still networking to finish 2023-08-08 23:00:41 +02:00
MasterRoby3 f6537c4cd0 Partial socket connection (client still TODO) 2023-08-07 22:27:10 +02:00
MasterRoby3 3cfefba694 Fixed error in README.md 2023-08-06 18:02:49 +02:00
MasterRoby3 6460815ca9 Completed README.md 2023-08-06 18:00:47 +02:00
MasterRoby3 7febdd33f1 Modified README.md content 2023-08-06 17:57:41 +02:00
MasterRoby3 1ed03d90ca prova key 2023-08-06 17:40:43 +02:00
MasterRoby3 76e799c3ae First dev commit 2023-08-06 17:10:18 +02:00
115 changed files with 16214 additions and 0 deletions

View File

@ -0,0 +1,141 @@
void BandwidthVsFragSize() {
gROOT->SetBatch(kTRUE);
auto f1000 = "./mean_1k_std_400_meantime_20ms_stddevtime_10ms.csv";
auto f1000_df = ROOT::RDF::MakeCsvDataFrame(f1000, true, ';');
auto f1000_nc = f1000_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f500 = "./mean_500_std_200_meantime_10ms_stddevtime_5ms.csv";
auto f500_df = ROOT::RDF::MakeCsvDataFrame(f500, true, ';');
auto f500_nc = f500_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f200 = "./mean_200_std_80_meantime_4ms_stddevtime_2ms.csv";
auto f200_df = ROOT::RDF::MakeCsvDataFrame(f200, true, ';');
auto f200_nc = f200_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f100 = "./mean_100_std_40_meantime_2ms_stddevtime_1ms.csv";
auto f100_df = ROOT::RDF::MakeCsvDataFrame(f100, true, ';');
auto f100_nc = f100_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f40 = "./mean_40_std_16_meantime_1ms_stddevtime_0ms.csv";
auto f40_df = ROOT::RDF::MakeCsvDataFrame(f40, true, ';');
auto f40_nc = f40_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f4 = "./mean_4_std_0_meantime_0ms_stddevtime_0ms.csv";
auto f4_df = ROOT::RDF::MakeCsvDataFrame(f4, true, ';');
auto f4_nc = f4_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto canvas = new TCanvas("c", "c", 2800, 1000);
//canvas->SetLogx();
//canvas->SetGrid();
//canvas->SetLogy();
canvas->Divide(2,1);
gStyle->SetPalette(1);
canvas->cd(1);
gPad->SetRightMargin(0.05);
gPad->SetLeftMargin(0.15);
gPad->SetGrid();
auto g1000 = f1000_nc.Graph("timeout_ms", "bandwidth");
g1000->SetTitle("Bandwidth vs Timeout: Linear;Timeout [ms];Bandwidth [kB/s]");
g1000->SetName("g1000");
g1000->SetMarkerStyle(55);
g1000->SetMarkerSize(2);
g1000->SetLineWidth(2);
//sel_g->GetXaxis()->SetLimits(-50,1000);
g1000->GetHistogram()->SetMinimum(0);
g1000->GetHistogram()->SetMaximum(15000);
g1000->DrawClone("ALP PLC PMC");
auto g500 = f500_nc.Graph("timeout_ms", "bandwidth");
g500->SetName("g500");
g500->SetMarkerStyle(55);
g500->SetMarkerSize(2);
g500->SetLineWidth(2);
g500->DrawClone("LP PLC PMC");
auto g200 = f200_nc.Graph("timeout_ms", "bandwidth");
g200->SetName("g200");
g200->SetMarkerStyle(55);
g200->SetMarkerSize(2);
g200->SetLineWidth(2);
g200->DrawClone("LP PLC PMC");
auto g100 = f100_nc.Graph("timeout_ms", "bandwidth");
g100->SetName("g100");
g100->SetMarkerStyle(55);
g100->SetMarkerSize(2);
g100->SetLineWidth(2);
g100->DrawClone("LP PLC PMC");
auto g40 = f40_nc.Graph("timeout_ms", "bandwidth");
g40->SetName("g40");
g40->SetMarkerStyle(55);
g40->SetMarkerSize(2);
g40->SetLineWidth(2);
g40->DrawClone("LP PLC PMC");
auto g4 = f4_nc.Graph("timeout_ms", "bandwidth");
g4->SetName("g4");
g4->SetMarkerStyle(55);
g4->SetMarkerSize(2);
g4->SetLineWidth(2);
g4->DrawClone("LP PLC PMC");
auto leg = new TLegend(0.55,0.15,0.86,0.37);
leg->SetHeader("Mean Fragment Size", "c");
leg->AddEntry("g1000","1 kB","lp");
leg->AddEntry("g500","500 B","lp");
leg->AddEntry("g200","200 B","lp");
leg->AddEntry("g100","100 B","lp");
leg->AddEntry("g40","40 B","lp");
leg->AddEntry("g4","4 B","lp");
leg->Draw();
canvas->cd(2);
gPad->SetRightMargin(0.1);
gPad->SetLeftMargin(0.1);
gPad->SetLogy();
gPad->SetGrid();
g1000->SetTitle("Bandwidth vs Timeout: Log;Timeout [ms];Bandwidth [kB/s]");
g1000->GetHistogram()->SetMinimum(1);
g1000->GetHistogram()->SetMaximum(20000);
g1000->DrawClone("ALP PLC PMC");
g500->DrawClone("LP PLC PMC");
g200->DrawClone("LP PLC PMC");
g100->DrawClone("LP PLC PMC");
g40->DrawClone("LP PLC PMC");
g4->DrawClone("LP PLC PMC");
leg->Draw();
//gStyle->SetLegendTextSize(0.01);
//canvas->BuildLegend(0.65,0.2,0.86,0.32, "Connection Method");
canvas->Print("TimeoutVsBandwidth.png");
gROOT->SetBatch(kFALSE);
gApplication->Terminate(0);
}

View File

@ -0,0 +1,56 @@
#include <chrono>
#include <cstdint>
#include <cstdio>
#include <mutex>
#include "ControlledQueue.h"
#include "TimeoutException.h"
ControlledQueue::ControlledQueue(uint32_t maxSize, int timeoutMicroseconds) : m_maxSize(maxSize), m_timeoutMicroseconds(timeoutMicroseconds) {;}
void ControlledQueue::init(uint32_t maxSize, int timeoutMicroseconds) {
m_maxSize = maxSize;
m_timeoutMicroseconds = timeoutMicroseconds;
}
void ControlledQueue::put(uint32_t word) {
std::unique_lock<std::mutex> lk(m_mtx);
/*
This while synthax is explicitly used to avoid unwanted spurious awakenings.
I'm keeping only the wait with not timeout to transmit backpressure to the upper reading thread, which blocks.
Since that thread has locked the mutex corresponding to the fd, basically the whole fd is blocked.
That way I can tranmit backpressure with TCP to the sending client.
*/
while (! (m_queue.size() < m_maxSize) ) {
m_cv.wait(lk);
}
m_queue.push(word);
lk.unlock();
m_cv.notify_all();
}
/*
Basically here a simple string exception is thrown if the wait terminates because of timeout and not because someone has inserted an element.
That way it can be catched from the main program that can set the error code accordingly.
*/
uint32_t ControlledQueue::get() {
std::unique_lock<std::mutex> lk(m_mtx);
while ( m_queue.empty() ) {
if ( !m_cv.wait_for(lk, std::chrono::microseconds(m_timeoutMicroseconds), [&]() { return !(m_queue.empty()); } ) ) {
throw TimeoutException();
}
}
uint32_t word = m_queue.front();
m_queue.pop();
lk.unlock();
m_cv.notify_all();
return word;
}

34
ControlledQueue.h 100644
View File

@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
#include <mutex>
#include <condition_variable>
#include <queue>
class ControlledQueue {
public:
/*
Default constructo added for default initialization in std::array. If used, it's necessary to call the init function afterwards.
*/
ControlledQueue() {;}
ControlledQueue(uint32_t maxSize, int timeoutMicroseconds);
void init(uint32_t maxSize, int timeoutMicroseconds);
void put(uint32_t word);
uint32_t get();
// Simple wrapper to check queue size
int size() { return m_queue.size(); }
// Simple wrapper to see wether the queue is empty
bool empty() { return m_queue.empty(); }
private:
std::mutex m_mtx;
std::condition_variable m_cv;
uint32_t m_maxSize;
std::queue<uint32_t> m_queue;
int m_timeoutMicroseconds;
};

114
DropRate.C 100644
View File

@ -0,0 +1,114 @@
void DropRate() {
gROOT->SetBatch(kTRUE);
auto f1000 = "./mean_1k_std_400_meantime_20ms_stddevtime_10ms.csv";
auto f1000_df = ROOT::RDF::MakeCsvDataFrame(f1000, true, ';');
auto f1000_nc = f1000_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f500 = "./mean_500_std_200_meantime_10ms_stddevtime_5ms.csv";
auto f500_df = ROOT::RDF::MakeCsvDataFrame(f500, true, ';');
auto f500_nc = f500_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f200 = "./mean_200_std_80_meantime_4ms_stddevtime_2ms.csv";
auto f200_df = ROOT::RDF::MakeCsvDataFrame(f200, true, ';');
auto f200_nc = f200_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f100 = "./mean_100_std_40_meantime_2ms_stddevtime_1ms.csv";
auto f100_df = ROOT::RDF::MakeCsvDataFrame(f100, true, ';');
auto f100_nc = f100_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f40 = "./mean_40_std_16_meantime_1ms_stddevtime_0ms.csv";
auto f40_df = ROOT::RDF::MakeCsvDataFrame(f40, true, ';');
auto f40_nc = f40_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f4 = "./mean_4_std_0_meantime_0ms_stddevtime_0ms.csv";
auto f4_df = ROOT::RDF::MakeCsvDataFrame(f4, true, ';');
auto f4_nc = f4_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto canvas = new TCanvas("c", "c", 1400, 1000);
//canvas->SetLogx();
canvas->SetGrid();
canvas->SetLogy();
gStyle->SetPalette(1);
auto g1000 = f1000_nc.Graph("timeout_ms", "drop_rate");
g1000->SetTitle("Fragment Drop Rate vs Timeout;Timeout [ms];Fragment Drop Rate");
g1000->SetName("g1000");
g1000->SetMarkerStyle(55);
g1000->SetMarkerSize(2);
g1000->SetLineWidth(2);
//sel_g->GetXaxis()->SetLimits(-50,1000);
g1000->GetHistogram()->SetMinimum(1e-11);
g1000->GetHistogram()->SetMaximum(1e-5);
g1000->DrawClone("ALP PLC PMC");
auto g500 = f500_nc.Graph("timeout_ms", "drop_rate");
g500->SetName("g500");
g500->SetMarkerStyle(55);
g500->SetMarkerSize(2);
g500->SetLineWidth(2);
g500->DrawClone("LP PLC PMC");
auto g200 = f200_nc.Graph("timeout_ms", "drop_rate");
g200->SetName("g200");
g200->SetMarkerStyle(55);
g200->SetMarkerSize(2);
g200->SetLineWidth(2);
g200->DrawClone("LP PLC PMC");
auto g100 = f100_nc.Graph("timeout_ms", "drop_rate");
g100->SetName("g100");
g100->SetMarkerStyle(55);
g100->SetMarkerSize(2);
g100->SetLineWidth(2);
g100->DrawClone("LP PLC PMC");
auto g40 = f40_nc.Graph("timeout_ms", "drop_rate");
g40->SetName("g40");
g40->SetMarkerStyle(55);
g40->SetMarkerSize(2);
g40->SetLineWidth(2);
g40->DrawClone("LP PLC PMC");
auto g4 = f4_nc.Graph("timeout_ms", "drop_rate");
g4->SetName("g4");
g4->SetMarkerStyle(55);
g4->SetMarkerSize(2);
g4->SetLineWidth(2);
g4->DrawClone("LP PLC PMC");
auto leg = new TLegend(0.55,0.65,0.86,0.87);
leg->SetHeader("Mean Fragment Size", "c");
leg->AddEntry("g1000","1 kB","lp");
leg->AddEntry("g500","500 B","lp");
leg->AddEntry("g200","200 B","lp");
leg->AddEntry("g100","100 B","lp");
leg->AddEntry("g40","40 B","lp");
leg->AddEntry("g4","4 B","lp");
leg->Draw();
//gStyle->SetLegendTextSize(0.01);
//canvas->BuildLegend(0.65,0.2,0.86,0.32, "Connection Method");
canvas->Print("DropRate.png");
gROOT->SetBatch(kFALSE);
gApplication->Terminate(0);
}

BIN
DropRate.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
Nodelay.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,8 @@
{
"folders": [
{
"path": ".."
}
],
"settings": {}
}

144
QueueOccup.C 100644
View File

@ -0,0 +1,144 @@
#include <vector>
void constHisto(std::vector<double> &times, std::vector<double> &means, TH1F* hist, std::vector<double> &binEdges) {
// Initialize vectors to store bin contents and counts
std::vector<double> binContents(binEdges.size() - 1, 0.0);
std::vector<int> binCounts(binEdges.size() - 1, 0);
// Loop through data and fill the histogram
for (size_t i = 0; i < times.size(); ++i) {
double val = means[i];
for (size_t j = 0; j < binEdges.size() - 1; ++j) {
if (times[i] >= binEdges[j] && times[i] < binEdges[j + 1]) {
binContents[j] += val;
binCounts[j]++;
break;
}
}
}
// Calculate the means for each bin and set the bin content
for (size_t i = 0; i < binEdges.size() - 1; ++i) {
double binMean = (binCounts[i] > 0) ? binContents[i] / binCounts[i] : 0;
hist->SetBinContent(i + 1, binMean); // Set the bin content to the mean
}
}
void QueueOccup() {
// Define your bin edges
gROOT->SetBatch(kTRUE);
std::vector<double> binEdges;
for (int i = 0; i <= 30; i++) {
binEdges.push_back(i);
if (i>=6) binEdges.push_back(i + 0.5);
}
//gROOT->SetBatch(kTRUE);
auto f100 = "./queue_occup_1kmean_20ms_timeout50ms_100clients.csv";
auto f100_df = ROOT::RDF::MakeCsvDataFrame(f100, true, ';');
auto f200 = "./queue_occup_1kmean_20ms_timeout50ms_200clients.csv";
auto f200_df = ROOT::RDF::MakeCsvDataFrame(f200, true, ';');
auto f500 = "./queue_occup_1kmean_20ms_timeout50ms_500clients.csv";
auto f500_df = ROOT::RDF::MakeCsvDataFrame(f500, true, ';');
auto f1000 = "./queue_occup_1kmean_20ms_timeout50ms_1000clients.csv";
auto f1000_df = ROOT::RDF::MakeCsvDataFrame(f1000, true, ';');
//gStyle->SetOptTitle(kFALSE);
gStyle->SetOptStat(0);
auto canvas = new TCanvas("c", "c", 1400, 1000);
//canvas->SetLogx();
canvas->SetGrid();
canvas->SetLogy();
//filteredEvents.Histo1D({"invMass", "CMS Opendata: #mu#mu mass;#mu#mu mass [GeV];Events", 512, 2, 110}, "m");
auto timesResult100 = f100_df.Take<double>("times");
auto meansResult100 = f100_df.Take<double>("means");
std::vector<double> times100 = timesResult100.GetValue();
std::vector<double> means100 = meansResult100.GetValue();
// Create a histogram with custom binning
TH1F *h100 = new TH1F("h100","Custom Histogram", binEdges.size() - 1, &binEdges[0]);
constHisto(times100, means100, h100, binEdges);
h100->SetLineWidth(3);
//filteredEvents.Histo1D({"invMass", "CMS Opendata: #mu#mu mass;#mu#mu mass [GeV];Events", 512, 2, 110}, "m");
auto timesResult200 = f200_df.Take<double>("times");
auto meansResult200 = f200_df.Take<double>("means");
std::vector<double> times200 = timesResult200.GetValue();
std::vector<double> means200 = meansResult200.GetValue();
// Create a histogram with custom binning
TH1F *h200 = new TH1F("h200","Custom Histogram", binEdges.size() - 1, &binEdges[0]);
constHisto(times200, means200, h200, binEdges);
h200->SetLineWidth(3);
//filteredEvents.Histo1D({"invMass", "CMS Opendata: #mu#mu mass;#mu#mu mass [GeV];Events", 512, 2, 110}, "m");
auto timesResult500 = f500_df.Take<double>("times");
auto meansResult500 = f500_df.Take<double>("means");
std::vector<double> times500 = timesResult500.GetValue();
std::vector<double> means500 = meansResult500.GetValue();
// Create a histogram with custom binning
TH1F *h500 = new TH1F("h500", "", binEdges.size() - 1, &binEdges[0]);
constHisto(times500, means500, h500, binEdges);
h500->SetLineWidth(3);
//filteredEvents.Histo1D({"invMass", "CMS Opendata: #mu#mu mass;#mu#mu mass [GeV];Events", 512, 2, 110}, "m");
auto timesResult1000 = f1000_df.Take<double>("times");
auto meansResult1000 = f1000_df.Take<double>("means");
std::vector<double> times1000 = timesResult1000.GetValue();
std::vector<double> means1000 = meansResult1000.GetValue();
// Create a histogram with custom binning
TH1F *h1000 = new TH1F("h1000", "Custom Histogram", binEdges.size() - 1, &binEdges[0]);
constHisto(times1000, means1000, h1000, binEdges);
h1000->SetLineWidth(3);
h1000->GetYaxis()->SetRangeUser(2., 150000.);
h1000->GetXaxis()->SetRangeUser(5., 30.);
gStyle->SetPalette(1);
h1000->SetTitle("Queue occupancy over time; Time [s];Queue Size [elements];");
h1000->Draw("plc");
h500->Draw("same plc");
h200->Draw("same plc");
h100->Draw("same plc");
//gStyle->SetLegendTextSize(0.01);
auto leg = new TLegend(0.64,0.62,0.9,0.77);
leg->SetHeader("Num Clients", "c");
leg->AddEntry("h100","100 Clients","lp");
leg->AddEntry("h200","200 Clients","lp");
leg->AddEntry("h500","500 Clients","lp");
leg->AddEntry("h1000","1000 Clients","lp");
leg->Draw();
//canvas->BuildLegend(0.65,0.2,0.86,0.32, "Connection Method");
canvas->Print("MeanQueueOccupation.png");
gROOT->SetBatch(kFALSE);
gApplication->Terminate(0);
}

View File

@ -0,0 +1,2 @@
# Event Builder Project
This repo contains the code for a simple Event Builder inspired by ATLAS event format. It's a project for the exam "Tecniche Digitali di Acquisizione Dati" @UNIPV.

View File

@ -0,0 +1,114 @@
void TimeoutAropNoblock() {
gROOT->SetBatch(kTRUE);
auto f4 = "./mean_4_std_0_meantime_0ms_stddevtime_0ms.csv";
auto f4_df = ROOT::RDF::MakeCsvDataFrame(f4, true, ';');
auto f4_nc = f4_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto f4_noblock = "./mean_4_std_0_meantime_0ms_stddevtime_0ms_NODELAY.csv";
auto f4_noblock_df = ROOT::RDF::MakeCsvDataFrame(f4_noblock, true, ';');
auto f4_noblock_nc = f4_noblock_df.Define("bandwidth", "( tot_bytes/static_cast<double>(1024) ) / tot_time_taken");
auto canvas = new TCanvas("c", "c", 2800, 1000);
//canvas->SetLogx();
//canvas->SetGrid();
//canvas->SetLogy();
canvas->Divide(2,1);
gStyle->SetPalette(1);
canvas->cd(1);
gPad->SetRightMargin(0.05);
gPad->SetLeftMargin(0.15);
gPad->SetGrid();
auto g4 = f4_nc.Graph("timeout_ms", "bandwidth");
g4->SetTitle("TCP_NODELAY Effect: bandwidth;Timeout [ms];Bandwidth [kB/s];");
g4->SetName("g4");
g4->SetMarkerStyle(55);
g4->SetMarkerSize(2);
g4->SetLineWidth(2);
g4->GetHistogram()->SetMinimum(0);
g4->GetHistogram()->SetMaximum(4500);
g4->DrawClone("ALP PLC PMC");
auto g4_noblock = f4_noblock_nc.Graph("timeout_ms", "bandwidth");
g4_noblock->SetName("g4_noblock");
g4_noblock->SetMarkerStyle(55);
g4_noblock->SetMarkerSize(2);
g4_noblock->SetLineWidth(2);
g4_noblock->DrawClone("LP PLC PMC");
auto leg = new TLegend(0.55,0.65,0.86,0.87);
leg->AddEntry("g4","TCP_NODELAY not set","lp");
leg->AddEntry("g4_noblock","TCP_NODELAY set","lp");
leg->Draw();
canvas->cd(2);
gPad->SetRightMargin(0.1);
gPad->SetLeftMargin(0.1);
gPad->SetLogy();
gPad->SetGrid();
auto g4_drop = f4_nc.Graph("timeout_ms", "drop_rate");
g4_drop->SetTitle("TCP_NODELAY Effect: drop rate;Timeout [ms];Fragment Drop Rate;");
g4_drop->SetName("g4_drop");
g4_drop->SetMarkerStyle(55);
g4_drop->SetMarkerSize(2);
g4_drop->SetLineWidth(2);
g4_drop->GetHistogram()->SetMinimum(1e-11);
g4_drop->GetHistogram()->SetMaximum(1e-5);
g4_drop->DrawClone("ALP PLC PMC");
auto g4_drop_noblock = f4_noblock_nc.Graph("timeout_ms", "drop_rate");
g4_drop_noblock->SetTitle("TCP_NODELAY Effect: drop rate;Timeout [ms];Fragment Drop Rate;");
g4_drop_noblock->SetName("g4_drop_noblock");
g4_drop_noblock->SetMarkerStyle(55);
g4_drop_noblock->SetMarkerSize(2);
g4_drop_noblock->SetLineWidth(2);
g4_drop_noblock->DrawClone("LP PLC PMC");
auto leg_drop = new TLegend(0.55,0.65,0.86,0.87);
leg_drop->AddEntry("g4_drop","TCP_NODELAY not set","lp");
leg_drop->AddEntry("g4_drop_noblock","TCP_NODELAY set","lp");
leg_drop->Draw();
/*
g1000->SetTitle("Bandwidth vs Timeout: Log;Timeout [ms];Bandwidth [kB/s]");
g1000->GetHistogram()->SetMinimum(1);
g1000->GetHistogram()->SetMaximum(20000);
g1000->DrawClone("ALP PLC PMC");
g500->DrawClone("LP PLC PMC");
g200->DrawClone("LP PLC PMC");
g100->DrawClone("LP PLC PMC");
g40->DrawClone("LP PLC PMC");
g4->DrawClone("LP PLC PMC");
leg->Draw();*/
//gStyle->SetLegendTextSize(0.01);
//canvas->BuildLegend(0.65,0.2,0.86,0.32, "Connection Method");
canvas->Print("Nodelay.png");
gROOT->SetBatch(kFALSE);
gApplication->Terminate(0);
}

18
TimeoutException.h 100644
View File

@ -0,0 +1,18 @@
#include <stdexcept>
class TimeoutException
: public std::runtime_error
{
public:
TimeoutException() : std::runtime_error("Timeout") {;}
TimeoutException(const char* message)
: std::runtime_error(message) {
}
TimeoutException(const std::string& message)
: std::runtime_error(message) {
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
a.out 100755

Binary file not shown.

View File

@ -0,0 +1,44 @@
#include "ControlledQueue.h"
#include <chrono>
#include <mutex>
ControlledQueue::ControlledQueue(uint32_t maxSize, int timeoutMicroseconds) : m_maxSize(maxSize), m_timeoutMicroseconds(timeoutMicroseconds) {;}
void ControlledQueue::put(Fragment fragment) {
std::unique_lock<std::mutex> lk(m_mtx);
/*
This while synthax is explicitly used to avoid unwanted spurious awakenings.
I'm keeping only the wait with not timeout to transmit backpressure to the upper reading thread, which blocks.
Since that thread has locked the mutex corresponding to the fd, basically the whole fd is blocked.
That way I can tranmit backpressure with TCP to the sending client.
*/
while (! (m_queue.size() < m_maxSize) ) {
m_cv.wait(lk);
}
m_queue.push(fragment);
lk.unlock();
m_cv.notify_all();
}
/*
Basically here a simple string exception is thrown if the wait terminates because of timeout and not because someone has inserted an element.
That way it can be catched from the main program that can set the error code accordingly.
*/
Fragment ControlledQueue::get() {
std::unique_lock<std::mutex> lk(m_mtx);
if ( !m_cv.wait_for(lk, std::chrono::microseconds(m_timeoutMicroseconds), !(m_queue.empty())) ) {
throw "Get Timeout";
}
Fragment fragment = m_queue.front();
m_queue.pop();
lk.unlock();
m_cv.notify_all();
return fragment;
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <cstdint>
#include <mutex>
#include <condition_variable>
#include <queue>
#include "fragment_dataformat.h"
class ControlledQueue {
public:
ControlledQueue(uint32_t maxSize, int timeoutMicroseconds);
void put(Fragment fragment);
Fragment get();
bool empty() { return m_queue.empty(); }
private:
std::mutex m_mtx;
std::condition_variable m_cv;
uint32_t m_maxSize;
std::queue<Fragment> m_queue;
int m_timeoutMicroseconds;
};

View File

@ -0,0 +1,8 @@
{
"folders": [
{
"path": ".."
}
],
"settings": {}
}

2
backup/README.md 100644
View File

@ -0,0 +1,2 @@
# Event Builder Project
This repo contains the code for a simple Event Builder inspired by ATLAS event format. It's a project for the exam "Tecniche Digitali di Acquisizione Dati" @UNIPV.

BIN
backup/a.out 100755

Binary file not shown.

BIN
backup/core 100644

Binary file not shown.

BIN
backup/evBuild.out 100755

Binary file not shown.

View File

@ -0,0 +1,244 @@
#include <arpa/inet.h>
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#include <queue>
#include <vector>
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void bindSocketPort(int server_fd, int port) {
struct sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("FD %d bound to port %d\n", server_fd, port);
}
void startListening(int server_fd) {
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("FD %d listening to new connections\n", server_fd);
}
int acceptConnection(int server_fd) {
int client_fd;
struct sockaddr_in remoteAddr;
size_t addrlen = sizeof(remoteAddr);
if ((client_fd = accept(server_fd, (struct sockaddr *)&remoteAddr, (socklen_t *)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("Connection from host %s, port %d, FD %d\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port), client_fd);
return client_fd;
}
void term_handler(int signal) {
printf("Terminated, received SIGNAL %d", signal);
exit(EXIT_SUCCESS);
}
/*
int main(int argc, char const *argv[]) {
signal(SIGTERM, term_handler);
if (argc != 2) {
printf("Usage: %s portNumber \n", argv[0]);
exit(EXIT_FAILURE);
}
int port = atoi(argv[1]);
printf("Start socket port %d\n", port);
int server_fd = makeSocket();
bindSocketPort(server_fd, port);
startListening(server_fd);
int client_fd = acceptConnection(server_fd);
while (true) {
uint32_t word;
ssize_t bytes = read(client_fd, &word, 4);
if (bytes != 4) {
perror("Receive failed");
exit(EXIT_FAILURE);
}
printf("[RICEVUTO]\t0x%x\n", word);
}
return 0;
}*/
#define TRUE 1
#define FALSE 0
int main(int argc, char const *argv[]) {
signal(SIGTERM, term_handler);
if (argc != 2) {
printf("Usage: %s portNumber \n", argv[0]);
exit(EXIT_FAILURE);
}
int port = atoi(argv[1]);
printf("Start socket port %d\n", port);
int opt = TRUE;
int master_socket , addrlen , new_socket , client_socket[30] ,
max_clients = 30 , activity, i , valread , sd;
int max_sd;
//set of socket descriptors
fd_set readfds;
//initialise all client_socket[] to 0 so not checked
for (i = 0; i < max_clients; i++)
{
client_socket[i] = 0;
}
master_socket = makeSocket();
//set master socket to allow multiple connections ,
//this is just a good habit, it will work without this
if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
sizeof(opt)) < 0 )
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
bindSocketPort(master_socket, port);
startListening(master_socket);
while (true) {
//clear the socket set
FD_ZERO(&readfds);
//add master socket to set
FD_SET(master_socket, &readfds);
max_sd = master_socket;
//add child sockets to set
for ( i = 0 ; i < max_clients ; i++)
{
//socket descriptor
sd = client_socket[i];
//if valid socket descriptor then add to read list
if(sd > 0)
FD_SET( sd , &readfds);
//highest file descriptor number, need it for the select function
if(sd > max_sd)
max_sd = sd;
}
//wait for an activity on one of the sockets , timeout is NULL ,
//so wait indefinitely
activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL);
if ((activity < 0) && (errno!=EINTR))
{
printf("select error");
}
//If something happened on the master socket ,
//then its an incoming connection
if (FD_ISSET(master_socket, &readfds))
{
new_socket = acceptConnection(master_socket);
//add new socket to array of sockets
for (i = 0; i < max_clients; i++)
{
//if position is empty
if( client_socket[i] == 0 )
{
client_socket[i] = new_socket;
printf("Adding to list of sockets as %d\n" , i);
break;
}
}
}
//else its some IO operation on some other socket
for (i = 0; i < max_clients; i++)
{
sd = client_socket[i];
if (FD_ISSET( sd , &readfds))
{
//Check if it was for closing , and also read the
//incoming message
uint32_t word;
if ((valread = recv( sd , &word, 4, 0)) == 0)
{
struct sockaddr_in address;
int addrlen;
//Somebody disconnected , get his details and print
getpeername(sd , (struct sockaddr*)&address , \
(socklen_t*)&addrlen);
printf("Host disconnected , ip %s , port %d \n" ,
inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
printf("Disconnected fd %d", sd);
//Close the socket and mark as 0 in list for reuse
close( sd );
client_socket[i] = 0;
}
//Echo back the message that came in
else
{
printf("[RICEVUTO]\t0x%x FROM %d\n", word, sd);
}
}
}
}
/*
int client_fd = acceptConnection(server_fd);
while (true) {
uint32_t word;
ssize_t bytes = read(client_fd, &word, 4);
if (bytes != 4) {
perror("Receive failed");
exit(EXIT_FAILURE);
}
printf("[RICEVUTO]\t0x%x\n", word);
}*/
return 0;
}

View File

@ -0,0 +1,85 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstring>
#define FRAGMENT_HEADER_MARKER 0xee1234ee
typedef struct Header {
uint32_t startOfHeaderMarker = FRAGMENT_HEADER_MARKER;
uint32_t headerSize;
uint32_t fragmentSize;
uint32_t sourceIdentifier;
uint32_t runNumber;
uint32_t detectorEventNumber;
uint32_t numberOfStatusElements;
uint32_t *statusElementsArray;
/*friend std::ostream& operator <<(std::ostream& os, Header const& header)
{
return os << std::setw(8) << std::setfill('0') << header.startOfHeaderMarker << '\n'
<< std::setw(8) << std::setfill('0') << header.headerSize << '\n'
<< std::setw(8) << std::setfill('0') << header.fragmentSize << '\n'
<< std::setw(8) << std::setfill('0') << header.runNumber << '\n'
<< std::setw(8) << std::setfill('0') << header.detectorEventNumber << '\n'
<< std::setw(8) << std::setfill('0') << header.numberOfStatusElements << '\n';
}*/
} Header;
typedef struct Fragment {
Header header;
uint32_t *payloadElements;
} Fragment;
enum ERROR_CODES {
INCORRECT_ERROR = (1 << 0),
CORRUPTED_ERROR = (1 << 1),
MISSING_DATA_ERROR = (1 << 2),
TIMEOUT_ERROR = (1 << 3)
};
void encode_header(uint32_t *buffer, const Header &header) {
buffer[0] = header.startOfHeaderMarker;
buffer[1] = header.headerSize;
buffer[2] = header.fragmentSize;
buffer[3] = header.sourceIdentifier;
buffer[4] = header.runNumber;
buffer[5] = header.detectorEventNumber;
buffer[6] = header.numberOfStatusElements;
std::memcpy(&buffer[7], header.statusElementsArray, header.numberOfStatusElements * sizeof(uint32_t));
}
void encode_fragment(uint32_t *buffer, const Fragment &fragment){
encode_header(buffer, fragment.header);
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;
}

View File

@ -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;

BIN
backup/prov.out 100755

Binary file not shown.

5
backup/prova.cpp 100644
View File

@ -0,0 +1,5 @@
#include <iostream>
int main() {
return 0;
}

161
backup/provider.cxx 100644
View File

@ -0,0 +1,161 @@
#include <algorithm>
#include <arpa/inet.h>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <netinet/in.h>
#include <random>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <csignal>
#include "fragment_dataformat.h"
#define MIN_FRAGMENTS 0
#define MAX_FRAGMENTS 100
/*
int rndError(float p){
float rndFloat = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
return rndFloat < p;
}*/
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void connectTo(int sock, const char* host, int port) {
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(host);
serv_addr.sin_port = htons(port);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to %s: %d\n", host, port);
}
void term_handler(int signal) {
printf("Terminated, received SIGNAL %d", signal);
exit(EXIT_SUCCESS);
}
int main(int argc, char* argv[]) {
signal(SIGTERM, term_handler);
signal(SIGINT, term_handler);
//will use it later to obtain random number from hardware
std::random_device rd;
std::mt19937 generator(42);
std::discrete_distribution<uint8_t> discrete_distr({0.9, 0.1});
std::normal_distribution<float> normal_distr(25., 10.);
std::uniform_int_distribution<uint32_t> unif_int_distib;
std::uniform_real_distribution<float> unif_float_distrib(0.5, 2);
//commenting all old_style generation
//srand (static_cast <unsigned> (42));
bool out_condition = true;
uint32_t event_number = 0;
uint32_t run_number = 0;
uint32_t source_id = 0;
if (argc != 5) {
printf("Usage %s host portNumber sourceId runNumber\n", argv[0]);
exit(EXIT_FAILURE);
}
const char* host = argv[1];
int port = atoi(argv[2]);
source_id = atoi(argv[3]);
run_number = atoi(argv[4]);
int socket = makeSocket();
connectTo(socket, host, port);
while (true) {
Header header;
header.sourceIdentifier = source_id;
header.runNumber = run_number;
header.detectorEventNumber = event_number;
event_number++;
header.numberOfStatusElements = 0;
//if swap to old style just change with function above and prob 0.1 for 1
uint8_t incorrectError = discrete_distr(generator);
uint8_t corruptedError = discrete_distr(generator);
uint8_t missingDataError = discrete_distr(generator);
uint8_t timeoutError = discrete_distr(generator);
uint32_t firstStatusElement = 0x0;
if (incorrectError) firstStatusElement |= INCORRECT_ERROR;
if (corruptedError) firstStatusElement |= CORRUPTED_ERROR;
if (missingDataError) firstStatusElement |= MISSING_DATA_ERROR;
if (timeoutError) firstStatusElement |= TIMEOUT_ERROR;
if (firstStatusElement != 0x0) {
header.numberOfStatusElements = 1;
header.statusElementsArray = new uint32_t[header.numberOfStatusElements];
header.statusElementsArray[0] = firstStatusElement;
}
uint32_t payload_size = std::max(std::min(static_cast<int>(std::round(normal_distr(generator))), MAX_FRAGMENTS), MIN_FRAGMENTS);
header.headerSize = 7 + header.numberOfStatusElements;
header.fragmentSize = header.headerSize + payload_size;
Fragment fragment;
fragment.header = header;
fragment.payloadElements = new uint32_t[payload_size];
for (uint32_t i = 0; i < payload_size; i++) {
fragment.payloadElements[i] = unif_int_distib(generator);
}
uint32_t buffer[header.fragmentSize];
encode_fragment(buffer, fragment);
ssize_t bytes = send(socket, reinterpret_cast<char*>(buffer), sizeof(buffer), 0);
if (bytes != header.fragmentSize * sizeof(uint32_t)) {
perror("Send failed: num bytes not matching");
exit(EXIT_FAILURE);
}
//std::cout << std::hex << std::setw(8) << std::setfill('0');
////std::cout << fragment.header;
//for (uint8_t i = 0; i < fragment.header.numberOfStatusElements; i++) {
// std::cout << "status element " << std::setw(8) << std::setfill('0') << fragment.header.statusElementsArray[i] << std::endl;
//}
//for (uint32_t i = 0; i < payload_size; i++) {
// std::cout << "payload element " << std::setw(8) << std::setfill('0') << fragment.payloadElements[i] << std::endl;
//}
//std::cout << std::endl;
if (header.numberOfStatusElements > 0){
delete [] fragment.header.statusElementsArray;
}
delete [] fragment.payloadElements;
sleep(unif_float_distrib(generator));
}
return 0;
}

View File

@ -0,0 +1,12 @@
#!/bin/bash
echo "Usage: $0 host port runNumber numberOfProviders"
if [ $# -eq 4 ]
then
echo "Selected host: $1:$2 runNumber: $3 numberOfProviders: $4"
for i in $(seq 1 $4);
do
echo "Spawning provider number $i"
./prov.out $1 $2 $3 &
done
fi

BIN
core 100644

Binary file not shown.

BIN
evBuild.out 100755

Binary file not shown.

466
event_builder.cxx 100644
View File

@ -0,0 +1,466 @@
#include <cerrno>
#include <condition_variable>
#include <cstddef>
#include <cinttypes>
#include <cstdint>
#include <cstdio> // for fprintf()
#include <functional>
#include <iostream>
#include <queue>
#include <ratio>
#include <unistd.h> // for close(), read()
#include <sys/epoll.h> // for epoll_create1(), epoll_ctl(), struct epoll_event
#include <cstring> // for strncmp
//my addition to the online guide
#include <csignal>
#include <cstdlib>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <utility>
#include <vector>
#include <chrono>
#include <fstream>
#include <thread>
#include <mutex>
#include <atomic>
#include <array>
#include <numeric>
#include "fragment_dataformat.h"
#include "full_event_format.h"
#include "TimeoutException.h"
#include "ControlledQueue.h"
#define MAX_EVENTS 1024
#define MAX_QUEUE_SIZE 1000000
#define READER_THREADS 6
// That's a buffer size of 64 kB, to maximize performance without it being too big, according to testing
#define BUFFER_SIZE_WORDS 16384
int min_fd = MAX_EVENTS + 1;
int max_fd = 0;
int exp_num = 0;
std::mutex conn_mutex;
std::condition_variable conn_cv;
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void bindSocketPort(int server_fd, int port) {
struct sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("FD %d bound to port %d\n", server_fd, port);
}
void startListening(int server_fd) {
if (listen(server_fd, 20000) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("FD %d listening to new connections\n", server_fd);
}
int acceptConnection(int server_fd) {
int client_fd;
struct sockaddr_in remoteAddr;
size_t addrlen = sizeof(remoteAddr);
if ((client_fd = accept(server_fd, (struct sockaddr *)&remoteAddr, (socklen_t *)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
} else {
int flags = fcntl(client_fd, F_GETFL);
fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
}
printf("Connection from host %s, port %d, FD %d\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port), client_fd);
return client_fd;
}
void acceptConnectionEpollStyle(int server_fd, int &efd) {
struct sockaddr_in new_remoteAddr;
int addrlen = sizeof(struct sockaddr_in);
while (true) {
int conn_sock = accept(server_fd, (struct sockaddr*)&new_remoteAddr, (socklen_t*)&addrlen);
if (conn_sock == -1) {
// All incoming connections have been processed
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
break;
} else {
perror("accept");
break;
}
}
// make new connection non-blocking
int flags = fcntl(conn_sock, F_GETFL, 0);
fcntl(conn_sock, F_SETFL, flags | O_NONBLOCK);
// monitor new connection for read events, always in edge triggered
struct epoll_event event;
event.events = EPOLLIN | EPOLLEXCLUSIVE;//| EPOLLET;
event.data.fd = conn_sock;
// Allow epoll to monitor the new connection
if (epoll_ctl(efd, EPOLL_CTL_ADD, conn_sock, &event) == -1) {
perror("epoll_ctl: conn_sock");
break;
}
printf("Accepted epoll style connection from %s:%d from fd: %d\n", inet_ntoa(new_remoteAddr.sin_addr), ntohs(new_remoteAddr.sin_port), conn_sock);
if (max_fd < conn_sock) max_fd = conn_sock;
if (min_fd > conn_sock) min_fd = conn_sock;
}
}
void term_handler(int signal) {
printf("Terminated, received SIGNAL %d", signal);
exit(EXIT_SUCCESS);
}
std::array<std::mutex, MAX_EVENTS> queues_mutexes;
void thradizable(int &epoll_fd, int &master_socket, std::array<ControlledQueue, MAX_EVENTS>& queues_array, const int &th_flag, const int thread_index) {
epoll_event events[MAX_EVENTS];
while (true) {
if (th_flag == 1) break;
// Time measurements
///auto start = std::chrono::high_resolution_clock::now();
// Returns only the sockets for which there are events
//printf("Before wait\n");
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
//printf("After wait\n");
if (nfds == -1) {
perror("epoll_wait");
exit(EXIT_FAILURE);
}
// Iterate on the sockets having events
for (int i = 0; i < nfds; i++) {
//printf("Tot fds = %d reading from %d\n", nfds, i);
int fd = events[i].data.fd;
if (fd == master_socket) {
// If the activity is on the master socket, than it's a new connection request
std::unique_lock<std::mutex> conn_lk(conn_mutex);
acceptConnectionEpollStyle(master_socket, epoll_fd);
conn_lk.unlock();
conn_cv.notify_all();
} else if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
// Than the client connection is closed, so I close it
printf("Closing %d", fd);
close(fd);
} else {
//printf("Ev trig th %d with tot b %lu\n", thread_index, part);
// Than we received data from one of the monitored sockets
uint32_t buffer[BUFFER_SIZE_WORDS];
//while (valread != EAGAIN) {
std::unique_lock<std::mutex> lk(queues_mutexes[fd]);
ssize_t valread = recv(fd, reinterpret_cast<char*>(buffer), sizeof(buffer), 0);
if (valread > 0) {
//printf("[RICEVUTO]\t FROM %d\n", fd);
int opt_incr = (valread % 4) ? 1 : 0;
for (int q_i = 0; q_i < (valread/4) + opt_incr; q_i++) {
queues_array[fd].put(buffer[q_i]);
}
/*
bytes_read += valread;
int kilos = 0;
if ((kilos = bytes_read / 1024) > 0) {
kBytes_read += kilos;
bytes_read -= (kilos * 1024);
//printf("reade bites %lu", bytes_read);
}*/
}
lk.unlock();
//}
}
}
///auto end = std::chrono::high_resolution_clock::now();
///double time_taken = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
//time taken in milliseconds
///
/*time_taken *= 1e-6;
total_time_taken += time_taken;
if (total_time_taken > 3e4) {
times.push_back(total_time_taken);
tot_received_data.push_back(kBytes_read);
break;
}*/
///
}
}
std::vector<double> times;
std::vector<double> timed_means;
double tot_time_taken = 0;
uint32_t tot_size_full_event = 0;
uint32_t num_events_stored = 0;
uint32_t fragments_lost = 0;
int fragments_per_event = max_fd - min_fd + 1;
void builder_thread (std::array<ControlledQueue, MAX_EVENTS> &queues_array, uint32_t &runNumber) {
uint32_t counter = 0;
while (1) {
auto start = std::chrono::high_resolution_clock::now();
if ( (max_fd < min_fd) || (exp_num <= 0) || ((max_fd - min_fd + 1) != exp_num)) {
std::unique_lock<std::mutex> conn_lk(conn_mutex);
while ( (max_fd < min_fd) || (exp_num <= 0) || ((max_fd - min_fd + 1) != exp_num)) {
conn_cv.wait(conn_lk);
}
conn_lk.unlock();
}
//printf("sono fuori bro");
FullEvent fullEvent;
fullEvent.headerSize = 5;
fullEvent.runNumber = runNumber;
fullEvent.eventNumber = counter;
fullEvent.fragmentsArray = new Fragment[max_fd - min_fd + 1];
uint32_t fullEventPayloadSize = 0;
double sumsize = 0;
for (int i = min_fd; i <= max_fd; i++){
//std::unique_lock<std::mutex> lk(queues_mutexes[i]);
int inCurrentEventNumber = 0;
while (inCurrentEventNumber != 1) {
try {
uint32_t starter = queues_array[i].get();
if (starter == FRAGMENT_HEADER_MARKER) {
uint32_t headerSize = queues_array[i].get();
uint32_t fragmentSize = queues_array[i].get();
uint32_t* buffer = new uint32_t[fragmentSize];
buffer[0] = starter;
buffer[1] = headerSize;
buffer[2] = fragmentSize;
for (int j = 3; j < fragmentSize; j++) {
buffer[j] = queues_array[i].get();
}
if (getDetectorEventNumber(buffer) < fullEvent.eventNumber) {
continue;
} else if (getDetectorEventNumber(buffer) == fullEvent.eventNumber) {
Fragment& fragment = fullEvent.fragmentsArray[i - min_fd];
decode_fragment(buffer, fragment);
inCurrentEventNumber = 1;
fullEventPayloadSize += fragment.header.fragmentSize;
} else {
printf("È successo un cazzo di casino");
}
delete [] buffer;
}
} catch (const TimeoutException& ex) {
//printf("Ho catchato\n");
inCurrentEventNumber = 1;
Fragment& fragment = fullEvent.fragmentsArray[i - min_fd];
Header& header = fragment.header;
header.sourceIdentifier = i - min_fd;
header.runNumber = runNumber;
header.detectorEventNumber = counter;
header.numberOfStatusElements = 1;
uint32_t firstStatusElement = 0x0;
firstStatusElement |= TIMEOUT_ERROR;
header.statusElementsArray = new uint32_t[header.numberOfStatusElements];
header.statusElementsArray[0] = firstStatusElement;
header.headerSize = 7 + header.numberOfStatusElements;
header.fragmentSize = header.headerSize;
//fragment.header = header;
//fullEvent.fragmentsArray[i - min_fd] = fragment;
fullEventPayloadSize += fragment.header.fragmentSize;
fragments_lost++;
}
}
sumsize += queues_array[i].size();
//lk.unlock();
}
double mean = sumsize / queues_array.size();
//timed_means.push_back(mean);
fullEvent.eventSize = fullEvent.headerSize + fullEventPayloadSize;
//printFullEvent(fullEvent);
num_events_stored = counter;
counter++;
auto end = std::chrono::high_resolution_clock::now();
double time_taken = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
time_taken *= 1e-9;
tot_time_taken += time_taken;
//times.push_back(tot_time_taken);
tot_size_full_event += fullEvent.eventSize;
//printf("timee %f", tot_time_taken);
if (tot_time_taken >= 30) break;
}
}
int main(int argc, char const *argv[]) {
signal(SIGTERM, term_handler);
if (argc != 5) {
printf("Usage: %s portNumber runNumber numClients timeout_ms\n", argv[0]);
exit(EXIT_FAILURE);
}
int port = atoi(argv[1]);
uint32_t runNumber = atoi(argv[2]);
exp_num = atoi(argv[3]);
int timeout_ms = atoi(argv[4]);
printf("You chose parameters: pnum %d runNum %d numClients %d timeout %d", port, runNumber, exp_num, timeout_ms);
printf("Start socket port %d\n", port);
int master_socket;
const int opt = 1;
master_socket = makeSocket();
//set master socket to allow multiple connections ,
//this is just a good habit, it will work without this
if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
sizeof(opt)) < 0 )
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
if( setsockopt(master_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&opt,
sizeof(opt)) < 0 )
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
bindSocketPort(master_socket, port);
startListening(master_socket);
int flags = fcntl(master_socket, F_GETFL, 0);
fcntl(master_socket, F_SETFL, flags | O_NONBLOCK);
epoll_event ev, events[MAX_EVENTS];
std::array<uint64_t, MAX_EVENTS> kBytes_read_on_descr;
//The atomic here is used as a flag to tell the thread to stop
std::vector<std::thread> vThreads;
//create the epoll instance
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
printf("Failed to create epoll file descriptor\n");
exit(EXIT_FAILURE);
}
ev.data.fd = master_socket;
// Reading events with edge triggered mode
ev.events = EPOLLIN | EPOLLEXCLUSIVE;//| EPOLLET;
// Allowing epoll to monitor the master_socket
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, master_socket, &ev) == -1){
perror("epoll_ctl");
exit(EXIT_FAILURE);
}
std::array<std::thread, READER_THREADS> vT;
std::array<int, READER_THREADS> thread_flags;
// Creating the data structure and initialization with max size and timeout ez win
std::array<ControlledQueue, MAX_EVENTS> queues_array;
for (auto& queue : queues_array) {
queue.init(MAX_QUEUE_SIZE, timeout_ms * 1000);
}
for (int t_i = 0; t_i < READER_THREADS; t_i++) {
thread_flags[t_i] = 0;
vT[t_i] = std::thread(thradizable, std::ref(epoll_fd), std::ref(master_socket), std::ref(queues_array), std::cref(thread_flags.at(t_i)), t_i);
//vT[t_i].detach();
}
std::thread bdth(builder_thread, std::ref(queues_array), std::ref(runNumber));
//ADD CONSUMER THREAD
bdth.join();
//for (double mean : timed_means) {
// printf("%.0f ", mean);
//}
//sleep(30);
printf("fragments lost %d\n", fragments_lost);
printf("tot ev %d\n", num_events_stored);
std::ofstream outfile;
//Test on queue size over time
//outfile.open("queue_occup_1kmean_20ms_timeout50ms_500clients.csv");
//outfile << "times;means;\n";
//auto iter_times = times.begin();
//auto iter_sizes = timed_means.begin();
//for ( ; iter_times != times.end() && iter_sizes != timed_means.end(); (++iter_times, ++iter_sizes)) {
// outfile << *iter_times << ";" << *iter_sizes << ";\n";
//}
outfile.open("mean_4_std_0_meantime_0ms_stddevtime_0ms_NODELAY.csv", std::ios_base::app);
outfile << timeout_ms << ";" << tot_time_taken << ";" << tot_size_full_event * 4 << ";" << fragments_lost/static_cast<double>(fragments_per_event * num_events_stored) << ";\n";
if (close(epoll_fd)) {
printf("Failed to close epoll file descriptor");
exit(EXIT_FAILURE);
}
return 0;
}

View File

@ -0,0 +1,126 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#define FRAGMENT_HEADER_MARKER 0xee1234ee
typedef struct Header {
uint32_t startOfHeaderMarker = FRAGMENT_HEADER_MARKER;
uint32_t headerSize;
uint32_t fragmentSize;
uint32_t sourceIdentifier;
uint32_t runNumber;
uint32_t detectorEventNumber;
uint32_t numberOfStatusElements;
uint32_t *statusElementsArray;
/*friend std::ostream& operator <<(std::ostream& os, Header const& header)
{
return os << std::setw(8) << std::setfill('0') << header.startOfHeaderMarker << '\n'
<< std::setw(8) << std::setfill('0') << header.headerSize << '\n'
<< std::setw(8) << std::setfill('0') << header.fragmentSize << '\n'
<< std::setw(8) << std::setfill('0') << header.runNumber << '\n'
<< std::setw(8) << std::setfill('0') << header.detectorEventNumber << '\n'
<< std::setw(8) << std::setfill('0') << header.numberOfStatusElements << '\n';
}*/
public:
Header() : statusElementsArray(NULL) {}
~Header() {
if (statusElementsArray != NULL) {
delete [] statusElementsArray;
}
}
} Header;
typedef struct Fragment {
Header header;
uint32_t *payloadElements;
public:
Fragment() : header(), payloadElements(NULL) {}
~Fragment() {
if (payloadElements != NULL) {
delete [] payloadElements;
}
}
} Fragment;
enum ERROR_CODES {
INCORRECT_ERROR = (1 << 0),
CORRUPTED_ERROR = (1 << 1),
MISSING_DATA_ERROR = (1 << 2),
TIMEOUT_ERROR = (1 << 3)
};
void encode_header(uint32_t *buffer, const Header &header) {
buffer[0] = header.startOfHeaderMarker;
buffer[1] = header.headerSize;
buffer[2] = header.fragmentSize;
buffer[3] = header.sourceIdentifier;
buffer[4] = header.runNumber;
buffer[5] = header.detectorEventNumber;
buffer[6] = header.numberOfStatusElements;
std::memcpy(&buffer[7], header.statusElementsArray, header.numberOfStatusElements * sizeof(uint32_t));
}
void encode_fragment(uint32_t *buffer, const Fragment &fragment){
encode_header(buffer, fragment.header);
std::memcpy(&buffer[fragment.header.headerSize], fragment.payloadElements, (fragment.header.fragmentSize - fragment.header.headerSize) * sizeof(uint32_t));
}
uint32_t getDetectorEventNumber(uint32_t *buffer) {
return buffer[5];
}
void 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;
//printf("Status elements bitch: %d\n", nStatusElements);
fragment.header.statusElementsArray = new uint32_t[nStatusElements];
for (int i = 1; i <= nStatusElements; i++) {
fragment.header.statusElementsArray[i-1] = 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[i-1] = buffer[6+nStatusElements+i];
}
}
void printFragment(Fragment &fragment) {
printf("NewFrag\n");
printf("0x%08x\n", fragment.header.startOfHeaderMarker);
printf("0x%08x\n", fragment.header.headerSize);
printf("0x%08x\n", fragment.header.fragmentSize);
printf("0x%08x\n", fragment.header.sourceIdentifier);
printf("0x%08x\n", fragment.header.runNumber);
printf("0x%08x\n", fragment.header.detectorEventNumber);
printf("0x%08x\n", fragment.header.numberOfStatusElements);
for (uint32_t i = 0; i < fragment.header.numberOfStatusElements; i++) {
printf("0x%08x\n", fragment.header.statusElementsArray[i]);
}
uint32_t payloadSize = fragment.header.fragmentSize - fragment.header.headerSize;
for (uint32_t i = 0; i < payloadSize; i++) {
printf("0x%08x\n", fragment.payloadElements[i]);
}
}

View File

@ -0,0 +1,48 @@
#pragma once
#include "fragment_dataformat.h"
#include <cstdint>
#include <cstdio>
#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;
uint32_t eventNumber;
Fragment *fragmentsArray;
public:
FullEvent() : fragmentsArray(NULL) {}
~FullEvent() {
if (fragmentsArray != NULL) {
delete [] fragmentsArray;
}
}
}FullEvent;
void printFullEvent(FullEvent &fullEvent) {
printf("0x%08x\n", fullEvent.startOfHeaderMarker);
printf("0x%08x\n", fullEvent.headerSize);
printf("0x%08x\n", fullEvent.eventSize);
printf("0x%08x\n", fullEvent.runNumber);
printf("0x%08x\n", fullEvent.eventNumber);
printf("\n");
uint32_t remainingPayloadSize = fullEvent.eventSize - fullEvent.headerSize;
uint32_t counter = 0;
while (remainingPayloadSize > 0) {
printFragment(fullEvent.fragmentsArray[counter]);
remainingPayloadSize -= fullEvent.fragmentsArray[counter].header.fragmentSize;
counter++;
printf("\n");
}
printf("\n\n\n");
}

1
gcc-13 120000
View File

@ -0,0 +1 @@
/home/master-roby3/newgcc/gcc/bin/gcc

View File

@ -0,0 +1,8 @@
timeout_ms;tot_time_taken;tot_bytes;drop_rate;
10;30.0032;338459908;1.40136e-09;
20;30.0002;346202464;1.63504e-09;
30;30.0011;347476836;4.67159e-10;
40;30.0012;344840600;0;
50;30;343088860;0;
100;30.0009;342096100;0;
500;30.0019;348029480;0;
1 timeout_ms tot_time_taken tot_bytes drop_rate
2 10 30.0032 338459908 1.40136e-09
3 20 30.0002 346202464 1.63504e-09
4 30 30.0011 347476836 4.67159e-10
5 40 30.0012 344840600 0
6 50 30 343088860 0
7 100 30.0009 342096100 0
8 500 30.0019 348029480 0

View File

@ -0,0 +1,9 @@
timeout_ms;tot_time_taken;tot_bytes;drop_rate;
1;30.0112;256532140;3.29324e-06;
10;30.0041;283265780;6.96389e-08;
20;30.0076;283558440;2.32906e-10;
30;30.015;283560020;0;
40;30.0075;283560020;0;
50;30.0033;283132760;0;
100;30.0037;283560020;0;
500;30.0114;283560020;0;
1 timeout_ms tot_time_taken tot_bytes drop_rate
2 1 30.0112 256532140 3.29324e-06
3 10 30.0041 283265780 6.96389e-08
4 20 30.0076 283558440 2.32906e-10
5 30 30.015 283560020 0
6 40 30.0075 283560020 0
7 50 30.0033 283132760 0
8 100 30.0037 283560020 0
9 500 30.0114 283560020 0

View File

@ -0,0 +1,9 @@
timeout_ms;tot_time_taken;tot_bytes;drop_rate;
1;30;313136400;2.72251e-06;
10;30.0067;313893980;4.43098e-09;
20;30.0003;314276532;9.3284e-10;
30;30.0041;313943316;4.66419e-10;
40;30.0013;314238880;0;
50;30.0029;314098020;0;
100;30.0004;314189260;0;
500;30.0018;314005180;0;
1 timeout_ms tot_time_taken tot_bytes drop_rate
2 1 30 313136400 2.72251e-06
3 10 30.0067 313893980 4.43098e-09
4 20 30.0003 314276532 9.3284e-10
5 30 30.0041 313943316 4.66419e-10
6 40 30.0013 314238880 0
7 50 30.0029 314098020 0
8 100 30.0004 314189260 0
9 500 30.0018 314005180 0

View File

@ -0,0 +1,9 @@
timeout_ms;tot_time_taken;tot_bytes;drop_rate;
1;30;361365412;7.99154e-07;
10;30;359955860;7.26272e-09;
20;30.0005;360052872;1.87425e-09;
30;30.0009;359275124;4.68557e-10;
40;30.0011;358812120;2.34276e-10;
50;30.0015;358824140;0;
100;30.0002;357773020;2.34272e-10;
500;30.0007;357413400;0;
1 timeout_ms tot_time_taken tot_bytes drop_rate
2 1 30 361365412 7.99154e-07
3 10 30 359955860 7.26272e-09
4 20 30.0005 360052872 1.87425e-09
5 30 30.0009 359275124 4.68557e-10
6 40 30.0011 358812120 2.34276e-10
7 50 30.0015 358824140 0
8 100 30.0002 357773020 2.34272e-10
9 500 30.0007 357413400 0

View File

@ -0,0 +1,9 @@
timeout_ms;tot_time_taken;tot_bytes;drop_rate;
1;30.0098;3867164;1.05697e-06;
10;30.1872;1088984;2.7219e-07;
20;30.1364;589124;2.16537e-07;
30;30.2068;432292;1.11062e-07;
40;30.0934;1222700;8.89452e-08;
50;30.1007;3751324;6.63657e-08;
100;30.1293;3395060;3.93532e-08;
500;30.1592;2460220;3.02707e-09;
1 timeout_ms tot_time_taken tot_bytes drop_rate
2 1 30.0098 3867164 1.05697e-06
3 10 30.1872 1088984 2.7219e-07
4 20 30.1364 589124 2.16537e-07
5 30 30.2068 432292 1.11062e-07
6 40 30.0934 1222700 8.89452e-08
7 50 30.1007 3751324 6.63657e-08
8 100 30.1293 3395060 3.93532e-08
9 500 30.1592 2460220 3.02707e-09

View File

@ -0,0 +1,9 @@
timeout_ms;tot_time_taken;tot_bytes;drop_rate;
1;30;126287872;7.86345e-07;
10;30.1036;72796028;1.49403e-07;
20;30.0004;55366152;9.68175e-08;
30;30.0001;76848500;5.06642e-08;
40;30.0144;30237660;4.80153e-08;
50;30.0015;30165440;3.65941e-08;
100;30.0042;73705460;1.33066e-08;
500;30.0002;57122680;6.99929e-10;
1 timeout_ms tot_time_taken tot_bytes drop_rate
2 1 30 126287872 7.86345e-07
3 10 30.1036 72796028 1.49403e-07
4 20 30.0004 55366152 9.68175e-08
5 30 30.0001 76848500 5.06642e-08
6 40 30.0144 30237660 4.80153e-08
7 50 30.0015 30165440 3.65941e-08
8 100 30.0042 73705460 1.33066e-08
9 500 30.0002 57122680 6.99929e-10

View File

@ -0,0 +1,9 @@
timeout_ms;tot_time_taken;tot_bytes;drop_rate;
1;30.002;285440932;3.60566e-06;
10;30.0045;292509020;8.85339e-08;
20;30.0054;292548652;6.98952e-10;
30;30.0068;292681920;4.65968e-10;
40;30.0007;292683240;0;
50;30.0057;292298380;0;
100;30.0011;292683240;0;
500;30.0085;292683240;0;
1 timeout_ms tot_time_taken tot_bytes drop_rate
2 1 30.002 285440932 3.60566e-06
3 10 30.0045 292509020 8.85339e-08
4 20 30.0054 292548652 6.98952e-10
5 30 30.0068 292681920 4.65968e-10
6 40 30.0007 292683240 0
7 50 30.0057 292298380 0
8 100 30.0011 292683240 0
9 500 30.0085 292683240 0

BIN
prov.out 100755

Binary file not shown.

5
prova.cpp 100644
View File

@ -0,0 +1,5 @@
#include <iostream>
int main() {
return 0;
}

172
provider.cxx 100644
View File

@ -0,0 +1,172 @@
#include <algorithm>
#include <arpa/inet.h>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <random>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <csignal>
#include "fragment_dataformat.h"
#define MIN_FRAGMENTS 0
#define MAX_FRAGMENTS 1024
#define MEAN_FRAG 1
#define STDDEV_FRAG 0
#define MEAN_TIME_MS 0
#define STDDEV_TIME_MS 0
/*
int rndError(float p){
float rndFloat = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
return rndFloat < p;
}*/
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void connectTo(int sock, const char* host, int port) {
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(host);
serv_addr.sin_port = htons(port);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to %s: %d\n", host, port);
}
void term_handler(int signal) {
printf("Terminated, received SIGNAL %d", signal);
exit(EXIT_SUCCESS);
}
int main(int argc, char* argv[]) {
signal(SIGTERM, term_handler);
signal(SIGINT, term_handler);
//will use it later to obtain random number from hardware
std::random_device rd;
std::mt19937 generator(42);
std::discrete_distribution<uint8_t> discrete_distr({0.9, 0.1});
std::normal_distribution<float> normal_distr(MEAN_FRAG, STDDEV_FRAG);
std::uniform_int_distribution<uint32_t> unif_int_distib;
std::normal_distribution<float> normal_distrib_time(MEAN_TIME_MS, STDDEV_TIME_MS);
//commenting all old_style generation
//srand (static_cast <unsigned> (42));
bool out_condition = true;
uint32_t event_number = 0;
uint32_t run_number = 0;
uint32_t source_id = 0;
if (argc != 5) {
printf("Usage %s host portNumber sourceId runNumber\n", argv[0]);
exit(EXIT_FAILURE);
}
const char* host = argv[1];
int port = atoi(argv[2]);
source_id = atoi(argv[3]);
run_number = atoi(argv[4]);
int socket = makeSocket();
const int opt = 1;
if( setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&opt,
sizeof(opt)) < 0 )
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
connectTo(socket, host, port);
while (true) {
Fragment fragment;
Header& header = fragment.header;
header.sourceIdentifier = source_id;
header.runNumber = run_number;
header.detectorEventNumber = event_number;
event_number++;
header.numberOfStatusElements = 0;
//if swap to old style just change with function above and prob 0.1 for 1
uint8_t incorrectError = discrete_distr(generator);
uint8_t corruptedError = discrete_distr(generator);
uint8_t missingDataError = discrete_distr(generator);
//uint8_t timeoutError = discrete_distr(generator);
uint32_t firstStatusElement = 0x0;
if (incorrectError) firstStatusElement |= INCORRECT_ERROR;
if (corruptedError) firstStatusElement |= CORRUPTED_ERROR;
if (missingDataError) firstStatusElement |= MISSING_DATA_ERROR;
//if (timeoutError) firstStatusElement |= TIMEOUT_ERROR;
if (firstStatusElement != 0x0) {
header.numberOfStatusElements = 1;
header.statusElementsArray = new uint32_t[header.numberOfStatusElements];
header.statusElementsArray[0] = firstStatusElement;
}
uint32_t payload_size = std::max(std::min(static_cast<int>(std::round(normal_distr(generator))), MAX_FRAGMENTS), MIN_FRAGMENTS);
header.headerSize = 7 + header.numberOfStatusElements;
header.fragmentSize = header.headerSize + payload_size;
fragment.payloadElements = new uint32_t[payload_size];
for (uint32_t i = 0; i < payload_size; i++) {
fragment.payloadElements[i] = unif_int_distib(generator);
}
uint32_t buffer[header.fragmentSize];
encode_fragment(buffer, fragment);
//printFragment(fragment);
ssize_t bytes = send(socket, reinterpret_cast<char*>(buffer), sizeof(buffer), 0);
//printf("sent bytes %zd\n", bytes);
if (bytes != header.fragmentSize * sizeof(uint32_t)) {
perror("Send failed: num bytes not matching");
exit(EXIT_FAILURE);
}
//std::cout << std::hex << std::setw(8) << std::setfill('0');
////std::cout << fragment.header;
//for (uint8_t i = 0; i < fragment.header.numberOfStatusElements; i++) {
// std::cout << "status element " << std::setw(8) << std::setfill('0') << fragment.header.statusElementsArray[i] << std::endl;
//}
//for (uint32_t i = 0; i < payload_size; i++) {
// std::cout << "payload element " << std::setw(8) << std::setfill('0') << fragment.payloadElements[i] << std::endl;
//}
//std::cout << std::endl;
//usleep(std::max(static_cast<int>(normal_distrib_time(generator) * 1e3), 0));
//usleep(10);
}
return 0;
}

View File

@ -0,0 +1,695 @@
times;means;
5.94664;2764.22;
5.99256;4350.62;
6.01936;4532.11;
6.05357;4495.74;
6.0838;4645.04;
6.11404;4843.81;
6.14368;5078.27;
6.17846;5290.04;
6.21851;5550.87;
6.25483;6299.81;
6.2891;6629.51;
6.29096;6758.66;
6.31143;6709.42;
6.35013;6874.94;
6.38715;7122.55;
6.41604;7267.55;
6.44828;7329.57;
6.47406;7606.71;
6.48831;7748.89;
6.5601;7783.62;
6.64595;7745.67;
6.70141;8088.61;
6.75381;8747.23;
6.76661;9013.87;
6.79962;8905.28;
6.82554;8972.22;
6.8589;9062.69;
6.87646;9201.15;
6.89458;9187.31;
6.93713;9133.35;
6.9565;9546.35;
6.97927;9622.05;
7.00038;9664.72;
7.03566;9593.19;
7.03874;9787.6;
7.06686;9655.66;
7.10865;9580.06;
7.14939;9647.41;
7.18879;9855.34;
7.23341;9756.2;
7.24568;9907.23;
7.26724;9828.31;
7.28077;9905.25;
7.31259;9906.48;
7.34186;10081.7;
7.39208;9976.54;
7.42067;10104.9;
7.47763;9902.46;
7.52285;10053.1;
7.54887;10126.4;
7.55694;10214.6;
7.59839;10088.9;
7.63761;10188.4;
7.67139;10257.7;
7.6926;10350.2;
7.72623;10458.7;
7.73899;10754;
7.7606;10812.6;
7.7854;10754;
7.81431;10782.6;
7.83129;10813.8;
7.86928;10660.4;
7.90181;10746.1;
7.94726;10718.9;
7.95845;10896.3;
7.9717;10882.6;
7.99388;10874;
8.02907;10843.1;
8.05949;10871;
8.08785;10895.3;
8.11821;10846.4;
8.1575;10964.3;
8.18908;10966;
8.21306;11021.3;
8.24813;11069.6;
8.28593;11287.1;
8.32754;11245.3;
8.33085;11452.1;
8.35359;11366.4;
8.40926;11259;
8.46403;11278.2;
8.50352;11364.8;
8.54087;11323.9;
8.58014;11401.8;
8.5872;11502.9;
8.60281;11460.1;
8.63144;11410.7;
8.64832;11517.8;
8.6864;11432.9;
8.70441;11573;
8.72577;11556.3;
8.74688;11604.1;
8.77275;11633.8;
8.81341;11550.3;
8.83956;11626.9;
8.88566;11625.6;
8.9277;11631.8;
8.93093;11795.6;
8.9517;11711.5;
8.95925;11804.5;
8.99457;11697;
9.02518;11853.7;
9.06196;11836.1;
9.08251;12019.4;
9.11923;12234.2;
9.13983;12289.9;
9.15852;12302.9;
9.20176;12167.3;
9.23791;12212.2;
9.2635;12312.9;
9.28674;12344.3;
9.30664;12386.6;
9.32785;12396.5;
9.35188;12387.1;
9.3666;12439.6;
9.39706;12329.9;
9.42888;12372;
9.46208;12478.1;
9.48237;12561.9;
9.50461;12571.2;
9.53233;12512.5;
9.54669;12593;
9.57599;12532.8;
9.61234;12607.9;
9.63895;12626.2;
9.67148;12562.7;
9.98389;12973.5;
10.293;15869.3;
10.4552;18833.1;
10.4855;20479.1;
10.5078;20685;
10.5226;20740;
10.5351;20785.6;
10.5502;20820.8;
10.5866;20617.7;
10.6065;20788.8;
10.651;20706.1;
10.6689;20829;
10.6967;20874.2;
10.726;20804.9;
10.7562;20816.8;
10.7944;20879.6;
10.8147;20964.8;
10.8469;20882.4;
10.8757;20910.5;
10.886;21140;
10.9178;21002.9;
10.9366;21212.2;
10.9718;21150.2;
10.9763;21312.8;
11.0157;21220.9;
11.0448;21234.3;
11.0533;21396.7;
11.0921;21395.7;
11.1072;21474.7;
11.1322;21534.3;
11.1771;21431.3;
11.195;21571.1;
11.2164;21540.9;
11.2614;21532.1;
11.2714;21734;
11.3051;21668;
11.322;21784.2;
11.356;21863.9;
11.4117;21868.7;
11.4558;21961.6;
11.4797;22092.2;
11.494;22231;
11.5322;22188.9;
11.5526;22325.5;
11.5723;22336.2;
12.062;22518.8;
12.1163;27816.9;
12.1887;28414.2;
12.2373;28517.9;
12.2684;28694.3;
12.2908;28825.1;
12.3049;28906.1;
12.3309;28925.6;
12.3573;28940.6;
12.3664;29065.6;
12.4071;28937.1;
12.4432;29048;
12.4698;29102.2;
12.5092;29110.9;
12.5332;29281.7;
12.5752;29167;
12.6068;29334.5;
12.616;29497;
12.6539;29521.8;
12.695;29593.1;
12.7179;29797.1;
12.7657;29806.4;
12.8038;29894.9;
12.839;29930.5;
12.8698;30106.3;
12.9186;30102.4;
12.9403;30325.6;
12.9658;30323.3;
13.0002;30445.3;
13.0165;30507.3;
13.0452;30542.7;
13.0731;30514.6;
13.0764;30687.3;
13.1015;30635;
13.1584;30620.8;
13.1961;30808.9;
13.2228;30896;
13.259;30853.6;
13.293;31034;
13.3068;31110.1;
13.3191;31183.4;
13.345;31135.8;
13.3577;31330.5;
13.3889;31302.3;
13.4147;31402.4;
13.4431;31493.3;
13.4778;31595.9;
13.5036;31605.2;
13.5349;31744.1;
13.5552;31828.2;
13.5999;31846.5;
13.642;31861.1;
13.6527;32107.3;
13.678;32163.2;
13.7055;32159.8;
13.7452;32299;
13.7665;32361.2;
13.7757;32491.6;
13.7865;32540.1;
13.8188;32515.3;
13.841;32873.9;
13.871;32855;
13.8981;32990.8;
13.9232;33043.2;
13.9435;33150.3;
13.9827;33171.7;
14.01;33376.2;
14.0153;33511.2;
14.0572;33341.2;
14.0915;33465.4;
14.1298;33644.3;
14.1443;33777.2;
14.1818;33579.6;
14.2016;33836.1;
14.2246;33799.8;
14.2444;33924.5;
14.2746;33895;
14.3021;34041.2;
14.3112;34184.3;
14.3745;33983.3;
14.4135;34230.5;
14.4437;34233.2;
14.5005;34185.1;
14.523;34469.1;
14.5836;34426.7;
14.6268;34584.3;
14.6836;34607.8;
14.7306;34589.6;
14.7867;34833.9;
14.8057;35022.9;
14.8453;35014;
14.8862;35079.8;
14.9249;35124.8;
14.9615;35440.9;
15.0101;35478.4;
15.0555;35560.3;
15.0996;35595.3;
15.1418;35762.1;
15.1532;35883.4;
15.1568;35898.4;
15.1823;35823.1;
15.2008;36074.2;
15.2358;36129.8;
15.2718;36289.7;
15.287;36426.3;
15.2997;36575.7;
15.3034;36677.3;
15.349;36630.3;
15.3811;36941.5;
15.4221;37218.2;
15.4448;37435.5;
15.4765;37565.6;
15.5081;37787.7;
15.5597;37854.7;
15.6154;38075.2;
15.6875;38460.6;
15.726;38885.1;
15.7781;38912.8;
15.8232;39369;
15.8683;39427;
15.9002;39836.9;
15.9044;39936.7;
15.9536;39894.2;
16.0047;40407.8;
16.0385;40569;
16.0771;40741.6;
16.1093;40829.3;
16.1597;40826.9;
16.1862;41018;
16.1974;41131;
16.2386;40969.2;
16.2584;41226.1;
16.3109;41280.5;
16.3832;41577.8;
16.4321;42127;
16.4705;42330.1;
16.5062;42369.8;
16.5634;42413;
16.574;42857.8;
16.6207;42714.9;
16.6498;43232.4;
16.6905;43444.4;
16.7127;43637.5;
16.7665;43686.7;
16.8163;44177.3;
16.8363;44419.3;
16.8845;44391.9;
16.931;44592.1;
16.9562;44788.6;
16.9814;45118.8;
17.0207;45260.4;
17.0418;45633;
17.0993;45880.1;
17.1379;46279.8;
17.1741;46586.5;
17.2197;46990.5;
17.2458;47369;
17.276;47612.8;
17.2774;47785.2;
17.3238;47916.1;
17.3732;48263.8;
17.4282;48706.7;
17.4936;49175.1;
17.5067;49533.8;
17.5426;49647.3;
17.563;49999.8;
17.595;50219.7;
17.6299;50693;
17.6888;50886.4;
17.7463;51535.6;
17.7943;51967.1;
17.8405;52468.1;
17.8839;52872.5;
17.9186;53245.7;
17.9565;53601.9;
17.9963;53818.2;
18.0366;53904.9;
18.0646;54305.8;
18.0943;54464.3;
18.1698;55118;
18.2016;55383;
18.2172;55669.6;
18.256;55728;
18.2781;56053.3;
18.3198;56129.7;
18.3676;56221.2;
18.4015;56469.8;
18.4243;56571.2;
18.4518;56653.5;
18.4716;56826.9;
18.5;56810.3;
18.5204;57030.5;
18.5458;57087;
18.5632;57305.1;
18.5873;57299;
18.6138;57311.2;
18.6343;57556.8;
18.6677;57473.6;
18.7029;57542;
18.7271;57872.8;
18.7312;58013.7;
18.7638;57922;
18.7926;58019.8;
18.8294;58080.2;
18.8486;58141.8;
18.8927;58236.7;
18.9212;58371.2;
18.9458;58609.4;
18.9845;58641.3;
19.0179;58980;
19.0536;59049;
19.0807;59093.5;
19.1043;59185.1;
19.1598;59187.7;
19.1871;59384.3;
19.2045;59537.3;
19.2239;59544.7;
19.2433;59624.6;
19.281;59572.9;
19.3089;59787.3;
19.3253;59878.7;
19.3648;59928.9;
19.378;60161;
19.4196;60121.4;
19.4319;60352.1;
19.4709;60387.3;
19.4865;60561.8;
19.5206;60500.3;
19.543;60669.7;
19.5685;60726.5;
19.6065;60831.3;
19.6426;60831.1;
19.6826;60957.2;
19.6934;61201.3;
19.7282;61215.1;
19.7412;61336.4;
19.7627;61314.1;
19.7983;61282.1;
19.8214;61451.2;
19.8307;61690.1;
19.8617;61704.4;
19.8843;61897.8;
19.9102;61954.4;
19.9317;61950.5;
19.9425;62128.8;
19.9524;62187.1;
19.9686;62228;
19.9828;62277;
20.0015;62353.7;
20.0253;62448.6;
20.055;62554.6;
20.0826;62554.6;
20.1257;62573.9;
20.1662;62684.4;
20.181;62859.4;
20.1905;62909.4;
20.2086;62847.4;
20.2426;62908.4;
20.2611;63132.9;
20.2757;63156.5;
20.3041;63146.5;
20.3412;63208.8;
20.3686;63294.8;
20.4082;63532.6;
20.4235;63678.2;
20.4715;63551;
20.5018;63904.1;
20.5247;64074;
20.5576;64073;
20.5687;64240.2;
20.6022;64126.9;
20.6413;64335.2;
20.6858;64468.5;
20.7408;64531;
20.7956;64688.8;
20.8316;64913.4;
20.871;64975.6;
20.9201;65098.1;
20.9441;65323.2;
20.9898;65570.2;
21.0213;65576.8;
21.0421;65768;
21.0715;65732.2;
21.1278;65901.7;
21.1481;66152.5;
21.1894;66265.4;
21.2179;66362.6;
21.2392;66456.7;
21.2614;66580.5;
21.3006;66714;
21.322;66850.7;
21.3409;66892.4;
21.3787;66940;
21.417;67170.8;
21.433;67293;
21.4497;67325.5;
21.5001;67368.7;
21.5446;67535.8;
21.572;67834.2;
21.6104;67788.3;
21.6456;68067.6;
21.6616;68163.1;
21.6871;68290.5;
21.7191;68347.8;
21.7635;68451.4;
21.7965;68640.8;
21.8156;68876.4;
21.8574;68919.7;
21.8874;69213.2;
21.9194;69217;
21.9469;69388.4;
21.9875;69581.9;
22.0268;69630.6;
22.0807;69627.2;
22.1349;69692.7;
22.1719;69886.1;
22.1891;70045.7;
22.2273;70027.5;
22.2784;70094.2;
22.3033;70226.1;
22.3414;70402.4;
22.3567;70559.6;
22.3939;70526.2;
22.4222;70941;
22.4543;71038;
22.5098;71140.5;
22.522;71432;
22.5632;71257.9;
22.5985;71668.3;
22.6325;72068.3;
22.6766;72253.6;
22.6926;72511.2;
22.7068;72602.9;
22.7457;72766.6;
22.7747;72889.3;
22.8134;73076.7;
22.8171;73308.6;
22.8414;73321.8;
22.8652;73491.8;
22.8795;73604.9;
22.9151;73629.7;
22.9459;73783.6;
22.9797;73893.8;
23.0197;73903.3;
23.0478;74196.3;
23.0639;74458.5;
23.0968;74469.3;
23.1237;74511.1;
23.1417;74665;
23.1799;74831;
23.206;74965.4;
23.2393;75035.9;
23.2672;75232.4;
23.3075;75442.8;
23.3391;75492.3;
23.3635;75647.8;
23.393;75716.3;
23.4293;75932;
23.4709;76063.5;
23.4974;76244.3;
23.5019;76494.3;
23.5345;76515;
23.5647;76696.2;
23.5963;76913.9;
23.6313;76983.1;
23.6582;77305.8;
23.6922;77374.4;
23.7223;77556.6;
23.7372;77678.3;
23.7615;77739;
23.7933;77819.8;
23.8459;78024.2;
23.8733;78450.7;
23.891;78598.8;
23.9316;78517.3;
24.0049;78720.1;
24.0795;79071;
24.1405;79523.6;
24.1623;79739.1;
24.2031;79636;
24.2533;79802.8;
24.2892;79927.2;
24.3491;80110.8;
24.4009;80392.8;
24.4702;80485.9;
24.5201;80700.8;
24.5422;80815.8;
24.5758;80773.5;
24.6249;80953.5;
24.6642;81118.4;
24.7035;81345.8;
24.7615;81464.7;
24.7792;81752.2;
24.82;81799.8;
24.8641;81886.7;
24.9131;81928;
24.9232;82290.3;
24.9692;82359.9;
25.0079;82756.4;
25.0422;82837.7;
25.076;83004.2;
25.1203;83072.1;
25.1754;83126;
25.2361;83386.1;
25.3154;83535;
25.4079;84004.8;
25.4762;84086.2;
25.5473;84688.8;
25.587;84991.9;
25.6329;85277;
25.7128;85672.9;
25.7867;86178.9;
25.8641;86720.4;
25.9256;87290.7;
25.9623;87608.7;
26.0281;87917.6;
26.0652;88307.9;
26.1164;88598.8;
26.1565;88916.7;
26.1779;89193;
26.2055;89334.7;
26.275;89753.8;
26.2901;90327.9;
26.3146;90364;
26.3358;90600.1;
26.3951;90708.6;
26.4403;91228.3;
26.4853;91590.4;
26.5348;91784.4;
26.5791;92122.9;
26.6034;92552.4;
26.6497;92683.6;
26.6864;93010.1;
26.6919;93367;
26.7338;93295.5;
26.7633;93690.7;
26.817;93878.2;
26.844;94227.3;
26.8816;94385.5;
26.9241;94678.5;
26.9865;94832.8;
27.031;95398.1;
27.0632;95674.8;
27.0784;95926.5;
27.1268;95928.9;
27.1697;96255.7;
27.2148;96584.2;
27.2387;97000.2;
27.2877;97222.3;
27.335;97568.8;
27.3782;97871.7;
27.4253;98310;
27.4762;98671.1;
27.5022;98914.8;
27.5469;99082.3;
27.5828;99435.8;
27.6234;99719.7;
27.6556;100010;
27.7048;100205;
27.7406;100511;
27.7918;100841;
27.8299;101147;
27.8861;101555;
27.9247;101801;
27.9533;102089;
27.9877;102342;
28.0308;102563;
28.061;102943;
28.0943;103207;
28.111;103419;
28.1543;103621;
28.1893;104103;
28.2189;104419;
28.2643;104424;
28.306;104860;
28.3348;105104;
28.3671;105398;
28.3881;105644;
28.421;105633;
28.4597;106032;
28.5037;106253;
28.5501;106493;
28.5838;106754;
28.6352;106711;
28.6871;106909;
28.7273;107261;
28.7662;107375;
28.7949;107479;
28.8222;107571;
28.8707;107597;
28.9108;107878;
28.9646;108073;
28.9986;108350;
29.0343;108453;
29.0892;108748;
29.1102;108939;
29.1801;108931;
29.2113;109545;
29.2381;109613;
29.2583;109743;
29.2896;109763;
29.3594;109928;
29.4101;110750;
29.4213;111140;
29.4719;111285;
29.5174;111935;
29.5491;112239;
29.5921;112407;
29.6061;112815;
29.6427;112973;
29.6591;113253;
29.6868;113289;
29.7122;113418;
29.743;113493;
29.7715;113578;
29.7956;113748;
29.8356;113880;
29.8795;114274;
29.9023;114454;
29.9372;114538;
29.9557;114747;
29.9871;114845;
30.0164;114892;
1 times means
2 5.94664 2764.22
3 5.99256 4350.62
4 6.01936 4532.11
5 6.05357 4495.74
6 6.0838 4645.04
7 6.11404 4843.81
8 6.14368 5078.27
9 6.17846 5290.04
10 6.21851 5550.87
11 6.25483 6299.81
12 6.2891 6629.51
13 6.29096 6758.66
14 6.31143 6709.42
15 6.35013 6874.94
16 6.38715 7122.55
17 6.41604 7267.55
18 6.44828 7329.57
19 6.47406 7606.71
20 6.48831 7748.89
21 6.5601 7783.62
22 6.64595 7745.67
23 6.70141 8088.61
24 6.75381 8747.23
25 6.76661 9013.87
26 6.79962 8905.28
27 6.82554 8972.22
28 6.8589 9062.69
29 6.87646 9201.15
30 6.89458 9187.31
31 6.93713 9133.35
32 6.9565 9546.35
33 6.97927 9622.05
34 7.00038 9664.72
35 7.03566 9593.19
36 7.03874 9787.6
37 7.06686 9655.66
38 7.10865 9580.06
39 7.14939 9647.41
40 7.18879 9855.34
41 7.23341 9756.2
42 7.24568 9907.23
43 7.26724 9828.31
44 7.28077 9905.25
45 7.31259 9906.48
46 7.34186 10081.7
47 7.39208 9976.54
48 7.42067 10104.9
49 7.47763 9902.46
50 7.52285 10053.1
51 7.54887 10126.4
52 7.55694 10214.6
53 7.59839 10088.9
54 7.63761 10188.4
55 7.67139 10257.7
56 7.6926 10350.2
57 7.72623 10458.7
58 7.73899 10754
59 7.7606 10812.6
60 7.7854 10754
61 7.81431 10782.6
62 7.83129 10813.8
63 7.86928 10660.4
64 7.90181 10746.1
65 7.94726 10718.9
66 7.95845 10896.3
67 7.9717 10882.6
68 7.99388 10874
69 8.02907 10843.1
70 8.05949 10871
71 8.08785 10895.3
72 8.11821 10846.4
73 8.1575 10964.3
74 8.18908 10966
75 8.21306 11021.3
76 8.24813 11069.6
77 8.28593 11287.1
78 8.32754 11245.3
79 8.33085 11452.1
80 8.35359 11366.4
81 8.40926 11259
82 8.46403 11278.2
83 8.50352 11364.8
84 8.54087 11323.9
85 8.58014 11401.8
86 8.5872 11502.9
87 8.60281 11460.1
88 8.63144 11410.7
89 8.64832 11517.8
90 8.6864 11432.9
91 8.70441 11573
92 8.72577 11556.3
93 8.74688 11604.1
94 8.77275 11633.8
95 8.81341 11550.3
96 8.83956 11626.9
97 8.88566 11625.6
98 8.9277 11631.8
99 8.93093 11795.6
100 8.9517 11711.5
101 8.95925 11804.5
102 8.99457 11697
103 9.02518 11853.7
104 9.06196 11836.1
105 9.08251 12019.4
106 9.11923 12234.2
107 9.13983 12289.9
108 9.15852 12302.9
109 9.20176 12167.3
110 9.23791 12212.2
111 9.2635 12312.9
112 9.28674 12344.3
113 9.30664 12386.6
114 9.32785 12396.5
115 9.35188 12387.1
116 9.3666 12439.6
117 9.39706 12329.9
118 9.42888 12372
119 9.46208 12478.1
120 9.48237 12561.9
121 9.50461 12571.2
122 9.53233 12512.5
123 9.54669 12593
124 9.57599 12532.8
125 9.61234 12607.9
126 9.63895 12626.2
127 9.67148 12562.7
128 9.98389 12973.5
129 10.293 15869.3
130 10.4552 18833.1
131 10.4855 20479.1
132 10.5078 20685
133 10.5226 20740
134 10.5351 20785.6
135 10.5502 20820.8
136 10.5866 20617.7
137 10.6065 20788.8
138 10.651 20706.1
139 10.6689 20829
140 10.6967 20874.2
141 10.726 20804.9
142 10.7562 20816.8
143 10.7944 20879.6
144 10.8147 20964.8
145 10.8469 20882.4
146 10.8757 20910.5
147 10.886 21140
148 10.9178 21002.9
149 10.9366 21212.2
150 10.9718 21150.2
151 10.9763 21312.8
152 11.0157 21220.9
153 11.0448 21234.3
154 11.0533 21396.7
155 11.0921 21395.7
156 11.1072 21474.7
157 11.1322 21534.3
158 11.1771 21431.3
159 11.195 21571.1
160 11.2164 21540.9
161 11.2614 21532.1
162 11.2714 21734
163 11.3051 21668
164 11.322 21784.2
165 11.356 21863.9
166 11.4117 21868.7
167 11.4558 21961.6
168 11.4797 22092.2
169 11.494 22231
170 11.5322 22188.9
171 11.5526 22325.5
172 11.5723 22336.2
173 12.062 22518.8
174 12.1163 27816.9
175 12.1887 28414.2
176 12.2373 28517.9
177 12.2684 28694.3
178 12.2908 28825.1
179 12.3049 28906.1
180 12.3309 28925.6
181 12.3573 28940.6
182 12.3664 29065.6
183 12.4071 28937.1
184 12.4432 29048
185 12.4698 29102.2
186 12.5092 29110.9
187 12.5332 29281.7
188 12.5752 29167
189 12.6068 29334.5
190 12.616 29497
191 12.6539 29521.8
192 12.695 29593.1
193 12.7179 29797.1
194 12.7657 29806.4
195 12.8038 29894.9
196 12.839 29930.5
197 12.8698 30106.3
198 12.9186 30102.4
199 12.9403 30325.6
200 12.9658 30323.3
201 13.0002 30445.3
202 13.0165 30507.3
203 13.0452 30542.7
204 13.0731 30514.6
205 13.0764 30687.3
206 13.1015 30635
207 13.1584 30620.8
208 13.1961 30808.9
209 13.2228 30896
210 13.259 30853.6
211 13.293 31034
212 13.3068 31110.1
213 13.3191 31183.4
214 13.345 31135.8
215 13.3577 31330.5
216 13.3889 31302.3
217 13.4147 31402.4
218 13.4431 31493.3
219 13.4778 31595.9
220 13.5036 31605.2
221 13.5349 31744.1
222 13.5552 31828.2
223 13.5999 31846.5
224 13.642 31861.1
225 13.6527 32107.3
226 13.678 32163.2
227 13.7055 32159.8
228 13.7452 32299
229 13.7665 32361.2
230 13.7757 32491.6
231 13.7865 32540.1
232 13.8188 32515.3
233 13.841 32873.9
234 13.871 32855
235 13.8981 32990.8
236 13.9232 33043.2
237 13.9435 33150.3
238 13.9827 33171.7
239 14.01 33376.2
240 14.0153 33511.2
241 14.0572 33341.2
242 14.0915 33465.4
243 14.1298 33644.3
244 14.1443 33777.2
245 14.1818 33579.6
246 14.2016 33836.1
247 14.2246 33799.8
248 14.2444 33924.5
249 14.2746 33895
250 14.3021 34041.2
251 14.3112 34184.3
252 14.3745 33983.3
253 14.4135 34230.5
254 14.4437 34233.2
255 14.5005 34185.1
256 14.523 34469.1
257 14.5836 34426.7
258 14.6268 34584.3
259 14.6836 34607.8
260 14.7306 34589.6
261 14.7867 34833.9
262 14.8057 35022.9
263 14.8453 35014
264 14.8862 35079.8
265 14.9249 35124.8
266 14.9615 35440.9
267 15.0101 35478.4
268 15.0555 35560.3
269 15.0996 35595.3
270 15.1418 35762.1
271 15.1532 35883.4
272 15.1568 35898.4
273 15.1823 35823.1
274 15.2008 36074.2
275 15.2358 36129.8
276 15.2718 36289.7
277 15.287 36426.3
278 15.2997 36575.7
279 15.3034 36677.3
280 15.349 36630.3
281 15.3811 36941.5
282 15.4221 37218.2
283 15.4448 37435.5
284 15.4765 37565.6
285 15.5081 37787.7
286 15.5597 37854.7
287 15.6154 38075.2
288 15.6875 38460.6
289 15.726 38885.1
290 15.7781 38912.8
291 15.8232 39369
292 15.8683 39427
293 15.9002 39836.9
294 15.9044 39936.7
295 15.9536 39894.2
296 16.0047 40407.8
297 16.0385 40569
298 16.0771 40741.6
299 16.1093 40829.3
300 16.1597 40826.9
301 16.1862 41018
302 16.1974 41131
303 16.2386 40969.2
304 16.2584 41226.1
305 16.3109 41280.5
306 16.3832 41577.8
307 16.4321 42127
308 16.4705 42330.1
309 16.5062 42369.8
310 16.5634 42413
311 16.574 42857.8
312 16.6207 42714.9
313 16.6498 43232.4
314 16.6905 43444.4
315 16.7127 43637.5
316 16.7665 43686.7
317 16.8163 44177.3
318 16.8363 44419.3
319 16.8845 44391.9
320 16.931 44592.1
321 16.9562 44788.6
322 16.9814 45118.8
323 17.0207 45260.4
324 17.0418 45633
325 17.0993 45880.1
326 17.1379 46279.8
327 17.1741 46586.5
328 17.2197 46990.5
329 17.2458 47369
330 17.276 47612.8
331 17.2774 47785.2
332 17.3238 47916.1
333 17.3732 48263.8
334 17.4282 48706.7
335 17.4936 49175.1
336 17.5067 49533.8
337 17.5426 49647.3
338 17.563 49999.8
339 17.595 50219.7
340 17.6299 50693
341 17.6888 50886.4
342 17.7463 51535.6
343 17.7943 51967.1
344 17.8405 52468.1
345 17.8839 52872.5
346 17.9186 53245.7
347 17.9565 53601.9
348 17.9963 53818.2
349 18.0366 53904.9
350 18.0646 54305.8
351 18.0943 54464.3
352 18.1698 55118
353 18.2016 55383
354 18.2172 55669.6
355 18.256 55728
356 18.2781 56053.3
357 18.3198 56129.7
358 18.3676 56221.2
359 18.4015 56469.8
360 18.4243 56571.2
361 18.4518 56653.5
362 18.4716 56826.9
363 18.5 56810.3
364 18.5204 57030.5
365 18.5458 57087
366 18.5632 57305.1
367 18.5873 57299
368 18.6138 57311.2
369 18.6343 57556.8
370 18.6677 57473.6
371 18.7029 57542
372 18.7271 57872.8
373 18.7312 58013.7
374 18.7638 57922
375 18.7926 58019.8
376 18.8294 58080.2
377 18.8486 58141.8
378 18.8927 58236.7
379 18.9212 58371.2
380 18.9458 58609.4
381 18.9845 58641.3
382 19.0179 58980
383 19.0536 59049
384 19.0807 59093.5
385 19.1043 59185.1
386 19.1598 59187.7
387 19.1871 59384.3
388 19.2045 59537.3
389 19.2239 59544.7
390 19.2433 59624.6
391 19.281 59572.9
392 19.3089 59787.3
393 19.3253 59878.7
394 19.3648 59928.9
395 19.378 60161
396 19.4196 60121.4
397 19.4319 60352.1
398 19.4709 60387.3
399 19.4865 60561.8
400 19.5206 60500.3
401 19.543 60669.7
402 19.5685 60726.5
403 19.6065 60831.3
404 19.6426 60831.1
405 19.6826 60957.2
406 19.6934 61201.3
407 19.7282 61215.1
408 19.7412 61336.4
409 19.7627 61314.1
410 19.7983 61282.1
411 19.8214 61451.2
412 19.8307 61690.1
413 19.8617 61704.4
414 19.8843 61897.8
415 19.9102 61954.4
416 19.9317 61950.5
417 19.9425 62128.8
418 19.9524 62187.1
419 19.9686 62228
420 19.9828 62277
421 20.0015 62353.7
422 20.0253 62448.6
423 20.055 62554.6
424 20.0826 62554.6
425 20.1257 62573.9
426 20.1662 62684.4
427 20.181 62859.4
428 20.1905 62909.4
429 20.2086 62847.4
430 20.2426 62908.4
431 20.2611 63132.9
432 20.2757 63156.5
433 20.3041 63146.5
434 20.3412 63208.8
435 20.3686 63294.8
436 20.4082 63532.6
437 20.4235 63678.2
438 20.4715 63551
439 20.5018 63904.1
440 20.5247 64074
441 20.5576 64073
442 20.5687 64240.2
443 20.6022 64126.9
444 20.6413 64335.2
445 20.6858 64468.5
446 20.7408 64531
447 20.7956 64688.8
448 20.8316 64913.4
449 20.871 64975.6
450 20.9201 65098.1
451 20.9441 65323.2
452 20.9898 65570.2
453 21.0213 65576.8
454 21.0421 65768
455 21.0715 65732.2
456 21.1278 65901.7
457 21.1481 66152.5
458 21.1894 66265.4
459 21.2179 66362.6
460 21.2392 66456.7
461 21.2614 66580.5
462 21.3006 66714
463 21.322 66850.7
464 21.3409 66892.4
465 21.3787 66940
466 21.417 67170.8
467 21.433 67293
468 21.4497 67325.5
469 21.5001 67368.7
470 21.5446 67535.8
471 21.572 67834.2
472 21.6104 67788.3
473 21.6456 68067.6
474 21.6616 68163.1
475 21.6871 68290.5
476 21.7191 68347.8
477 21.7635 68451.4
478 21.7965 68640.8
479 21.8156 68876.4
480 21.8574 68919.7
481 21.8874 69213.2
482 21.9194 69217
483 21.9469 69388.4
484 21.9875 69581.9
485 22.0268 69630.6
486 22.0807 69627.2
487 22.1349 69692.7
488 22.1719 69886.1
489 22.1891 70045.7
490 22.2273 70027.5
491 22.2784 70094.2
492 22.3033 70226.1
493 22.3414 70402.4
494 22.3567 70559.6
495 22.3939 70526.2
496 22.4222 70941
497 22.4543 71038
498 22.5098 71140.5
499 22.522 71432
500 22.5632 71257.9
501 22.5985 71668.3
502 22.6325 72068.3
503 22.6766 72253.6
504 22.6926 72511.2
505 22.7068 72602.9
506 22.7457 72766.6
507 22.7747 72889.3
508 22.8134 73076.7
509 22.8171 73308.6
510 22.8414 73321.8
511 22.8652 73491.8
512 22.8795 73604.9
513 22.9151 73629.7
514 22.9459 73783.6
515 22.9797 73893.8
516 23.0197 73903.3
517 23.0478 74196.3
518 23.0639 74458.5
519 23.0968 74469.3
520 23.1237 74511.1
521 23.1417 74665
522 23.1799 74831
523 23.206 74965.4
524 23.2393 75035.9
525 23.2672 75232.4
526 23.3075 75442.8
527 23.3391 75492.3
528 23.3635 75647.8
529 23.393 75716.3
530 23.4293 75932
531 23.4709 76063.5
532 23.4974 76244.3
533 23.5019 76494.3
534 23.5345 76515
535 23.5647 76696.2
536 23.5963 76913.9
537 23.6313 76983.1
538 23.6582 77305.8
539 23.6922 77374.4
540 23.7223 77556.6
541 23.7372 77678.3
542 23.7615 77739
543 23.7933 77819.8
544 23.8459 78024.2
545 23.8733 78450.7
546 23.891 78598.8
547 23.9316 78517.3
548 24.0049 78720.1
549 24.0795 79071
550 24.1405 79523.6
551 24.1623 79739.1
552 24.2031 79636
553 24.2533 79802.8
554 24.2892 79927.2
555 24.3491 80110.8
556 24.4009 80392.8
557 24.4702 80485.9
558 24.5201 80700.8
559 24.5422 80815.8
560 24.5758 80773.5
561 24.6249 80953.5
562 24.6642 81118.4
563 24.7035 81345.8
564 24.7615 81464.7
565 24.7792 81752.2
566 24.82 81799.8
567 24.8641 81886.7
568 24.9131 81928
569 24.9232 82290.3
570 24.9692 82359.9
571 25.0079 82756.4
572 25.0422 82837.7
573 25.076 83004.2
574 25.1203 83072.1
575 25.1754 83126
576 25.2361 83386.1
577 25.3154 83535
578 25.4079 84004.8
579 25.4762 84086.2
580 25.5473 84688.8
581 25.587 84991.9
582 25.6329 85277
583 25.7128 85672.9
584 25.7867 86178.9
585 25.8641 86720.4
586 25.9256 87290.7
587 25.9623 87608.7
588 26.0281 87917.6
589 26.0652 88307.9
590 26.1164 88598.8
591 26.1565 88916.7
592 26.1779 89193
593 26.2055 89334.7
594 26.275 89753.8
595 26.2901 90327.9
596 26.3146 90364
597 26.3358 90600.1
598 26.3951 90708.6
599 26.4403 91228.3
600 26.4853 91590.4
601 26.5348 91784.4
602 26.5791 92122.9
603 26.6034 92552.4
604 26.6497 92683.6
605 26.6864 93010.1
606 26.6919 93367
607 26.7338 93295.5
608 26.7633 93690.7
609 26.817 93878.2
610 26.844 94227.3
611 26.8816 94385.5
612 26.9241 94678.5
613 26.9865 94832.8
614 27.031 95398.1
615 27.0632 95674.8
616 27.0784 95926.5
617 27.1268 95928.9
618 27.1697 96255.7
619 27.2148 96584.2
620 27.2387 97000.2
621 27.2877 97222.3
622 27.335 97568.8
623 27.3782 97871.7
624 27.4253 98310
625 27.4762 98671.1
626 27.5022 98914.8
627 27.5469 99082.3
628 27.5828 99435.8
629 27.6234 99719.7
630 27.6556 100010
631 27.7048 100205
632 27.7406 100511
633 27.7918 100841
634 27.8299 101147
635 27.8861 101555
636 27.9247 101801
637 27.9533 102089
638 27.9877 102342
639 28.0308 102563
640 28.061 102943
641 28.0943 103207
642 28.111 103419
643 28.1543 103621
644 28.1893 104103
645 28.2189 104419
646 28.2643 104424
647 28.306 104860
648 28.3348 105104
649 28.3671 105398
650 28.3881 105644
651 28.421 105633
652 28.4597 106032
653 28.5037 106253
654 28.5501 106493
655 28.5838 106754
656 28.6352 106711
657 28.6871 106909
658 28.7273 107261
659 28.7662 107375
660 28.7949 107479
661 28.8222 107571
662 28.8707 107597
663 28.9108 107878
664 28.9646 108073
665 28.9986 108350
666 29.0343 108453
667 29.0892 108748
668 29.1102 108939
669 29.1801 108931
670 29.2113 109545
671 29.2381 109613
672 29.2583 109743
673 29.2896 109763
674 29.3594 109928
675 29.4101 110750
676 29.4213 111140
677 29.4719 111285
678 29.5174 111935
679 29.5491 112239
680 29.5921 112407
681 29.6061 112815
682 29.6427 112973
683 29.6591 113253
684 29.6868 113289
685 29.7122 113418
686 29.743 113493
687 29.7715 113578
688 29.7956 113748
689 29.8356 113880
690 29.8795 114274
691 29.9023 114454
692 29.9372 114538
693 29.9557 114747
694 29.9871 114845
695 30.0164 114892

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

17
simulation.sh 100755
View File

@ -0,0 +1,17 @@
#!/bin/bash
list=(1 10 20 30 40 50 100 500)
echo starting
for t in ${list[@]}; do
./evBuild.out 7777 5 200 $t &
pid=$!
sleep 2
./spawn_clients.sh "127.0.0.1" 7777 5 200
echo $pid
wait $pid
kill $pid
sleep 1
echo "new iteration"
done

12
spawn_clients.sh 100755
View File

@ -0,0 +1,12 @@
#!/bin/bash
echo "Usage: $0 host port runNumber numberOfProviders"
if [ $# -eq 4 ]
then
echo "Selected host: $1:$2 runNumber: $3 numberOfProviders: $4"
for i in $(seq 1 $4);
do
echo "Spawning provider number $i"
./prov.out $1 $2 $i $3 &
done
fi

Binary file not shown.

View File

@ -0,0 +1,105 @@
#include <algorithm>
#include <arpa/inet.h>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <netinet/in.h>
#include <sys/socket.h>
#include <csignal>
#include <chrono>
#include <iostream>
#include <iomanip>
#include <tuple>
#include <unistd.h>
#include <vector>
#include <fstream>
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void connectTo(int sock, const char* host, int port) {
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(host);
serv_addr.sin_port = htons(port);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to %s: %d\n", host, port);
}
int main(int argc, char* argv[]) {
int socket = makeSocket();
connectTo(socket, "127.0.0.1", 7777);
//allocating 100 megabytes of memory
uint64_t* chunky_boy = new uint64_t[13107200];
size_t chunky_boy_size = 13107200 * sizeof(uint64_t);
printf("chonky size %d", static_cast<int>(chunky_boy_size));
sleep(5);
//setting memory to verify non-emptyness
memset(chunky_boy, 45678832, chunky_boy_size);
std::vector<int> sizes;
std::vector<double> times;
for ( int i = 1; i < 1e6 + 2; i += 1e3) {
printf("Selected buffer size: %d\n", i);
auto start = std::chrono::high_resolution_clock::now();
int kilos = 0;
for ( int j = 0; j < chunky_boy_size; ) {
ssize_t bytes = send(socket, reinterpret_cast<char*>(chunky_boy) + j, std::min(static_cast<int>(chunky_boy_size) - j, i), 0);
j += i;
if (j%1024 == 0) {
kilos++;
}
}
auto end = std::chrono::high_resolution_clock::now();
double time_taken = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
time_taken *= 1e-9;
times.push_back(time_taken);
sizes.push_back(i);
std::cout << "Time taken by program is : " << std::fixed
<< time_taken << std::setprecision(9);
std::cout << " sec" << std::endl;
}
std::ofstream fout;
fout.open("send_data_buffer");
fout << "buffer_size;time;\n";
auto iter_sizes = sizes.begin();
auto iter_times = times.begin();
for ( ; (iter_sizes != sizes.end()) && (iter_times != times.end()) ; (++iter_sizes, ++iter_times) ) {
fout << *iter_sizes << ";" << *iter_times << ";\n";
}
fout.close();
return 0;
}

Binary file not shown.

View File

@ -0,0 +1,91 @@
#include <arpa/inet.h>
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void bindSocketPort(int server_fd, int port) {
struct sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("FD %d bound to port %d\n", server_fd, port);
}
void startListening(int server_fd) {
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("FD %d listening to new connections\n", server_fd);
}
int acceptConnection(int server_fd) {
int client_fd;
struct sockaddr_in remoteAddr;
size_t addrlen = sizeof(remoteAddr);
if ((client_fd = accept(server_fd, (struct sockaddr *)&remoteAddr, (socklen_t *)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("Connection from host %s, port %d, FD %d\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port), client_fd);
return client_fd;
}
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: %s portNumber \n", argv[0]);
exit(EXIT_FAILURE);
}
int port = atoi(argv[1]);
printf("Start socket port %d\n", port);
int server_fd = makeSocket();
bindSocketPort(server_fd, port);
startListening(server_fd);
int client_fd = acceptConnection(server_fd);
uint64_t bytes_read = 0;
uint64_t kbytes_read = 0;
while (true) {
char buffer[32 * 1024] = {0};
ssize_t bytes = read(client_fd, &buffer, sizeof(buffer));
bytes_read += static_cast<uint64_t>(bytes);
//printf("tot bytos %lu\n", bytes_read);
if (uint64_t newkb = (bytes_read / 1024) > 0) {
//printf("before: %lu", bytes_read);
bytes_read -= (1024 * newkb);
//printf("after: %lu", bytes_read);
kbytes_read += newkb;
//printf("Read %d kbytes\n", static_cast<int>(kbytes_read));
}
}
return 0;
}

Binary file not shown.

View File

@ -0,0 +1,283 @@
#include <asm-generic/errno-base.h>
#include <asm-generic/errno.h>
#include <cerrno>
#include <cstddef>
#include <cstdio> // for fprintf()
#include <unistd.h> // for close(), read()
#include <sys/epoll.h> // for epoll_create1(), epoll_ctl(), struct epoll_event
#include <cstring> // for strncmp
//my addition to the online guide
#include <csignal>
#include <cstdlib>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <vector>
#include <chrono>
#include <fstream>
#define MAX_EVENTS 20000
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void bindSocketPort(int server_fd, int port) {
struct sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("FD %d bound to port %d\n", server_fd, port);
}
void startListening(int server_fd) {
if (listen(server_fd, 20000) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("FD %d listening to new connections\n", server_fd);
}
int acceptConnection(int server_fd) {
int client_fd;
struct sockaddr_in remoteAddr;
size_t addrlen = sizeof(remoteAddr);
if ((client_fd = accept(server_fd, (struct sockaddr *)&remoteAddr, (socklen_t *)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
} else {
int flags = fcntl(client_fd, F_GETFL);
fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
}
printf("Connection from host %s, port %d, FD %d\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port), client_fd);
return client_fd;
}
void acceptConnectionEpollStyle(int server_fd, int &efd) {
struct sockaddr_in new_remoteAddr;
int addrlen = sizeof(struct sockaddr_in);
while (true) {
int conn_sock = accept(server_fd, (struct sockaddr*)&new_remoteAddr, (socklen_t*)&addrlen);
if (conn_sock == -1) {
// All incoming connections have been processed
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
break;
} else {
perror("accept");
break;
}
}
// make new connection non-blocking
int flags = fcntl(conn_sock, F_GETFL, 0);
fcntl(conn_sock, F_SETFL, flags | O_NONBLOCK);
// monitor new connection for read events, always in edge triggered
struct epoll_event event;
event.events = EPOLLIN;// | EPOLLET;
event.data.fd = conn_sock;
// Allow epoll to monitor the new connection
if (epoll_ctl(efd, EPOLL_CTL_ADD, conn_sock, &event) == -1) {
perror("epoll_ctl: conn_sock");
break;
}
printf("Accepted epoll style connection from %s:%d from fd: %d\n", inet_ntoa(new_remoteAddr.sin_addr), ntohs(new_remoteAddr.sin_port), conn_sock);
}
}
void term_handler(int signal) {
printf("Terminated, received SIGNAL %d", signal);
exit(EXIT_SUCCESS);
}
int main(int argc, char const *argv[]) {
signal(SIGTERM, term_handler);
if (argc != 2) {
printf("Usage: %s portNumber \n", argv[0]);
exit(EXIT_FAILURE);
}
int port = atoi(argv[1]);
printf("Start socket port %d\n", port);
int master_socket;
const int opt = 1;
master_socket = makeSocket();
//set master socket to allow multiple connections ,
//this is just a good habit, it will work without this
if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
sizeof(opt)) < 0 )
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
bindSocketPort(master_socket, port);
startListening(master_socket);
int flags = fcntl(master_socket, F_GETFL, 0);
fcntl(master_socket, F_SETFL, flags | O_NONBLOCK);
struct epoll_event ev, events[MAX_EVENTS];
//create the epoll instance
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
printf("Failed to create epoll file descriptor\n");
exit(EXIT_FAILURE);
}
ev.data.fd = master_socket;
// Reading events with edge triggered mode
ev.events = EPOLLIN;// | EPOLLET;
// Allowing epoll to monitor the master_socket
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, master_socket, &ev) == -1){
perror("epoll_ctl");
exit(EXIT_FAILURE);
}
std::vector<int> sizes;
std::vector<uint64_t> tot_received_data;
std::vector<double> times;
int increment = 499;
for (int buf_size = 1; buf_size < 1e6 + 1; ) {
switch (buf_size) {
case 500:
increment = 500;
break;
case (int) 1e3:
increment = 1e3;
break;
case (int) 5e3:
increment = 5e3;
break;
case (int) 1e4:
increment = 1e4;
break;
case (int) 5e4:
increment = 5e4;
break;
case (int) 1e5:
increment = 1e5;
break;
case (int) 5e5:
increment = 5e5;
break;
}
printf("Next increment %d with current i: %d\n", increment, buf_size);
uint64_t bytes_read = 0;
uint64_t kBytes_read = 0;
double total_time_taken = 0;
while (true) {
// Time measurements
auto start = std::chrono::high_resolution_clock::now();
// Returns only the sockets for which there are events
//printf("Before wait\n");
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
//printf("After wait\n");
if (nfds == -1) {
perror("epoll_wait");
exit(EXIT_FAILURE);
}
// Iterate on the sockets having events
for (int i = 0; i < nfds; i++) {
//printf("Tot fds = %d reading from %d\n", nfds, i);
int fd = events[i].data.fd;
if (fd == master_socket) {
// If the activity is on the master socket, than it's a new connection request
acceptConnectionEpollStyle(master_socket, epoll_fd);
} else if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
// Than the client connection is closed, so I close it
printf("Closing %d", fd);
close(fd);
} else {
// Than we received data from one of the monitored sockets
char buffer[buf_size];
int valread = 0;
//while (valread != EAGAIN) {
valread = recv(fd, &buffer, buf_size, 0);
if (valread > 0) {
//printf("[RICEVUTO]\t FROM %d\n", fd);
bytes_read += valread;
int kilos = 0;
if ((kilos = bytes_read / 1024) > 0) {
kBytes_read += kilos;
bytes_read -= (kilos * 1024);
//printf("reade bites %lu", bytes_read);
}
}
//}
}
}
auto end = std::chrono::high_resolution_clock::now();
double time_taken = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
//time taken in milliseconds
time_taken *= 1e-6;
total_time_taken += time_taken;
if (total_time_taken > 3e4) {
times.push_back(total_time_taken);
sizes.push_back(buf_size);
tot_received_data.push_back(kBytes_read);
break;
}
}
buf_size += increment;
}
std::ofstream fout;
fout.open("epoll_data_stats_1000_TIMEOUT.csv");
//the time is in milliseconds and the data in kbytes
fout << "buffer_size;time;total_received_data;\n";
auto iter_sizes = sizes.begin();
auto iter_times = times.begin();
auto iter_data = tot_received_data.begin();
for ( ; (iter_sizes != sizes.end()) && (iter_times != times.end()) && (iter_data != tot_received_data.end()) ; (++iter_sizes, ++iter_times, ++iter_data) ) {
fout << *iter_sizes << ";" << *iter_times << ";" << *iter_data << ";\n";
}
fout.close();
if (close(epoll_fd)) {
printf("Failed to close epoll file descriptor");
exit(EXIT_FAILURE);
}
return 0;
}

View File

@ -0,0 +1,301 @@
#include <arpa/inet.h>
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#include <vector>
#include <chrono>
#include <fstream>
#include <fcntl.h>
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void bindSocketPort(int server_fd, int port) {
struct sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("FD %d bound to port %d\n", server_fd, port);
}
void startListening(int server_fd) {
if (listen(server_fd, 1024) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("FD %d listening to new connections\n", server_fd);
}
int acceptConnection(int server_fd) {
int client_fd;
struct sockaddr_in remoteAddr;
size_t addrlen = sizeof(remoteAddr);
if ((client_fd = accept(server_fd, (struct sockaddr *)&remoteAddr, (socklen_t *)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
} else {
int flags = fcntl(client_fd, F_GETFL);
fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
}
printf("Connection from host %s, port %d, FD %d\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port), client_fd);
return client_fd;
}
void term_handler(int signal) {
printf("Terminated, received SIGNAL %d", signal);
exit(EXIT_SUCCESS);
}
#define TRUE 1
#define FALSE 0
int main(int argc, char const *argv[]) {
signal(SIGTERM, term_handler);
if (argc != 2) {
printf("Usage: %s portNumber \n", argv[0]);
exit(EXIT_FAILURE);
}
int port = atoi(argv[1]);
printf("Start socket port %d\n", port);
int opt = TRUE;
int master_socket , addrlen , new_socket , client_socket[1024] ,
max_clients = 1024 , activity, i , valread , sd;
int max_sd;
//set of socket descriptors
fd_set readfds;
//initialise all client_socket[] to 0 so not checked
for (i = 0; i < max_clients; i++)
{
client_socket[i] = 0;
}
master_socket = makeSocket();
//set master socket to allow multiple connections ,
//this is just a good habit, it will work without this
if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
sizeof(opt)) < 0 )
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
bindSocketPort(master_socket, port);
startListening(master_socket);
int flags = fcntl(master_socket, F_GETFL, 0);
fcntl(master_socket, F_SETFL, flags | O_NONBLOCK);
std::vector<int> sizes;
std::vector<uint64_t> tot_received_data;
std::vector<double> times;
int increment = 499;
for (int kikko = 1; kikko < 1e6 + 1;) {
switch (kikko) {
case 500:
increment = 500;
break;
case (int) 1e3:
increment = 1e3;
break;
case (int) 5e3:
increment = 5e3;
break;
case (int) 1e4:
increment = 1e4;
break;
case (int) 5e4:
increment = 5e4;
break;
case (int) 1e5:
increment = 1e5;
break;
case (int) 5e5:
increment = 5e5;
break;
}
printf("Next increment %d with current i: %d\n", increment, kikko);
uint64_t bytes_read = 0;
uint64_t kBytes_read = 0;
double total_time_taken = 0;
while (true) {
auto start = std::chrono::high_resolution_clock::now();
//clear the socket set
FD_ZERO(&readfds);
//add master socket to set
FD_SET(master_socket, &readfds);
max_sd = master_socket;
//add child sockets to set
for ( i = 0 ; i < max_clients ; i++)
{
//socket descriptor
sd = client_socket[i];
//if valid socket descriptor then add to read list
if(sd > 0)
FD_SET( sd , &readfds);
//highest file descriptor number, need it for the select function
if(sd > max_sd)
max_sd = sd;
}
//wait for an activity on one of the sockets , timeout is NULL ,
//so wait indefinitely
activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL);
if ((activity < 0) && (errno!=EINTR))
{
printf("select error");
}
//If something happened on the master socket ,
//then its an incoming connection
if (FD_ISSET(master_socket, &readfds))
{
new_socket = acceptConnection(master_socket);
//add new socket to array of sockets
for (i = 0; i < max_clients; i++)
{
//if position is empty
if( client_socket[i] == 0 )
{
client_socket[i] = new_socket;
printf("Adding to list of sockets as %d\n" , i);
break;
}
}
}
//else its some IO operation on some other socket
for (i = 0; i < max_clients; i++)
{
sd = client_socket[i];
if (FD_ISSET( sd , &readfds))
{
//Check if it was for closing , and also read the
//incoming message
char buffer[kikko];
/*if ((valread = recv( sd , &buffer, kikko, 0)) >= 0)
{
printf("[RICEVUTO]\t FROM %d valread: %d\n", sd, valread);
bytes_read += valread;
int kilos = 0;
if ((kilos = bytes_read / 1024) > 0) {
kBytes_read += kilos;
bytes_read -= (kilos * 1024);
//printf("reade bites %lu", bytes_read);
}
}*/
if ((valread = recv( sd , &buffer, kikko, 0)) == 0)
{
struct sockaddr_in address;
int addrlen;
//Somebody disconnected , get his details and print
getpeername(sd , (struct sockaddr*)&address , \
(socklen_t*)&addrlen);
printf("Host disconnected , ip %s , port %d \n" ,
inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
printf("Disconnected fd %d", sd);
//Close the socket and mark as 0 in list for reuse
close( sd );
client_socket[i] = 0;
}
//Echo back the message that came in
else
{
if (valread > 0) {
//printf("[RICEVUTO]\t FROM %d\n", sd);
bytes_read += valread;
int kilos = 0;
if ((kilos = bytes_read / 1024) > 0) {
kBytes_read += kilos;
bytes_read -= (kilos * 1024);
//printf("reade bites %lu", bytes_read);
}
}
}
}
}
auto end = std::chrono::high_resolution_clock::now();
double time_taken = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
//time taken in milliseconds
time_taken *= 1e-6;
total_time_taken += time_taken;
if (total_time_taken > 3e4) {
times.push_back(total_time_taken);
sizes.push_back(kikko);
tot_received_data.push_back(kBytes_read);
break;
}
//sleep(3);
}
kikko += increment;
}
std::ofstream fout;
fout.open("select_data_stats_1000desc_NOBLOCK_TIMEOUT_HARD.csv");
//the time is in milliseconds and the data in kbytes
fout << "buffer_size;time;total_received_data;\n";
auto iter_sizes = sizes.begin();
auto iter_times = times.begin();
auto iter_data = tot_received_data.begin();
for ( ; (iter_sizes != sizes.end()) && (iter_times != times.end()) && (iter_data != tot_received_data.end()) ; (++iter_sizes, ++iter_times, ++iter_data) ) {
fout << *iter_sizes << ";" << *iter_times << ";" << *iter_data << ";\n";
}
fout.close();
return 0;
}

View File

@ -0,0 +1,56 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#define START_OF_HEADER_MARKER 0xee1234ee
typedef struct Header {
uint32_t startOfHeaderMarker = START_OF_HEADER_MARKER;
uint32_t headerSize;
uint32_t fragmentSize;
uint32_t sourceIdentifier;
uint32_t runNumber;
uint32_t detectorEventNumber;
uint32_t numberOfStatusElements;
uint32_t *statusElementsArray;
/*friend std::ostream& operator <<(std::ostream& os, Header const& header)
{
return os << std::setw(8) << std::setfill('0') << header.startOfHeaderMarker << '\n'
<< std::setw(8) << std::setfill('0') << header.headerSize << '\n'
<< std::setw(8) << std::setfill('0') << header.fragmentSize << '\n'
<< std::setw(8) << std::setfill('0') << header.runNumber << '\n'
<< std::setw(8) << std::setfill('0') << header.detectorEventNumber << '\n'
<< std::setw(8) << std::setfill('0') << header.numberOfStatusElements << '\n';
}*/
} Header;
typedef struct Fragment {
Header header;
uint32_t *payloadElements;
} Fragment;
enum ERROR_CODES {
INCORRECT_ERROR = (1 << 0),
CORRUPTED_ERROR = (1 << 1),
MISSING_DATA_ERROR = (1 << 2),
TIMEOUT_ERROR = (1 << 3)
};
void encode_header(uint32_t *buffer, const Header &header) {
buffer[0] = header.startOfHeaderMarker;
buffer[1] = header.headerSize;
buffer[2] = header.fragmentSize;
buffer[3] = header.sourceIdentifier;
buffer[4] = header.runNumber;
buffer[5] = header.detectorEventNumber;
buffer[6] = header.numberOfStatusElements;
std::memcpy(&buffer[7], header.statusElementsArray, header.numberOfStatusElements * sizeof(uint32_t));
}
void encode_fragment(uint32_t *buffer, const Fragment &fragment){
encode_header(buffer, fragment.header);
std::memcpy(&buffer[fragment.header.headerSize], fragment.payloadElements, (fragment.header.fragmentSize - fragment.header.headerSize) * sizeof(uint32_t));
}

View File

@ -0,0 +1,46 @@
# Important notes on why to use level triggered mode in this scenario
For monitoring multiple clients sending data frequently, you should generally use level-triggered mode with epoll() for simplicity and reliability.
Level-Triggered Mode: In this mode, the epoll_wait() function returns whenever there is data available to read or write on a socket, as long as the socket remains ready. You use recv() or send() to read or write the data. This mode is more suitable for handling frequent data transmission, as the socket remains in the ready state until all available data is processed.
Edge-Triggered Mode: In this mode, the epoll_wait() function returns only when the socket transitions from not ready to ready. You need to process data until EAGAIN is received, at which point you should exit the loop and re-register the socket with EPOLLONESHOT to be notified again when the socket becomes ready again. This mode requires more careful management, as you must handle the data until no more is available, and it can lead to more complex code.
Given your description of continuous data transmission causing the application to hang in edge-triggered mode, and considering your preference for handling frequent data transmission, level-triggered mode seems like the better choice. It allows you to focus on processing data without worrying about handling the edge conditions and re-registering the socket.
From a theoretical standpoint:
Edge Triggered: This mode provides more fine-grained control and can potentially be more efficient, especially in scenarios where data arrival might be infrequent and you want to be notified only when there's a change in socket readiness.
Level Triggered: This mode simplifies handling continuous data flow, as the socket remains in the ready state as long as data is available, which is often more suitable for high-frequency data streams.
Ultimately, your choice should depend on the nature of your application and how you want to manage the data flow. While edge-triggered mode can be used with careful handling, level-triggered mode is generally simpler and more straightforward for frequent data transmission scenarios.
Exactly, you've got it right! In scenarios where you need to read and buffer all available data for later processing, level-triggered mode is the better choice. It ensures that you'll be continuously notified as long as there's data available to read, allowing you to consume and buffer the data without worrying about missing any part of it.
Level-triggered mode is particularly well-suited for scenarios where you want to handle data consumption and processing at your own pace, as the socket remains in the ready state as long as data is available, ensuring that you have the opportunity to read all available data before continuing with other tasks.
So, for your specific use case of reading all the data available and buffering it for later use, level-triggered mode with epoll() is a solid choice.
Yes, your approach of using one thread for epoll-based socket monitoring and another thread for data analysis using thread-safe queues is a valid and common way to handle this kind of scenario. Here's a high-level overview of how your setup would work:
Epoll Thread: This thread will use epoll() with level-triggered mode to monitor multiple sockets for incoming data. Whenever data is available to read on a socket, the epoll thread can read the data and enqueue it into the thread-safe queue.
Data Analysis Thread: This thread will be responsible for dequeuing the buffered data from the thread-safe queue and performing the necessary analysis on it. Since the queue is thread-safe, you won't have to worry about synchronization issues between the two threads.
This separation of concerns allows you to isolate the low-level socket I/O and buffering logic from the data analysis logic, making your application more modular and maintainable.
Keep in mind a few considerations:
Concurrency: While using multiple threads can improve parallelism, it also introduces complexity. Ensure that you handle thread synchronization and communication properly to avoid race conditions or deadlocks.
Resource Management: Manage your data buffers carefully to avoid excessive memory consumption, especially if data arrives rapidly. Consider setting limits on the size of your buffers and implementing buffer recycling mechanisms if needed.
Thread Safety: Make sure the data analysis thread doesn't access or modify the same data buffers that the epoll thread is using. This is where your thread-safe queue comes in handy, as it provides a clean boundary between the two threads.
Error Handling: Implement robust error handling mechanisms to gracefully handle unexpected situations, such as socket errors or issues with the thread-safe queue.
Overall, your proposed approach seems reasonable and can be an effective way to achieve your goal of efficiently buffering data for later analysis while utilizing multi-threading for improved performance.

Binary file not shown.

View File

@ -0,0 +1,80 @@
#include <algorithm>
#include <arpa/inet.h>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <netinet/in.h>
#include <sys/socket.h>
#include <csignal>
#include <iostream>
#include <iomanip>
#include <tuple>
#include <unistd.h>
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void connectTo(int sock, const char* host, int port) {
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(host);
serv_addr.sin_port = htons(port);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to %s: %d\n", host, port);
}
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: ./prov.out timeout (ms)");
exit(EXIT_FAILURE);
}
int timeout = atoi(argv[1]);
//printf("Selected timeout: %f", static_cast<double>(timeout) / 1000);
int socket = makeSocket();
connectTo(socket, "127.0.0.1", 7777);
//allocating 100 megabytes of memory
uint64_t* chunky_boy = new uint64_t[67108];
size_t chunky_boy_size = 67108 * sizeof(uint64_t);
printf("chonky size %d", static_cast<int>(chunky_boy_size));
//setting memory to verify non-emptyness
memset(chunky_boy, 45678, chunky_boy_size);
int buffer_size = 1024 * 32;
for ( ;;) {
for ( int j = 0; j < chunky_boy_size; ) {
ssize_t bytes = send(socket, reinterpret_cast<char*>(chunky_boy) + j, std::min(static_cast<int>(chunky_boy_size) - j, buffer_size), 0);
if (timeout != 0) {
sleep(static_cast<double>(timeout) / 1000);
}
j += buffer_size;
}
}
return 0;
}

View File

@ -0,0 +1,19 @@
this test wants to see how much data is possible to gather in 60 seconds with select and epoll.
For that reason, I'm removing the random time between provider data generation and send it asap.
I'll spawn 50 clients and let them connect and send data as fast as they can while I measure total received data on server side.
I'm ignoring all bottlenecks for now. All tests of this section are brought out on my local machine.
EDIT: by default all clients allocate a massive 100 megabytes of space to send big chunks of data.
To test with a bigger number of descriptors (I'm making 100, 500, 1000) i'm lowering the chunk size as well as changing
the generation method of the data to send.
So trashing first result with 50 and re executing with all the different clien numbers.
since no big performance difference (as expected, since with all clients active also epoll has to iterate through everything since it gets notified from all),
retesting with timeout on majority of clients. files with *_TIMEOUT.csv have only 50 clients without timeout, files with *TIMEOUT_HARD.csv have only 2 clients.
The timeout is pretty hard, we're talking 1 second, to hilight the difference in performance.
With epoll we see a big rise in throughput with the 2 clients, since we kill cpu time for iteration and optimize the 30 seconds time analysis,
in the 50 clients it's not so evident. With 50 we start to see already big improvements with epoll vs select.
Now I try to multithread epoll, to see if the data acquired increases. I'll measure the full bandwith received, I expect a semi-linear increase in performance.
For the multithreading thread check the threads folder

View File

@ -0,0 +1,15 @@
#!/bin/bash
echo "Usage: $0 host port runNumber numberOfProviders"
if [ $# -eq 1 ]
then
for i in $(seq 1 $1);
do
echo "Spawning provider number $i"
if [ $i -le 2 ]
then
./prov.out 0&
else
./prov.out 1000&
fi
done
fi

Binary file not shown.

View File

@ -0,0 +1,324 @@
#include <cerrno>
#include <cstddef>
#include <cinttypes>
#include <cstdint>
#include <cstdio> // for fprintf()
#include <functional>
#include <iostream>
#include <queue>
#include <ratio>
#include <unistd.h> // for close(), read()
#include <sys/epoll.h> // for epoll_create1(), epoll_ctl(), struct epoll_event
#include <cstring> // for strncmp
//my addition to the online guide
#include <csignal>
#include <cstdlib>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <utility>
#include <vector>
#include <chrono>
#include <fstream>
#include <thread>
#include <mutex>
#include <atomic>
#include <array>
#define MAX_EVENTS 20000
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void bindSocketPort(int server_fd, int port) {
struct sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("FD %d bound to port %d\n", server_fd, port);
}
void startListening(int server_fd) {
if (listen(server_fd, 20000) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("FD %d listening to new connections\n", server_fd);
}
int acceptConnection(int server_fd) {
int client_fd;
struct sockaddr_in remoteAddr;
size_t addrlen = sizeof(remoteAddr);
if ((client_fd = accept(server_fd, (struct sockaddr *)&remoteAddr, (socklen_t *)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
} else {
int flags = fcntl(client_fd, F_GETFL);
fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
}
printf("Connection from host %s, port %d, FD %d\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port), client_fd);
return client_fd;
}
void acceptConnectionEpollStyle(int server_fd, int &efd) {
struct sockaddr_in new_remoteAddr;
int addrlen = sizeof(struct sockaddr_in);
while (true) {
int conn_sock = accept(server_fd, (struct sockaddr*)&new_remoteAddr, (socklen_t*)&addrlen);
if (conn_sock == -1) {
// All incoming connections have been processed
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
break;
} else {
perror("accept");
break;
}
}
// make new connection non-blocking
int flags = fcntl(conn_sock, F_GETFL, 0);
fcntl(conn_sock, F_SETFL, flags | O_NONBLOCK);
// monitor new connection for read events, always in edge triggered
struct epoll_event event;
event.events = EPOLLIN | EPOLLEXCLUSIVE;//| EPOLLET;
event.data.fd = conn_sock;
// Allow epoll to monitor the new connection
if (epoll_ctl(efd, EPOLL_CTL_ADD, conn_sock, &event) == -1) {
perror("epoll_ctl: conn_sock");
break;
}
printf("Accepted epoll style connection from %s:%d from fd: %d\n", inet_ntoa(new_remoteAddr.sin_addr), ntohs(new_remoteAddr.sin_port), conn_sock);
}
}
void term_handler(int signal) {
printf("Terminated, received SIGNAL %d", signal);
exit(EXIT_SUCCESS);
}
std::atomic<uint64_t> grandtotal_kb;
std::queue<std::pair<int, uint64_t>> data_queue;
std::mutex queue_mutex;
void thradizable(int &epoll_fd, int &master_socket, const int &th_flag, const int thread_index) {
epoll_event events[MAX_EVENTS];
uint64_t bytes_read = 0;
uint64_t kBytes_read = 0;
while (true) {
if (th_flag == 1) {
grandtotal_kb += kBytes_read;
break;
}
// Time measurements
///auto start = std::chrono::high_resolution_clock::now();
// Returns only the sockets for which there are events
//printf("Before wait\n");
int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
//printf("After wait\n");
if (nfds == -1) {
perror("epoll_wait");
exit(EXIT_FAILURE);
}
// Iterate on the sockets having events
for (int i = 0; i < nfds; i++) {
//printf("Tot fds = %d reading from %d\n", nfds, i);
int fd = events[i].data.fd;
if (fd == master_socket) {
// If the activity is on the master socket, than it's a new connection request
acceptConnectionEpollStyle(master_socket, epoll_fd);
} else if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
// Than the client connection is closed, so I close it
printf("Closing %d", fd);
close(fd);
} else {
uint64_t part = grandtotal_kb;
//printf("Ev trig th %d with tot b %lu\n", thread_index, part);
// Than we received data from one of the monitored sockets
uint64_t buffer[8];
int valread = 0;
//while (valread != EAGAIN) {
std::unique_lock<std::mutex> lk(queue_mutex);
valread = recv(fd, reinterpret_cast<char*>(buffer), sizeof(buffer), 0);
if (valread > 0) {
//printf("[RICEVUTO]\t FROM %d\n", fd);
int opt_incr = (valread % 8) ? 1 : 0;
for (int q_i = 0; q_i < (valread/8) + opt_incr; q_i++) {
data_queue.push(std::pair<int, uint64_t>(thread_index, buffer[q_i]));
}
grandtotal_kb += valread;
/*
bytes_read += valread;
int kilos = 0;
if ((kilos = bytes_read / 1024) > 0) {
kBytes_read += kilos;
bytes_read -= (kilos * 1024);
//printf("reade bites %lu", bytes_read);
}*/
}
lk.unlock();
//}
}
}
///auto end = std::chrono::high_resolution_clock::now();
///double time_taken = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
//time taken in milliseconds
///
/*time_taken *= 1e-6;
total_time_taken += time_taken;
if (total_time_taken > 3e4) {
times.push_back(total_time_taken);
tot_received_data.push_back(kBytes_read);
break;
}*/
///
}
}
std::vector<uint64_t> popped;
void printer_thread() {
while (1) {
std::unique_lock<std::mutex> lk(queue_mutex);
if (!data_queue.empty()) {
std::pair<int, uint64_t> element = data_queue.front();
data_queue.pop();
popped.push_back(element.second);
//printf("Element: %lu from thread %d\n", element.second, element.first);
if (element.second == 999) {
int fail_flag = 0;
for (int i = 1; i < 999; i++) {
if (popped[i] == i) continue;
else fail_flag = 1;
}
if (fail_flag == 1) printf("FAILURE\n");
else printf("success\n");
}
}
lk.unlock();
usleep(10);
}
}
int main(int argc, char const *argv[]) {
signal(SIGTERM, term_handler);
if (argc != 2) {
printf("Usage: %s portNumber \n", argv[0]);
exit(EXIT_FAILURE);
}
int port = atoi(argv[1]);
printf("Start socket port %d\n", port);
int master_socket;
const int opt = 1;
master_socket = makeSocket();
//set master socket to allow multiple connections ,
//this is just a good habit, it will work without this
if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
sizeof(opt)) < 0 )
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
bindSocketPort(master_socket, port);
startListening(master_socket);
int flags = fcntl(master_socket, F_GETFL, 0);
fcntl(master_socket, F_SETFL, flags | O_NONBLOCK);
epoll_event ev, events[MAX_EVENTS];
std::array<uint64_t, MAX_EVENTS> kBytes_read_on_descr;
//The atomic here is used as a flag to tell the thread to stop
std::vector<std::thread> vThreads;
//create the epoll instance
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
printf("Failed to create epoll file descriptor\n");
exit(EXIT_FAILURE);
}
ev.data.fd = master_socket;
// Reading events with edge triggered mode
ev.events = EPOLLIN | EPOLLEXCLUSIVE;//| EPOLLET;
// Allowing epoll to monitor the master_socket
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, master_socket, &ev) == -1){
perror("epoll_ctl");
exit(EXIT_FAILURE);
}
std::array<std::thread, 2> vT;
std::array<int, 2> thread_flags;
for (int t_i = 0; t_i < 2; t_i++) {
thread_flags[t_i] = 0;
vT[t_i] = std::thread(thradizable, std::ref(epoll_fd), std::ref(master_socket), std::cref(thread_flags.at(t_i)), t_i);
}
std::thread printer(printer_thread);
printer.join();
if (close(epoll_fd)) {
printf("Failed to close epoll file descriptor");
exit(EXIT_FAILURE);
}
return 0;
}

View File

@ -0,0 +1,13 @@
#!/bin/bash
for i in $(seq 1 1000);
do
echo "exec $i" >> res.txt
./ev_builder.out 7777 >> res.txt &
sleep 1
./prov.out &
sleep 3
kill -15 `pidof ./ev_builder.out`
kill -15 `pidof ./prov.out`
sleep 1
done

Binary file not shown.

View File

@ -0,0 +1,62 @@
#include <algorithm>
#include <arpa/inet.h>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <netinet/in.h>
#include <sys/socket.h>
#include <csignal>
#include <iostream>
#include <iomanip>
#include <tuple>
#include <unistd.h>
#define BIGDIM 10000
int makeSocket() {
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void connectTo(int sock, const char* host, int port) {
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(host);
serv_addr.sin_port = htons(port);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to %s: %d\n", host, port);
}
int main(int argc, char* argv[]) {
int socket = makeSocket();
connectTo(socket, "127.0.0.1", 7777);
uint64_t alotofvalues[BIGDIM];
for (int i = 1; i < BIGDIM; i++) {
alotofvalues[i] = i;
}
int send_counter = 0;
for (;;) {
alotofvalues[0] = send_counter;
ssize_t bytes = send(socket, reinterpret_cast<char*>(alotofvalues), sizeof(alotofvalues), 0);
sleep(10000);
send_counter++;
}
return 0;
}

View File

@ -0,0 +1,8 @@
# Is epoll really thread safe?
### 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).
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.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,20 @@
#include <ostream>
#include <queue>
#include <array>
#include <iostream>
int main() {
std::queue<int> queue;
std::array<int, 4> range = {1,2,3,4};
queue.push_range(range);
while (!queue.empty()) {
std::cout << queue.front() << std::endl;
queue.pop();
}
return 0;
}

View File

@ -0,0 +1,25 @@
#include <ostream>
#include <queue>
#include <array>
#include <iostream>
int main() {
std::array<std::queue<int>, 3> arr_queues;
for (int j = 0; j < 5; j++) {
for (int i = 0; i < 3; i++) {
arr_queues[i].push(i+j+10);
}
}
for (int j = 0; j < 5; j++) {
for (int i = 0; i < 3; i++) {
std::cout << "Queue numebr " << i << " " << arr_queues[i].front() << std::endl;
arr_queues[i].pop();
}
}
return 0;
}

View File

@ -0,0 +1,54 @@
void BrokenAxis()
{
TCanvas *c = new TCanvas("c", "c",700,900);
TPad *p1 = new TPad("p1","p1",0.1,0.5,0.9,0.901);
p1->SetBottomMargin(0.);
p1->SetFillColor(0);
p1->SetBorderMode(0);
p1->SetLogy();
p1->Draw();
TPad *p2 = new TPad("p2","p2",0.1,0.1,0.9,0.501);
p2->SetTopMargin(0.);
p2->SetFillColor(0);
p2->SetBorderMode(0);
p2->Draw();
float x1[] = {3,5,6,9}; float y1[] = {100,900,400,200};
TGraph *gr1 = new TGraph(4,x1,y1);
gr1->GetXaxis()->SetLimits(0.,10.);
gr1->SetTitle("");
gr1->GetXaxis()->SetLabelSize(0);
gr1->GetXaxis()->SetTickLength(0);
gr1->SetMarkerStyle(20);
float x2[] = {1,2,3,8}; float y2[] = {4,7,6,5};
TGraph *gr2 = new TGraph(4,x2,y2);
gr2->GetXaxis()->SetLimits(0.,10.);
gr2->SetTitle("");
gr2->SetMarkerStyle(22);
p1->cd();
gr1->Draw("ALP");
gr1->GetHistogram()->SetMinimum(-20.);
p2->cd();
gr2->Draw("ALP");
gr2->GetHistogram()->SetMaximum(7.5);
c->cd();
TPad *b = new TPad("b","b",0.1,0.46,0.8199,0.53);
b->SetBorderMode(0);
b->SetFillColor(0);
b->Draw();
b->cd();
TLine *line = new TLine(0.11,0,0.1105677,0.399656);
line->Draw();
line = new TLine(0.1105677,0.5860092,0.11,1);
line->Draw();
line = new TLine(0.076639,0.5143349,0.1524797,0.6863532);
line->Draw();
line = new TLine(0.076639,0.3423165,0.1524797,0.5143349);
line->Draw();
}

View File

@ -0,0 +1,62 @@
void ConnMethodComparison() {
gROOT->SetBatch(kTRUE);
auto sel_filename = "./select_data_stats_1000desc_NOBLOCK_TIMEOUT_HARD.csv";
auto sel_df = ROOT::RDF::MakeCsvDataFrame(sel_filename, true, ';');
auto sel_nc = sel_df.Define("bandwidth", "( total_received_data/static_cast<double>(1024) ) / (time/1000)").Define("bf_kb", "buffer_size/static_cast<double>(1024)");
auto epoll_filename = "./epoll_data_stats_1000_TIMEOUT_HARD.csv";
auto epoll_df = ROOT::RDF::MakeCsvDataFrame(epoll_filename, true, ';');
auto epoll_nc = epoll_df.Define("bandwidth", "( total_received_data/static_cast<double>(1024) ) / (time/1000)").Define("bf_kb", "buffer_size/static_cast<double>(1024)");
auto canvas = new TCanvas("c", "c", 1400, 1000);
//canvas->SetLogx();
canvas->SetGrid();
//canvas->SetLogy();
auto sel_g = sel_nc.Graph("bf_kb", "bandwidth");
sel_g->SetTitle("Select vs Epoll: 1000 clients (99.8% long timeouts);Buffer Size [kB];Bandwidth [kB/s]");
sel_g->SetName("sel");
sel_g->SetMarkerStyle(55);
sel_g->SetMarkerSize(2);
sel_g->SetMarkerColor(kBlue);
sel_g->SetLineColor(kBlue);
sel_g->SetLineWidth(2);
//sel_g->GetXaxis()->SetLimits(-50,1000);
sel_g->GetHistogram()->SetMinimum(0);
sel_g->GetHistogram()->SetMaximum(7000);
sel_g->DrawClone("ALP");
auto epoll_g = epoll_nc.Graph("bf_kb", "bandwidth");
epoll_g->SetTitle("Select vs Epoll: 1000 clients (99.8% long timeouts);Buffer Size [kB];Bandwidth [kB/s]");
epoll_g->SetName("epoll");
epoll_g->SetMarkerStyle(55);
epoll_g->SetMarkerSize(2);
epoll_g->SetMarkerColor(kRed);
epoll_g->SetLineColor(kRed);
epoll_g->SetLineWidth(2);
//epoll_g->GetXaxis()->SetLimits(-50,1000);
//epoll_g->GetHistogram()->SetMinimum(1e3);
//epoll_g->GetHistogram()->SetMaximum(1e7);
epoll_g->DrawClone("LP");
//gStyle->SetLegendTextSize(0.01);
auto leg = new TLegend(0.60,0.42,0.86,0.57);
leg->SetHeader("Connection method", "c");
leg->AddEntry("sel","Select","lp");
leg->AddEntry("epoll","Epoll","lp");
leg->Draw();
//canvas->BuildLegend(0.65,0.2,0.86,0.32, "Connection Method");
canvas->Print("Epoll_Select_1000_TIMEOUT_HARD.png");
gROOT->SetBatch(kFALSE);
gApplication->Terminate(0);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,62 @@
void MultiThComp() {
gROOT->SetBatch(kTRUE);
auto epoll_filename = "./epoll_data_stats_1000_TIMEOUT_HARD.csv";
auto epoll_df = ROOT::RDF::MakeCsvDataFrame(epoll_filename, true, ';');
auto epoll_nc = epoll_df.Define("bandwidth", "( total_received_data/static_cast<double>(1024) ) / (time/1000)").Define("bf_kb", "buffer_size/static_cast<double>(1024)");
auto epoll_multi_filename = "./epoll_data_stats_1000_multith_TIMEOUT_HARD.csv";
auto epoll_multi_df = ROOT::RDF::MakeCsvDataFrame(epoll_multi_filename, true, ';');
auto epoll_multi_nc = epoll_multi_df.Define("bandwidth", "( total_received_data/static_cast<double>(1024) ) / (time/1000)").Define("bf_kb", "buffer_size/static_cast<double>(1024)");
auto canvas = new TCanvas("c", "c", 1400, 1000);
//canvas->SetLogx();
canvas->SetGrid();
//canvas->SetLogy();
auto epoll_g = epoll_nc.Graph("bf_kb", "bandwidth");
epoll_g->SetTitle("Epoll vs Epoll Multithread (99.8% long timeouts): 1000 clients;Buffer Size [kB];Bandwidth [kB/s]");
epoll_g->SetName("epoll");
epoll_g->SetMarkerStyle(55);
epoll_g->SetMarkerSize(2);
epoll_g->SetMarkerColor(kBlue);
epoll_g->SetLineColor(kBlue);
epoll_g->SetLineWidth(2);
//epoll_g->GetXaxis()->SetLimits(-50,1000);
epoll_g->GetHistogram()->SetMinimum(0);
epoll_g->GetHistogram()->SetMaximum(7000);
epoll_g->DrawClone("ALP");
auto epoll_multi_g = epoll_multi_nc.Graph("bf_kb", "bandwidth");
epoll_multi_g->SetTitle("Epoll vs Epoll Multithread (99.8% long timeouts): 1000 clients;Buffer Size [kB];Bandwidth [kB/s]");
epoll_multi_g->SetName("epoll_multi");
epoll_multi_g->SetMarkerStyle(55);
epoll_multi_g->SetMarkerSize(2);
epoll_multi_g->SetMarkerColor(8);
epoll_multi_g->SetLineColor(8);
epoll_multi_g->SetLineWidth(2);
//epoll_multi_g->GetXaxis()->SetLimits(-50,1000);
//epoll_multi_g->GetHistogram()->SetMinimum(1e3);
//epoll_multi_g->GetHistogram()->SetMaximum(1e7);
epoll_multi_g->DrawClone("LP");
//gStyle->SetLegendTextSize(0.01);
auto leg = new TLegend(0.60,0.17,0.86,0.32);
leg->SetHeader("Connection method", "c");
leg->AddEntry("epoll","Epoll Single Thread","lp");
leg->AddEntry("epoll_multi","Epoll 6 Threads","lp");
leg->Draw();
//canvas->BuildLegend(0.65,0.2,0.86,0.32, "Connection Method");
canvas->Print("Epoll_Multi_1000_TIMEOUT_HARD.png");
gROOT->SetBatch(kFALSE);
gApplication->Terminate(0);
}

View File

@ -0,0 +1,34 @@
void SendBuf() {
gROOT->SetBatch(kTRUE);
auto filename = "./send_data_buffer.csv";
auto df = ROOT::RDF::MakeCsvDataFrame(filename, true, ';');
auto newcol = df.Define("bandwidth", "100*1024/time").Define("bf_kb", "buffer_size/static_cast<double>(1024)");
auto canvas = new TCanvas("c", "c", 1400, 1000);
//canvas->SetLogx();
canvas->SetGrid();
canvas->SetLogy();
auto g = newcol.Graph("bf_kb", "bandwidth");
g->SetTitle("Bandwidth vs Sender Buffer Size;Buffer Size [kB];Bandwidth [kB/s]");
// Make the plot esthetically better
//It's kMultiply a lil bigger
g->SetMarkerStyle(52);
g->SetMarkerSize(1.5);
g->SetMarkerColor(kBlack);
g->SetLineColor(kBlue);
g->GetXaxis()->SetLimits(-50,1000);
g->GetHistogram()->SetMinimum(1e3);
g->GetHistogram()->SetMaximum(1e7);
g->DrawClone("ALP");
canvas->Print("SendBufferSize.png");
gROOT->SetBatch(kFALSE);
gApplication->Terminate(0);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1,81 @@
void SenderBufSize() {
auto filename = "./send_data_buffer.csv";
auto df = ROOT::RDF::MakeCsvDataFrame(filename, true, ';');
auto newcol = df.Define("bandwidth", "100*1024/time").Define("bf_kb", "buffer_size/static_cast<double>(1024)");
//TPad (const char *name, const char *title, Double_t xlow, Double_t ylow, Double_t xup, Double_t yup, Color_t color=-1, Short_t bordersize=-1, Short_t bordermode=-2)
auto canvas = new TCanvas();
//canvas->SetLogx();
//canvas->SetLogy();
auto graph1 = newcol.Graph("bf_kb", "bandwidth");
auto graph2 = newcol.Graph("bf_kb", "bandwidth");
//graph1->SetTitle("Bandwidth vs Sender Buffer Size;Buffer Size [kB];Bandwidth [kB/s]");
graph2->SetTitle("Bandwidth vs Sender Buffer Size;Buffer Size [kB];Bandwidth [kB/s]");
graph1->SetTitle("");
//graph2->SetTitle("");
graph1->GetXaxis()->SetLimits(0,0.7);
graph2->GetXaxis()->SetLimits(0.7,1e3);
graph1->GetYaxis()->SetLimits(0,1e6);
graph2->GetYaxis()->SetLimits(0,1e6);
//auto printable = newcol.Display();
//printable->Print();
// Make the plot esthetically better
//It's kMultiply a lil bigger
//graph1->GetYaxis()->SetLabelSize(0);
//graph1->GetYaxis()->SetTickLength(0);
graph1->GetXaxis()->SetNdivisions(0);
graph1->SetMarkerStyle(52);
graph1->SetMarkerSize(1.5);
graph1->SetMarkerColor(kBlack);
graph1->SetLineColor(kBlue);
//graph2->GetYaxis()->SetLabelSize(0);
//graph2->GetYaxis()->SetTickLength(0);
graph2->SetMarkerStyle(52);
graph2->SetMarkerSize(1.5);
graph2->SetMarkerColor(kBlack);
graph2->SetLineColor(kBlue);
auto pad1 = new TPad("p1","p1",0.05,0.05,0.2,0.95);
pad1->SetRightMargin(0.);
pad1->SetFillColor(0);
pad1->SetBorderMode(0);
pad1->SetLogy();
pad1->Draw();
auto pad2 = new TPad("p2","p2",0.205,0.05,0.95,0.95);
pad2->SetLeftMargin(0.);
pad2->SetFillColor(0);
pad2->SetBorderMode(0);
pad2->SetLogx();
pad2->SetLogy();
pad2->Draw();
pad1->cd();
graph1->DrawClone("ALP");
pad2->cd();
graph2->DrawClone("ALP");
canvas->Modified();
canvas->Update();
//graph->DrawClone("ALP");
//gApplication->Terminate(0);
}

View File

@ -0,0 +1,40 @@
void Try() {
// Define your data
std::vector<double> times = {1, 1.2, 1.5, 1.7, 2.1, 2.2, 2.9};
std::vector<double> values = {5, 6, 7, 8, 9, 10, 11};
// Define your bin edges
std::vector<double> binEdges = {1, 2, 3}; // Define your desired bin edges here
// Create a histogram with custom binning
TH1F *hist = new TH1F("custom_hist", "Custom Histogram", binEdges.size() - 1, &binEdges[0]);
// Initialize vectors to store bin contents and counts
std::vector<double> binContents(binEdges.size() - 1, 0.0);
std::vector<int> binCounts(binEdges.size() - 1, 0);
// Loop through data and fill the histogram
for (size_t i = 0; i < times.size(); ++i) {
double val = values[i];
for (size_t j = 0; j < binEdges.size() - 1; ++j) {
if (times[i] >= binEdges[j] && times[i] < binEdges[j + 1]) {
binContents[j] += val;
binCounts[j]++;
break;
}
}
}
// Calculate the means for each bin and set the bin content
for (size_t i = 0; i < binEdges.size() - 1; ++i) {
double binMean = (binCounts[i] > 0) ? binContents[i] / binCounts[i] : 0;
hist->SetBinContent(i + 1, binMean); // Set the bin content to the mean
}
// Create a canvas and draw the histogram
TCanvas *canvas = new TCanvas("canvas", "Custom Histogram", 800, 600);
hist->Draw();
canvas->SaveAs("custom_histogram.png");
delete canvas;
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,19 @@
buffer_size;time;total_received_data;
1;30000;45817;
500;30000;16688512;
1000;30000;26801219;
2000;30004.1;40979357;
3000;30000.2;49705756;
4000;30000.1;56029482;
5000;30000.1;60047108;
10000;30000.2;99444868;
20000;30000.2;106228515;
30000;30000.6;103007812;
40000;30000.5;112140625;
50000;30000.8;104677734;
100000;30002.8;119785156;
200000;30001.2;117539062;
300000;30002.7;127939453;
400000;30010.1;121523437;
500000;30004.6;125390625;
1 buffer_size time total_received_data
2 1 30000 45817
3 500 30000 16688512
4 1000 30000 26801219
5 2000 30004.1 40979357
6 3000 30000.2 49705756
7 4000 30000.1 56029482
8 5000 30000.1 60047108
9 10000 30000.2 99444868
10 20000 30000.2 106228515
11 30000 30000.6 103007812
12 40000 30000.5 112140625
13 50000 30000.8 104677734
14 100000 30002.8 119785156
15 200000 30001.2 117539062
16 300000 30002.7 127939453
17 400000 30010.1 121523437
18 500000 30004.6 125390625

View File

@ -0,0 +1,18 @@
buffer_size;time;total_received_data;
1;30000.5;26535;
500;30000.9;12931772;
1000;30000.8;20953270;
2000;30000.7;30575921;
3000;30000.2;37463270;
4000;30003.3;42943248;
5000;30000.4;47972201;
10000;30003.9;57650021;
20000;30001.7;70555676;
30000;30006.6;66315379;
40000;30000.8;64524353;
50000;30006.4;80692139;
100000;30008.4;93501600;
200000;30002.2;103220112;
300000;30010;108385843;
400000;30002.3;110109484;
500000;30041.3;106363740;
1 buffer_size time total_received_data
2 1 30000.5 26535
3 500 30000.9 12931772
4 1000 30000.8 20953270
5 2000 30000.7 30575921
6 3000 30000.2 37463270
7 4000 30003.3 42943248
8 5000 30000.4 47972201
9 10000 30003.9 57650021
10 20000 30001.7 70555676
11 30000 30006.6 66315379
12 40000 30000.8 64524353
13 50000 30006.4 80692139
14 100000 30008.4 93501600
15 200000 30002.2 103220112
16 300000 30010 108385843
17 400000 30002.3 110109484
18 500000 30041.3 106363740

View File

@ -0,0 +1,19 @@
buffer_size;time;total_received_data;
1;30001.7;23972;
500;30001.1;16452118;
1000;30000;28659540;
2000;30000;43843616;
3000;30000;53965134;
4000;30000;78146535;
5000;30000;81098297;
10000;30000.1;104959571;
20000;30000;103154410;
30000;30000.1;98912274;
40000;30000.2;106528334;
50000;30000;108412018;
100000;30000.1;99869795;
200000;30001.9;113863135;
300000;30006.9;113726256;
400000;30003.6;113588963;
500000;30004.1;124238792;
1 buffer_size time total_received_data
2 1 30001.7 23972
3 500 30001.1 16452118
4 1000 30000 28659540
5 2000 30000 43843616
6 3000 30000 53965134
7 4000 30000 78146535
8 5000 30000 81098297
9 10000 30000.1 104959571
10 20000 30000 103154410
11 30000 30000.1 98912274
12 40000 30000.2 106528334
13 50000 30000 108412018
14 100000 30000.1 99869795
15 200000 30001.9 113863135
16 300000 30006.9 113726256
17 400000 30003.6 113588963
18 500000 30004.1 124238792

View File

@ -0,0 +1,18 @@
buffer_size;time;total_received_data;
1;30000.7;32735;
500;30000;18563821;
1000;30000;33321199;
2000;30000;57600348;
3000;30000;72226712;
4000;30000;80548950;
5000;30000;92428421;
10000;30000;125112074;
20000;30000;130615660;
30000;30000;133488130;
40000;30000;149347337;
50000;30000;141748519;
100000;30000;145676700;
200000;30000.1;167065891;
300000;30000.1;180569049;
400000;30000;186854294;
500000;30000;191359610;
1 buffer_size time total_received_data
2 1 30000.7 32735
3 500 30000 18563821
4 1000 30000 33321199
5 2000 30000 57600348
6 3000 30000 72226712
7 4000 30000 80548950
8 5000 30000 92428421
9 10000 30000 125112074
10 20000 30000 130615660
11 30000 30000 133488130
12 40000 30000 149347337
13 50000 30000 141748519
14 100000 30000 145676700
15 200000 30000.1 167065891
16 300000 30000.1 180569049
17 400000 30000 186854294
18 500000 30000 191359610

View File

@ -0,0 +1,19 @@
buffer_size;time;total_received_data;
1;30001.8;121453;
500;30001.8;38315920;
1000;30013.8;60329152;
2000;30005.2;74660074;
3000;30005.9;85193274;
4000;30006.5;96597573;
5000;30008.5;106440822;
10000;30011.8;137147617;
20000;30007.9;176761989;
30000;30006.4;156482849;
40000;30014;177159351;
50000;30049.3;171875036;
100000;30053.9;224264206;
200000;30048.3;225628771;
300000;30121;180069213;
400000;30016.7;156804334;
500000;30000.6;230636978;
1 buffer_size time total_received_data
2 1 30001.8 121453
3 500 30001.8 38315920
4 1000 30013.8 60329152
5 2000 30005.2 74660074
6 3000 30005.9 85193274
7 4000 30006.5 96597573
8 5000 30008.5 106440822
9 10000 30011.8 137147617
10 20000 30007.9 176761989
11 30000 30006.4 156482849
12 40000 30014 177159351
13 50000 30049.3 171875036
14 100000 30053.9 224264206
15 200000 30048.3 225628771
16 300000 30121 180069213
17 400000 30016.7 156804334
18 500000 30000.6 230636978

View File

@ -0,0 +1,18 @@
buffer_size;time;total_received_data;
1;30002.1;140629;
500;30003.8;31440572;
1000;30004.1;48545615;
2000;30010.9;65841163;
3000;30011.9;79191486;
4000;30008.6;83061533;
5000;30011.5;82064998;
10000;30005.2;96952555;
20000;30007;132912119;
30000;30005.2;138298731;
40000;30017.7;138156188;
50000;30017.2;139215949;
100000;30051.2;139854062;
200000;30008.9;146022695;
300000;30061.5;142890809;
400000;30083.1;138006324;
500000;30074.4;133424935;
1 buffer_size time total_received_data
2 1 30002.1 140629
3 500 30003.8 31440572
4 1000 30004.1 48545615
5 2000 30010.9 65841163
6 3000 30011.9 79191486
7 4000 30008.6 83061533
8 5000 30011.5 82064998
9 10000 30005.2 96952555
10 20000 30007 132912119
11 30000 30005.2 138298731
12 40000 30017.7 138156188
13 50000 30017.2 139215949
14 100000 30051.2 139854062
15 200000 30008.9 146022695
16 300000 30061.5 142890809
17 400000 30083.1 138006324
18 500000 30074.4 133424935

View File

@ -0,0 +1,18 @@
buffer_size;time;total_received_data;
1;30002.1;163986;
500;30019;34088098;
1000;30005.1;50801994;
2000;30006.2;69301651;
3000;30005.4;80399265;
4000;30012.7;90123946;
5000;30010.8;98647263;
10000;30011.7;116325174;
20000;30049.7;134726431;
30000;30025;144562322;
40000;30028.7;147823821;
50000;30012.3;146218628;
100000;30069.2;151376815;
200000;30011.5;138831476;
300000;30022.2;145632228;
400000;30096.8;146447339;
500000;30143.2;134063359;
1 buffer_size time total_received_data
2 1 30002.1 163986
3 500 30019 34088098
4 1000 30005.1 50801994
5 2000 30006.2 69301651
6 3000 30005.4 80399265
7 4000 30012.7 90123946
8 5000 30010.8 98647263
9 10000 30011.7 116325174
10 20000 30049.7 134726431
11 30000 30025 144562322
12 40000 30028.7 147823821
13 50000 30012.3 146218628
14 100000 30069.2 151376815
15 200000 30011.5 138831476
16 300000 30022.2 145632228
17 400000 30096.8 146447339
18 500000 30143.2 134063359

View File

@ -0,0 +1,18 @@
buffer_size;time;total_received_data;
1;30000.3;38239;
500;30000.3;15008694;
1000;30000.5;24572299;
2000;30000.1;34510344;
3000;30001;41199235;
4000;30000.9;45359880;
5000;30000.5;48985625;
10000;30003.5;59779061;
20000;30003.2;66210747;
30000;30000.4;70755300;
40000;30002.9;91266308;
50000;30005.9;112726855;
100000;30002;120034453;
200000;30004.6;120310170;
300000;30011.9;110168294;
400000;30017;103690777;
500000;30023.6;106875799;
1 buffer_size time total_received_data
2 1 30000.3 38239
3 500 30000.3 15008694
4 1000 30000.5 24572299
5 2000 30000.1 34510344
6 3000 30001 41199235
7 4000 30000.9 45359880
8 5000 30000.5 48985625
9 10000 30003.5 59779061
10 20000 30003.2 66210747
11 30000 30000.4 70755300
12 40000 30002.9 91266308
13 50000 30005.9 112726855
14 100000 30002 120034453
15 200000 30004.6 120310170
16 300000 30011.9 110168294
17 400000 30017 103690777
18 500000 30023.6 106875799

View File

@ -0,0 +1,19 @@
buffer_size;time;total_received_data;
500;30000;923066;
500;30000;1246851;
500;30000;1224399;
500;30000;1236942;
500;30000;1237006;
500;30000;1240083;
500;30000;1243543;
500;30000;1247446;
500;30000;1249498;
500;30000;1242588;
500;30000;1246731;
500;30000;1249731;
500;30000;1245551;
500;30000;1251264;
500;30000;1257202;
500;30000;1253106;
500;30000;1250601;
500;30000;1249947;
1 buffer_size time total_received_data
2 500 30000 923066
3 500 30000 1246851
4 500 30000 1224399
5 500 30000 1236942
6 500 30000 1237006
7 500 30000 1240083
8 500 30000 1243543
9 500 30000 1247446
10 500 30000 1249498
11 500 30000 1242588
12 500 30000 1246731
13 500 30000 1249731
14 500 30000 1245551
15 500 30000 1251264
16 500 30000 1257202
17 500 30000 1253106
18 500 30000 1250601
19 500 30000 1249947

Some files were not shown because too many files have changed in this diff Show More