1
0

Add mechanism to measure when broadcast finished execution

This commit is contained in:
Athanasios Xygkis
2020-09-21 11:57:49 +02:00
committed by Thanasis Xigis
parent da6d2f3e6f
commit 21124b2613
4 changed files with 237 additions and 29 deletions

View File

@@ -1,32 +1,90 @@
#pragma once
#include "parser.hpp"
void waitOnBarrier(Parser::Host const &barrier);
#include <endian.h>
#include <algorithm>
void waitOnBarrier(Parser::Host const &barrier) {
struct sockaddr_in server;
std::memset(&server, 0, sizeof(server));
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
throw std::runtime_error("Could not create the barrier socket: " +
std::string(std::strerror(errno)));
class Coordinator {
public:
Coordinator(unsigned long id, Parser::Host barrier, Parser::Host signal)
: id_{id}, barrier_{barrier}, signal_{signal}
{
signalFd_ = connectToHost(signal_, "signal");
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = barrier.ip;
server.sin_port = barrier.port;
if (connect(fd, reinterpret_cast<struct sockaddr *>(&server),
sizeof(server)) < 0) {
throw std::runtime_error("Could not connect to the barrier: " +
std::string(std::strerror(errno)));
void waitOnBarrier() {
int fd = connectToHost(barrier_, "barrier");
char dummy;
if (recv(fd, &dummy, sizeof(dummy), 0) < 0) {
throw std::runtime_error("Could not read from the barrier socket: " +
std::string(std::strerror(errno)));
}
close(fd);
}
char dummy;
if (recv(fd, &dummy, sizeof(dummy), 0) < 0) {
throw std::runtime_error("Could not read from the barrier socket: " +
std::string(std::strerror(errno)));
void finishedBroadcasting() {
close(signalFd_);
}
close(fd);
}
private:
int connectToHost(Parser::Host const &host, std::string const &reason) {
struct sockaddr_in server;
std::memset(&server, 0, sizeof(server));
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
throw std::runtime_error("Could not create the " + reason + " socket: " +
std::string(std::strerror(errno)));
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = host.ip;
server.sin_port = host.port;
if (connect(fd, reinterpret_cast<struct sockaddr *>(&server),
sizeof(server)) < 0) {
throw std::runtime_error("Could not connect to the " + reason + ": " +
std::string(std::strerror(errno)));
}
auto id = htonT(static_cast<uint64_t>(id_));
if (writeWithRetry(fd, reinterpret_cast<uint8_t *>(&id), sizeof(id))) {
throw std::runtime_error("Could not send my LogicalPID to the " + reason + ": " +
std::string(std::strerror(errno)));
}
return fd;
}
// From https://stackoverflow.com/questions/32683086/handling-incomplete-write-calls
ssize_t writeWithRetry (int fd, uint8_t const* buf, size_t size) {
ssize_t ret;
while (size > 0) {
do
{
ret = write(fd, buf, size);
} while ((ret < 0) && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
if (ret < 0)
return ret;
size -= ret;
buf += ret;
}
return 0;
}
template <typename T>
constexpr T htonT (T value) noexcept
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
char* ptr = reinterpret_cast<char*>(&value);
std::reverse(ptr, ptr + sizeof(T));
#endif
return value;
}
private:
unsigned long id_;
Parser::Host barrier_;
Parser::Host signal_;
int signalFd_;
};

View File

@@ -118,6 +118,11 @@ public:
return barrier_;
}
Host signal() const {
checkParsed();
return signal_;
}
const char *outputPath() const {
checkParsed();
return outputPath_.c_str();
@@ -204,6 +209,10 @@ private:
return false;
}
if (!parseSignal()) {
return false;
}
if (!parseOutputPath()) {
return false;
}
@@ -218,7 +227,7 @@ private:
void help(const int, char const *const *argv) {
auto configStr = "CONFIG";
std::cerr << "Usage: " << argv[0]
<< " --id ID --hosts HOSTS --barrier NAME:PORT --output OUTPUT";
<< " --id ID --hosts HOSTS --barrier NAME:PORT --signal NAME:PORT --output OUTPUT";
if (!withConfig) {
std::cerr << "\n";
@@ -287,13 +296,36 @@ private:
return false;
}
bool parseOutputPath() {
bool parseSignal() {
if (argc < 9) {
return false;
}
if (std::strcmp(argv[7], "--output") == 0) {
outputPath_ = std::string(argv[8]);
if (std::strcmp(argv[7], "--signal") == 0) {
std::string signal_addr = argv[8];
std::replace(signal_addr.begin(), signal_addr.end(), ':', ' ');
std::stringstream ss(signal_addr);
std::string signal_name;
unsigned short signal_port;
ss >> signal_name;
ss >> signal_port;
signal_ = Host(0, signal_name, signal_port);
return true;
}
return false;
}
bool parseOutputPath() {
if (argc < 11) {
return false;
}
if (std::strcmp(argv[9], "--output") == 0) {
outputPath_ = std::string(argv[10]);
return true;
}
@@ -305,11 +337,11 @@ private:
return true;
}
if (argc < 10) {
if (argc < 12) {
return false;
}
configPath_ = std::string(argv[9]);
configPath_ = std::string(argv[11]);
return true;
}
@@ -352,6 +384,7 @@ private:
unsigned long id_;
std::string hostsPath_;
Host barrier_;
Host signal_;
std::string outputPath_;
std::string configPath_;
};

View File

@@ -69,6 +69,15 @@ int main(int argc, char **argv) {
std::cout << "Machine-readbale Port: " << barrier.port << "\n";
std::cout << "\n";
std::cout << "Signal:\n";
std::cout << "========\n";
auto signal = parser.signal();
std::cout << "Human-readable IP: " << signal.ipReadable() << "\n";
std::cout << "Machine-readable IP: " << signal.ip << "\n";
std::cout << "Human-readbale Port: " << signal.portReadable() << "\n";
std::cout << "Machine-readbale Port: " << signal.port << "\n";
std::cout << "\n";
std::cout << "Path to output:\n";
std::cout << "===============\n";
std::cout << parser.outputPath() << "\n\n";
@@ -81,11 +90,17 @@ int main(int argc, char **argv) {
std::cout << "Doing some initialization...\n\n";
Coordinator coordinator(parser.id(), barrier, signal);
std::cout << "Waiting for all processes to finish initialization\n\n";
waitOnBarrier(barrier);
coordinator.waitOnBarrier();
std::cout << "Broadcasting messages...\n\n";
std::cout << "Signaling end of broadcasting messages\n\n";
coordinator.finishedBroadcasting();
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(60));
}