Skip to content

Commit

Permalink
Merge pull request #28 from sio2project/real-time-output
Browse files Browse the repository at this point in the history
Real time output
  • Loading branch information
b-chmiel authored Dec 1, 2021
2 parents db0aed6 + 61a6131 commit 369317c
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 15 deletions.
27 changes: 19 additions & 8 deletions src/limits/TimeLimitListener.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,24 +88,27 @@ executor::ExecuteAction TimeLimitListener::onSigalrmSignal() {
if (!isTimerCreated_) {
return executor::ExecuteAction::CONTINUE;
}
return verifyTimeUsage();
auto time = getTimeUsage();
return verifyTimeUsage(move(time));
}

void TimeLimitListener::onPostExecute() {
// TODO: run this just after child exit
verifyTimeUsage();
// TODO Save time usage to OutputBuilder.
auto time = getTimeUsage();
outputBuilder_->setRealTimeMicroseconds(time->realTimeUs);
verifyTimeUsage(move(time));
}

executor::ExecuteAction TimeLimitListener::verifyTimeUsage() {
if (rTimelimitUs_ != 0 && getRealTimeUsage() > rTimelimitUs_) {
executor::ExecuteAction TimeLimitListener::verifyTimeUsage(std::unique_ptr<TimeLimitListener::TimeUsage> timeUsage) {
if (rTimelimitUs_ != 0 && timeUsage->realTimeUs > rTimelimitUs_) {
outputBuilder_->setKillReason(
printer::OutputBuilder::KillReason::TLE,
"real time limit exceeded");
return executor::ExecuteAction::KILL;
}
if (uTimelimitUs_ != 0 || sTimelimitUs_ != 0 || usTimelimitUs_ != 0) {
ProcessTimeUsage ptu = getProcessTimeUsage();
ProcessTimeUsage& ptu = timeUsage->processTimeUs;

if (uTimelimitUs_ != 0 && ptu.uTimeUs > uTimelimitUs_) {
outputBuilder_->setKillReason(
printer::OutputBuilder::KillReason::TLE,
Expand All @@ -128,7 +131,7 @@ executor::ExecuteAction TimeLimitListener::verifyTimeUsage() {
return executor::ExecuteAction::CONTINUE;
}

uint64_t TimeLimitListener::getRealTimeUsage() {
uint64_t TimeLimitListener::getRealTimeUsage() const {
std::chrono::steady_clock::time_point now =
std::chrono::steady_clock::now();
std::chrono::steady_clock::duration realTimeUsage = now - startRealTime_;
Expand All @@ -138,7 +141,7 @@ uint64_t TimeLimitListener::getRealTimeUsage() {
return realTimeUsageUs;
}

TimeLimitListener::ProcessTimeUsage TimeLimitListener::getProcessTimeUsage() {
TimeLimitListener::ProcessTimeUsage TimeLimitListener::getProcessTimeUsage() const {
std::ifstream stat("/proc/" + std::to_string(childPid_) + "/stat");
if (!stat.good()) {
throw SystemException("Error reading /proc/childPid_/stat");
Expand All @@ -164,6 +167,14 @@ TimeLimitListener::ProcessTimeUsage TimeLimitListener::getProcessTimeUsage() {
return result;
}

std::unique_ptr<TimeLimitListener::TimeUsage> TimeLimitListener::getTimeUsage() const {
return std::make_unique<TimeUsage>(
TimeUsage{
.realTimeUs = getRealTimeUsage(),
.processTimeUs = getProcessTimeUsage()
}
);
}

} // namespace limits
} // namespace s2j
12 changes: 9 additions & 3 deletions src/limits/TimeLimitListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,18 @@ class TimeLimitListener
uint64_t sTimeUs; // system time in [us]
};

struct TimeUsage {
uint64_t realTimeUs;
ProcessTimeUsage processTimeUs;
};

static const uint64_t TIMER_TICKING_INTERVAL_US;
static const long CLOCK_TICKS_PER_SECOND;

executor::ExecuteAction verifyTimeUsage();
uint64_t getRealTimeUsage();
ProcessTimeUsage getProcessTimeUsage();
executor::ExecuteAction verifyTimeUsage(std::unique_ptr<TimeUsage>);
uint64_t getRealTimeUsage() const;
ProcessTimeUsage getProcessTimeUsage() const;
std::unique_ptr<TimeUsage> getTimeUsage() const;

uint64_t rTimelimitUs_; // real time limit in [us]
uint64_t uTimelimitUs_; // user time limit in [us]
Expand Down
6 changes: 6 additions & 0 deletions src/printer/OIModelOutputBuilder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace printer {

OIModelOutputBuilder::OIModelOutputBuilder()
: milliSecondsElapsed_(0)
, realMilliSecondsElapsed_(0)
, memoryPeakKb_(0)
, syscallsCounter_(0)
, exitStatus_(0)
Expand All @@ -15,6 +16,11 @@ OutputBuilder& OIModelOutputBuilder::setCyclesUsed(uint64_t cyclesUsed) {
return *this;
}

OutputBuilder& OIModelOutputBuilder::setRealTimeMicroseconds(uint64_t time) {
realMilliSecondsElapsed_ = time / 1000;
return *this;
}

OutputBuilder& OIModelOutputBuilder::setMemoryPeak(uint64_t memoryPeakKb) {
memoryPeakKb_ = memoryPeakKb;
return *this;
Expand Down
2 changes: 2 additions & 0 deletions src/printer/OIModelOutputBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class OIModelOutputBuilder : public OutputBuilder {
OIModelOutputBuilder();

OutputBuilder& setCyclesUsed(uint64_t cyclesUsed) override;
OutputBuilder& setRealTimeMicroseconds(uint64_t time) override;
OutputBuilder& setMemoryPeak(uint64_t memoryPeakKb) override;
OutputBuilder& setExitStatus(uint32_t exitStatus) override;
OutputBuilder& setKillSignal(uint32_t killSignal) override;
Expand All @@ -20,6 +21,7 @@ class OIModelOutputBuilder : public OutputBuilder {
static const uint64_t CYCLES_PER_SECOND = 2'000'000'000;

uint64_t milliSecondsElapsed_;
uint64_t realMilliSecondsElapsed_;
uint64_t memoryPeakKb_;
uint64_t syscallsCounter_;
uint32_t exitStatus_;
Expand Down
3 changes: 3 additions & 0 deletions src/printer/OutputBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class OutputBuilder {
virtual OutputBuilder& setCyclesUsed(uint64_t cyclesUsed) {
return *this;
}
virtual OutputBuilder& setRealTimeMicroseconds(uint64_t time) {
return *this;
}
virtual OutputBuilder& setMemoryPeak(uint64_t memoryPeakKb) {
return *this;
}
Expand Down
44 changes: 44 additions & 0 deletions src/printer/RealTimeOIOutputBuilder.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "RealTimeOIOutputBuilder.h"

#include <sstream>

namespace s2j {
namespace printer {

const std::string RealTimeOIOutputBuilder::FORMAT_NAME = "oireal";

std::string RealTimeOIOutputBuilder::dump() const {
KillReason reason = killReason_;
if (reason == KillReason::NONE) {
if (killSignal_ > 0 || exitStatus_ > 0) {
reason = KillReason::RE;
}
}

std::stringstream ss;
ss << killReasonName(reason) << " " << exitStatus_ << " "
<< realMilliSecondsElapsed_ << " "
<< 0ULL << " " << memoryPeakKb_ << " "
<< syscallsCounter_ << std::endl;
dumpStatus(ss);
ss << std::endl;
return ss.str();
}

void RealTimeOIOutputBuilder::dumpStatus(std::ostream& ss) const {
if (killReason_ != KillReason::NONE) {
ss << killReasonComment_;
}
else if (killSignal_ > 0) {
ss << "process exited due to signal " << killSignal_;
}
else if (exitStatus_ > 0) {
ss << "runtime error " << exitStatus_;
}
else {
ss << "ok";
}
}

} // namespace printer
} // namespace s2j
20 changes: 20 additions & 0 deletions src/printer/RealTimeOIOutputBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include "OIModelOutputBuilder.h"

namespace s2j {
namespace printer {

class RealTimeOIOutputBuilder : public OIModelOutputBuilder {
public:
std::string dump() const override;

const static std::string FORMAT_NAME;

private:
void dumpStatus(std::ostream& ss) const;
int encodeStatusCode() const;
};

} // namespace printer
} // namespace s2j
8 changes: 6 additions & 2 deletions src/s2japp/ApplicationSettings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "common/Utils.h"
#include "printer/AugmentedOIOutputBuilder.h"
#include "printer/OITimeToolOutputBuilder.h"
#include "printer/RealTimeOIOutputBuilder.h"
#include "seccomp/policy/DefaultPolicy.h"
#include "seccomp/policy/PermissivePolicy.h"

Expand Down Expand Up @@ -80,7 +81,7 @@ class StringOutputGenerator : public TCLAP::StdOutput {
namespace s2j {
namespace app {

const std::string ApplicationSettings::VERSION = "1.4.1-beta";
const std::string ApplicationSettings::VERSION = "1.4.2";

const std::string ApplicationSettings::DESCRIPTION =
"SIO2jail, a sandbox for programming contests.";
Expand All @@ -90,7 +91,10 @@ const FactoryMap<s2j::printer::OutputBuilder>
{{"oitt",
std::make_shared<s2j::printer::OITimeToolOutputBuilder>},
{"oiaug",
std::make_shared<s2j::printer::AugmentedOIOutputBuilder>}});
std::make_shared<s2j::printer::AugmentedOIOutputBuilder>},
{"oireal",
std::make_shared<s2j::printer::RealTimeOIOutputBuilder>}
});
const std::string ApplicationSettings::DEFAULT_OUTPUT_FORMAT = "oitt";

const FactoryMap<s2j::seccomp::policy::BaseSyscallPolicy>
Expand Down
6 changes: 4 additions & 2 deletions src/seccomp/policy/DefaultPolicy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ void DefaultPolicy::addExecutionControlRules(bool allowFork) {
"clock_nanosleep",
"open",
"epoll_create1",
"openat"});
"openat"
});

rules_.emplace_back(SeccompRule(
"set_thread_area", action::ActionTrace([](auto& /* tracee */) {
Expand Down Expand Up @@ -128,7 +129,7 @@ void DefaultPolicy::addInputOutputRules() {
"dup2", action::ActionAllow(), filter::SyscallArg(1) >= 3));

// Allow reading from any file descriptor
allowSyscalls({"read", "readv", "dup", "fcntl", "fcntl64"});
allowSyscalls({"read", "readv", "dup", "fcntl", "fcntl64", "pread64"});

rules_.emplace_back(SeccompRule("ioctl", action::ActionErrno(ENOTTY)));

Expand All @@ -150,6 +151,7 @@ void DefaultPolicy::addFileSystemAccessRules(bool readOnly) {
"stat64",
"fstat",
"fstat64",
"newfstatat",
"lstat",
"lstat64",
"listxattr",
Expand Down

0 comments on commit 369317c

Please sign in to comment.