Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions examples/coroutine/FunctionalEventExampleNetwork.ned
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


package inet.examples.coroutine;

import inet.common.FunctionalEventExample;

network FunctionalEventExampleNetwork
{
submodules:
functionalEvent: FunctionalEventExample;
}
14 changes: 14 additions & 0 deletions examples/coroutine/SimulationContinuationExampleNetwork.ned
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


package inet.examples.coroutine;

import inet.common.SimulationContinuationExample;

network SimulationContinuationExampleNetwork
{
submodules:
continuation: SimulationContinuationExample;
}
14 changes: 14 additions & 0 deletions examples/coroutine/SimulationTaskExampleNetwork.ned
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


package inet.examples.coroutine;

import inet.common.SimulationTaskExample;

network SimulationTaskExampleNetwork
{
submodules:
task: SimulationTaskExample;
}
11 changes: 11 additions & 0 deletions examples/coroutine/omnetpp.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[General]
sim-time-limit = 10s

[Config SimulationTask]
network = SimulationTaskExampleNetwork

[Config SimulationContinuation]
network = SimulationContinuationExampleNetwork

[Config FunctionalEvent]
network = FunctionalEventExampleNetwork
36 changes: 36 additions & 0 deletions src/inet/common/FunctionalEvent.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


#include "inet/common/FunctionalEvent.h"

namespace inet {

void scheduleAt(const char *name, simtime_t time, std::function<void()> f)
{
if (time < simTime())
throw cRuntimeError("Cannot schedule function to the past");
auto event = new FunctionalEvent(name, f);
event->setArrivalTime(time);
getSimulation()->insertEvent(event);
}

void scheduleAfter(const char *name, simtime_t delay, std::function<void()> f)
{
if (delay < 0)
throw cRuntimeError("Cannot schedule function to the past");
scheduleAt(name, simTime() + delay, f);
}

void FunctionalEvent::execute()
{
f();
removeFromOwnershipTree();
delete this;
}

} // namespace inet

47 changes: 47 additions & 0 deletions src/inet/common/FunctionalEvent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


#ifndef __INET_FUNCTIONALEVENT_H
#define __INET_FUNCTIONALEVENT_H

#include "inet/common/INETDefs.h"

namespace inet {

using namespace std;

/**
* Schedules a lambda function for execution at a specific simulation time.
*/
INET_API void scheduleAt(const char *name, simtime_t time, std::function<void()> f);

/**
* Schedules a lambda function for execution after a specific simulation time.
*/
INET_API void scheduleAfter(const char *name, simtime_t delay, std::function<void()> f);

/**
* This event executes a lambda function.
*/
class INET_API FunctionalEvent : public cEvent
{
private:
std::function<void()> f;

public:
FunctionalEvent(const char *name, std::function<void()> f) : cEvent(name), f(f) { }

virtual cEvent *dup() const override { return new FunctionalEvent(getName(), f); }
virtual cObject *getTargetObject() const override { return nullptr; }

virtual void execute() override;
};

} // namespace inet

#endif

34 changes: 34 additions & 0 deletions src/inet/common/FunctionalEventExample.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


#include "inet/common/FunctionalEventExample.h"

#include "inet/common/FunctionalEvent.h"

namespace inet {

Define_Module(FunctionalEventExample);

void FunctionalEventExample::initialize()
{
int count = par("count");
simtime_t maxDelay = par("maxDelay");
for (int i = 0; i < count; i++) {
simtime_t delay = uniform(0, maxDelay);
inet::scheduleAfter("scheduleAfter", delay, [=] () {
std::cout << "At: " << simTime() << " scheduleAfter event " << i << " executed" << std::endl;
});
std::cout << "At: " << simTime() << " scheduled scheduleAfter event " << i << " with delay " << delay << std::endl;
simtime_t time = simTime() + uniform(0, maxDelay);
inet::scheduleAt("scheduleAt", time, [=] () {
std::cout << "At: " << simTime() << " scheduleAt event " << i << " executed" << std::endl;
});
std::cout << "At: " << simTime() << " scheduled scheduleAt event " << i << " at time " << time << std::endl;
}
}

} // namespace inet
23 changes: 23 additions & 0 deletions src/inet/common/FunctionalEventExample.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


#ifndef __INET_FUNCTIONALEVENTEXAMPLE_H
#define __INET_FUNCTIONALEVENTEXAMPLE_H

#include "inet/common/INETDefs.h"

namespace inet {

class INET_API FunctionalEventExample : public cSimpleModule
{
protected:
virtual void initialize() override;
};

} // namespace inet

#endif
18 changes: 18 additions & 0 deletions src/inet/common/FunctionalEventExample.ned
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//

package inet.common;

//
// Example module that demonstrates the use of ~FunctionalEvent for scheduling
// lambda functions at specific simulation times.
//
simple FunctionalEventExample
{
parameters:
int count = default(3);
double maxDelay @unit(s) = default(1s);
}
46 changes: 46 additions & 0 deletions src/inet/common/SimulationContinuation.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


#include "inet/common/SimulationContinuation.h"

namespace inet {

// ---- sleepSimulationTime ----

void sleepSimulationTime(simtime_t duration)
{
// Schedule the resume event BEFORE suspending, because suspendEvent()
// does not return until the event is actually resumed.
resumeEvent(currentEventLoopContext, simTime() + duration);
suspendEvent();
// Resumed after wake-up event fired
}

// ---- SimulationContinuation ----

void SimulationContinuation::suspend()
{
if (isStopped)
throw cRuntimeError("Cannot suspend event execution because suspend() has been already called");
isStopped = true;
// Save the context pointer BEFORE suspending, so resume() can use it later
suspendedContext = currentEventLoopContext;
suspendEvent();
// Resumed after resume() scheduled a wake-up event
}

void SimulationContinuation::resume()
{
if (!isStopped)
throw cRuntimeError("Cannot resume event execution because suspend() has not been called yet");
isStopped = false;
resumeEvent(suspendedContext, simTime());
suspendedContext = nullptr;
}

} // namespace inet

39 changes: 39 additions & 0 deletions src/inet/common/SimulationContinuation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


#ifndef __INET_SIMULATIONCONTINUATION_H
#define __INET_SIMULATIONCONTINUATION_H

#include "inet/common/INETDefs.h"

namespace inet {

/**
* Stops the execution of the current event and schedules resuming the execution after the specified simulation time.
*/
INET_API void sleepSimulationTime(simtime_t duration);

/**
* This class supports temporarily stopping and later resuming the execution of the current event.
*/
class INET_API SimulationContinuation
{
protected:
bool isStopped = false;
EventLoopContext *suspendedContext = nullptr;

public:
virtual ~SimulationContinuation() { }

virtual void suspend();
virtual void resume();
};

} // namespace inet

#endif

45 changes: 45 additions & 0 deletions src/inet/common/SimulationContinuationExample.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


#include "inet/common/SimulationContinuationExample.h"

#include "inet/common/FunctionalEvent.h"
#include "inet/common/SimulationContinuation.h"

namespace inet {

Define_Module(SimulationContinuationExample);

void SimulationContinuationExample::initialize()
{
scheduleAt(simTime(), new cMessage("start"));
}

void SimulationContinuationExample::handleMessage(cMessage *msg)
{
delete msg;
runSimulationContinuationExample();
}

void SimulationContinuationExample::runSimulationContinuationExample()
{
int count = par("count");
simtime_t maxSleepTime = par("maxSleepTime");
for (int i = 0; i < count; i++) {
SimulationContinuation continuation;
inet::scheduleAfter("resume", uniform(0, maxSleepTime), [&] () {
std::cout << "At: " << simTime() << " step " << i << " resuming" << std::endl;
continuation.resume();
});
std::cout << "At: " << simTime() << " step " << i << " suspending" << std::endl;
continuation.suspend();
std::cout << "At: " << simTime() << " step " << i << " resumed" << std::endl;
}
std::cout << "At: " << simTime() << " all steps finished" << std::endl;
}

} // namespace inet
26 changes: 26 additions & 0 deletions src/inet/common/SimulationContinuationExample.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//


#ifndef __INET_SIMULATIONCONTINUATIONEXAMPLE_H
#define __INET_SIMULATIONCONTINUATIONEXAMPLE_H

#include "inet/common/INETDefs.h"

namespace inet {

class INET_API SimulationContinuationExample : public cSimpleModule
{
protected:
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;

virtual void runSimulationContinuationExample();
};

} // namespace inet

#endif
18 changes: 18 additions & 0 deletions src/inet/common/SimulationContinuationExample.ned
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Copyright (C) 2024 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//

package inet.common;

//
// Example module that demonstrates the use of ~SimulationContinuation for
// suspending and resuming event execution.
//
simple SimulationContinuationExample
{
parameters:
int count = default(3);
double maxSleepTime @unit(s) = default(1s);
}
Loading
Loading