PlatformLab/Arachne

Arachne::sleep(uint64_t ns) broken?

yilongli opened this issue · 2 comments

I have a piece of code like the following in my application to check whether Arachne::sleep works as expected:

uint64_t wakeupTime = Cycles::rdtsc() + Cycles::fromNanoseconds(
        Cycles::toNanoseconds(sleepCycles));
Arachne::sleep(Cycles::toNanoseconds(sleepCycles));
uint64_t now = Cycles::rdtsc();
if (now < wakeupTime) {
    LOG(ERROR, "Arachne::sleep broken; woke up %lu cyc early", wakeupTime - now);
}

I frequently get the error message with a non-trivial gap between now and wakeupTime. Can you confirm that the sleeping thread will only wake up after Cycles::rdtsc() is larger than core.loadedContext->wakeupTimeInCycles?

Also, can you provide an Arachne::sleep(uint64 cycles) to avoid the hassle and potential precision problem of manually converting between cycles and nanoseconds? Thanks.

hq6 commented

I cannot reproduce this problem. Please specify a value for sleepCycles where this problem reproduces. I ran the following program for ~1 minute without producing the problem.

#include <stdio.h>
#include "Arachne/Arachne.h"
#include "PerfUtils/Cycles.h"

using PerfUtils::Cycles;

 // This is where user code should start running.
void AppMain(int argc, const char** argv) {
    uint64_t sleepCycles = 1000000;
    while (true) {
        uint64_t wakeupTime = Cycles::rdtsc() + Cycles::fromNanoseconds(
                Cycles::toNanoseconds(sleepCycles));
        Arachne::sleep(Cycles::toNanoseconds(sleepCycles));
        uint64_t now = Cycles::rdtsc();
        if (now < wakeupTime) {
            fprintf(stderr, "Arachne::sleep broken; woke up %lu cyc early", wakeupTime - now);
        }
    }
}

 // The following bootstrapping code should be copied verbatim into most Arachne
 // applications.
 void AppMainWrapper(int argc, const char** argv) {
     AppMain(argc, argv);
     Arachne::shutDown();
 }
 int main(int argc, const char** argv){
     Arachne::init(&argc, argv);
     Arachne::createThread(&AppMainWrapper, argc, argv);
     Arachne::waitForTermination();
 }

After some more investigation, the problem appears to be that I am using a different Cycles::cyclesPerSec value than Arachne when I convert between seconds and cycles. There won't be a problem if there is an Arachne::sleep(uint64_t cycles) method.