Compare commits
No commits in common. "dev" and "main" have entirely different histories.
|
@ -1,141 +0,0 @@
|
|||
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);
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#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
|
@ -1,114 +0,0 @@
|
|||
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
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 30 KiB |
BIN
Nodelay.png
Before Width: | Height: | Size: 64 KiB |
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": ".."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
144
QueueOccup.C
|
@ -1,144 +0,0 @@
|
|||
#include <vector>
|
||||
|
||||
void constHisto(std::vector<double> ×, 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);
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
# 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.
|
|
@ -1,114 +0,0 @@
|
|||
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);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#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) {
|
||||
}
|
||||
};
|
Before Width: | Height: | Size: 57 KiB |
|
@ -1,44 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#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;
|
||||
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": ".."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
# 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
BIN
backup/core
|
@ -1,244 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#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
|
@ -1,5 +0,0 @@
|
|||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#!/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
evBuild.out
|
@ -1,466 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
#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]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
#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,8 +0,0 @@
|
|||
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,9 +0,0 @@
|
|||
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,9 +0,0 @@
|
|||
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,9 +0,0 @@
|
|||
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,9 +0,0 @@
|
|||
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,9 +0,0 @@
|
|||
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,9 +0,0 @@
|
|||
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;
|
|
172
provider.cxx
|
@ -1,172 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,695 +0,0 @@
|
|||
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,17 +0,0 @@
|
|||
#!/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
|
|
@ -1,12 +0,0 @@
|
|||
#!/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
|
|
@ -1,105 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,283 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,301 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
#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));
|
||||
}
|
||||
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
# 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.
|
||||
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
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
|
|
@ -1,15 +0,0 @@
|
|||
#!/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
|
|
@ -1,324 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#!/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
|
|
@ -1,62 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
# 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.
|
|
@ -1,20 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
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();
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
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);
|
||||
}
|
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 37 KiB |
|
@ -1,62 +0,0 @@
|
|||
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);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
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);
|
||||
}
|
Before Width: | Height: | Size: 31 KiB |
|
@ -1,81 +0,0 @@
|
|||
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);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
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;
|
||||
}
|
Before Width: | Height: | Size: 23 KiB |
|
@ -1,19 +0,0 @@
|
|||
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,18 +0,0 @@
|
|||
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,19 +0,0 @@
|
|||
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,18 +0,0 @@
|
|||
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,19 +0,0 @@
|
|||
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,18 +0,0 @@
|
|||
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,18 +0,0 @@
|
|||
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,18 +0,0 @@
|
|||
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,19 +0,0 @@
|
|||
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;
|
|