0
votes

The simulation runs but in the console I have this note.

undisposed object: (omnetpp::cMessage) Mysimulation.Switch4.eth[2].queue.scheduler.IntervalTimemsg -- check module destructor undisposed object: (omnetpp::cMessage) Mysimulation.Switch5.eth[1].queue.scheduler.IntervalTimemsg -- check module destructor

Actually It is a module that I have created using two timing messages over and over through the simulation. I read online and found that this error is related to creating objects that is not deleted at the time it should be deleted.

void PriorityScheduler::initialize() {
gateCycleTimemsg = new cMessage("gateCycleTimemsg"); 
scheduleAt(baseTime , gateCycleTimemsg); 
// baseTime = 2s
}

void PriorityScheduler::handleMessage(cMessage *msg) {
   if (msg == gateCycleTimemsg) {

      if (currentList == (lastIntervalTime)) {  
      delete msg; 
      gateCycleTimemsg = new cMessage("gateCycleTimemsg");     
      scheduleAt( simTime() + gateCycleTime , gateCycleTimemsg); 
      ...
      IntervalTimemsg = new cMessage("IntervalTimemsg");
      scheduleAt( simTime() + Interval , IntervalTimemsg);
      }

      else if (currentList == (firstIntervalTime)) {
      gateCycleTimemsg = msg;    // same message reused
      scheduleAt(simTime() + gateCycleTime , gateCycleTimemsg); 
      //gateCycleTime = 10 seconds
      ...
      IntervalTimemsg = new cMessage("IntervalTimemsg"); 
      scheduleAt( simTime() + Interval , IntervalTimemsg); 
      // Interval = 1s
      }
  }

  else if (msg == IntervalTimemsg) {
       if (currentList == (lastIntervalTime));    
       else{
       IntervalTimemsg = msg;                 
       scheduleAt( simTime() + Interval , IntervalTimemsg);
       }
}

Plugin path: /home/amr/omnetpp-5.0/samples/etc/plugins;./plugins terminate called after throwing an instance of 'omnetpp::cRuntimeError' what(): Object pk-56-145 is currently in (omnetpp::cEventHeap)simulation.scheduled-events, it cannot be deleted. If this error occurs inside omnetpp::cEventHeap, it needs to be changed to call drop() before it can delete that object. If this error occurs inside omnetpp::cEventHeap's destructor and pk-56-145 is a class member, omnetpp::cEventHeap needs to call drop() in the destructor

I created a constructor as well as destructor. I also created the function finish() after reading online for solutions. Still this didn't solve it.

I also removed each message received and created a new one while sending but It didn't change any thing.

edit: I edited the coding with delete msg; I added and gave an example of timings and added the below part,

BaseTime 'BT', gateCycleTime 'CT', Interval 'IT'

----> BT              
         <---- IT1 ----> <----- IT2 ----> .........<-------- ITx -------->    
         <------------------------------ CT ----------------------------->

I used the same message for BT and CT while another message for ITs as I dont know the timing of the last IT 'ITx'.

3

3 Answers

3
votes

You are creating new timers (messages) but never delete the old ones. Simply deleting the message while it is processed, does not work (hence the error message).

My suggestion (without knowing anything in particular about your simulation):

  1. create the timer message once in your initialization function (for example)
  2. in if (msg == gateCycleTimemsg) --> check if the timer message is already scheduled
  3. if the timer message is already scheduled, cancel the timer and reschedule it again but do not create a new one
  4. if the timer is not scheduled, schedule (create) it (for the first time apparently)
  5. for else if (msg == IntervalTimemsg) --> this is called when the timer experied (the self message was delivered), hence just reschedule the timer but do not create a new message.

You can read more about self messages (often used for timers) in the OMNeT++ manual: https://omnetpp.org/doc/omnetpp/manual/#sec:simple-modules:self-messages

1
votes

In general, timers should not be created in the handleMessage() function to avoid the creation and destruction of objects in each call. Therefore, the initialize function should create the messages

void PriorityScheduler::initialize() {
    gateCycleTimemsg = new cMessage("gateCycleTimemsg");
    IntervalTimemsg = new cMessage("IntervalTimemsg");
    scheduleAt(baseTime , gateCycleTimemsg); 
}

and the finish function or the destructor should clean them.

void PriorityScheduler::finish() {
    cancelAndDelete(gateCycleTimemsg);
    cancelAndDelete(IntervalTimemsg);
}
1
votes

In the line

IntervalTimemsg = new cMessage("IntervalTimemsg"); 

you every time create a new instance of cMessage object, and the pointer to it you write into IntervalTimemsg. However, you never delete an object indicated by IntervalTimemsg. As a consequence, when this line is executed second (and another) time:

  • A new object is created in the memory
  • The pointer to the previous object is lost
  • The previous object still exists in the memory

Therefore cancelAndDelete(IntervalTimemsg) in finish() will only delete the last object.

Proposed solution:

  1. In constructor add:

    IntervalTimemsg = nullptr;
    
  2. Change the line:

    IntervalTimemsg = new cMessage("IntervalTimemsg"); 
    

    into:

    if (IntervalTimemsg != nullptr) {
       cancelAndDelete (IntervalTimemsg);
    }
    IntervalTimemsg = new cMessage("IntervalTimemsg");