Skip to content
Permalink
Browse files
Emulate a more recent time to application plugins
Whereever we communicate a time with a plug-in, we should emulate
that it is more recent than the epoch to prevent lazy programming
from causing problems when running in Shadow.

fixes #392
  • Loading branch information
robgjansen committed Jan 23, 2018
1 parent c43cea1 commit 50720e887598df3bfd016429d3fface51bf2cbe7
@@ -317,6 +317,13 @@ SimulationTime worker_getCurrentTime() {
return worker->clock.now;
}

/* The emulated time starts at January 1st, 2000. This time should be used
* in any places where time is returned to the application, to handle code
* that assumes the world is in a relatively recent time. */
EmulatedTime worker_getEmulatedTime() {
return (EmulatedTime)(worker_getCurrentTime() + EMULATED_TIME_OFFSET);
}

guint worker_getRawCPUFrequency() {
Worker* worker = _worker_getPrivate();
return slave_getRawCPUFrequency(worker->slave);
@@ -28,6 +28,8 @@ void worker_sendPacket(Packet* packet);
gboolean worker_isAlive();

SimulationTime worker_getCurrentTime();
EmulatedTime worker_getEmulatedTime();

guint worker_getRawCPUFrequency();
guint32 worker_getNodeBandwidthUp(GQuark nodeID, in_addr_t ip);
guint32 worker_getNodeBandwidthDown(GQuark nodeID, in_addr_t ip);
@@ -58,6 +58,20 @@ typedef guint ShadowID;
*/
#define SIMTIME_ONE_HOUR G_GUINT64_CONSTANT(3600000000000)

/**
* Emulation time in nanoseconds. Allows for a consistent representation
* of time throughput the simulator. Emulation time is the simulation time
* plus the EMULATION_TIME_OFFSET. This type allows us to explicitly
* distinguish each type of time in the code.,
*/
typedef guint64 EmulatedTime;

/**
* The number of nanoseconds from the epoch to January 1st, 2000 at 12:00am UTC.
* This is used to emulate to applications that we are in a recent time.
*/
#define EMULATED_TIME_OFFSET G_GUINT64_CONSTANT(946684800) * SIMTIME_ONE_SECOND

#ifdef DEBUG
/**
* Memory magic for assertions that memory has not been freed. The idea behind
@@ -1737,7 +1737,6 @@ void tcp_processPacket(TCP* tcp, Packet* packet) {
return;
}

SimulationTime now = worker_getCurrentTime();
gint nPacketsAcked = 0;

if(packetLength > 0) {
@@ -4308,9 +4308,16 @@ int process_emu_fflush(Process* proc, FILE *stream) {

/* time family */

/* make sure we return the 'emulated' time, and not the actual simulation clock */
EmulatedTime _process_getEmulatedTimeHelper(Process* proc) {
return worker_getEmulatedTime();
}

time_t process_emu_time(Process* proc, time_t *t) {
ProcessContext prevCTX = _process_changeContext(proc, proc->activeContext, PCTX_SHADOW);
time_t secs = (time_t) (worker_getCurrentTime() / SIMTIME_ONE_SECOND);

EmulatedTime now = _process_getEmulatedTimeHelper(proc);
time_t secs = (time_t) (now / SIMTIME_ONE_SECOND);
if(t != NULL){
*t = secs;
}
@@ -4326,7 +4333,7 @@ int process_emu_clock_gettime(Process* proc, clockid_t clk_id, struct timespec *

ProcessContext prevCTX = _process_changeContext(proc, proc->activeContext, PCTX_SHADOW);

SimulationTime now = worker_getCurrentTime();
EmulatedTime now = _process_getEmulatedTimeHelper(proc);
tp->tv_sec = now / SIMTIME_ONE_SECOND;
tp->tv_nsec = now % SIMTIME_ONE_SECOND;

@@ -4337,12 +4344,14 @@ int process_emu_clock_gettime(Process* proc, clockid_t clk_id, struct timespec *
int process_emu_gettimeofday(Process* proc, struct timeval* tv, struct timezone* tz) {
if(tv) {
ProcessContext prevCTX = _process_changeContext(proc, proc->activeContext, PCTX_SHADOW);
SimulationTime now = worker_getCurrentTime();
SimulationTime sec = now / (SimulationTime)SIMTIME_ONE_SECOND;
SimulationTime usec = (now - (sec*(SimulationTime)SIMTIME_ONE_SECOND)) / (SimulationTime)SIMTIME_ONE_MICROSECOND;
utility_assert(usec < (SimulationTime)1000000);

EmulatedTime now = _process_getEmulatedTimeHelper(proc);
EmulatedTime sec = now / (EmulatedTime)SIMTIME_ONE_SECOND;
EmulatedTime usec = (now - (sec*(EmulatedTime)SIMTIME_ONE_SECOND)) / (EmulatedTime)SIMTIME_ONE_MICROSECOND;
utility_assert(usec < (EmulatedTime)1000000);
tv->tv_sec = (time_t)sec;
tv->tv_usec = (suseconds_t)usec;

_process_changeContext(proc, PCTX_SHADOW, prevCTX);
}
return 0;
@@ -11,8 +11,8 @@ extern int run_test_arg(time_t);
int main(int argc, char* argv[]) {
fprintf(stdout, "########## preload test starting ##########\n");

/* preload.test.shadow.config.xml runs at time 3, so shadow's preload will return 3 */
if(run_test_arg((time_t)3) != 0) {
/* preload.test.shadow.config.xml runs at time 946684803, so shadow's preload will return 946684803 */
if(run_test_arg((time_t)946684803) != 0) {
fprintf(stdout, "########## preload test failed\n");
return -EXIT_FAILURE;
}

0 comments on commit 50720e8

Please sign in to comment.