Bug 375 - Ctrl-C does not always work when running Python simulations
Ctrl-C does not always work when running Python simulations
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: python bindings
ns-3.2
All All
: P3 normal
Assigned To: ns-bugs
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2008-10-08 07:04 EDT by Gustavo J. A. M. Carneiro
Modified: 2009-01-13 14:29 EST (History)
0 users

See Also:


Attachments
rough patch (5.48 KB, patch)
2008-12-25 15:15 EST, Gustavo J. A. M. Carneiro
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Gustavo J. A. M. Carneiro 2008-10-08 07:04:52 EDT
Because Simulator::Run does not give back control to Python, unless there is some scheduled Python callback, so it never "notices" the signal.
Comment 1 Gustavo J. A. M. Carneiro 2008-12-25 15:15:52 EST
Created attachment 342 [details]
rough patch

I had a first patch.  The naive approach:

        while (!ns3::Simulator::IsFinished())
        {        
            if (PyEval_ThreadsInitialized())
                py_thread_state = PyEval_SaveThread();
            ns3::Simulator::RunOneEvent();
            if (py_thread_state)
                PyEval_RestoreThread(py_thread_state);
            PyErr_CheckSignals();
            if (PyErr_Occurred())
                return NULL;
        }

Problems:

 1- I had to patch ns3::Simulator::IsFinished() to consider also the m_stop variable of the scheduler, otherwise my custom loop will ignore the Simulator::Stop() call;

 2- Obviously there is an overhead of checking for signals on _every_ simulator iteration.  On my system, the measured overhead (in the csma-bridge.py example) is 3.5% if the threading python module is not imported, or 4.3% with threading imported (there's an optimization that avoids the Python GIL calls if threading is not being used).

I then modified the patch a bit.  The attached patch takes a parameter 'signal_check_frequency', which is the number of iterations to run before checking for signals, or -1 to not check for signals at all.  With the default value of 100, the overhead is only 0.7% for non-threaded programs, which I think is acceptable.  Ctrl-C is, of course, very responsive.

A better approach would be, perhaps, to create a thread which asks python to check for interrupts every second or so, and sets a global flag when interrupt is detected, so that the simulation loop can check for that variable, which should have less overhead.  But I think this patch is much less complicated and has reasonably low overhead, so I'll settle for it, if no objections.

I have to ask, what to do with the Simulator::IsFinished change?  Is it OK to commit, or propose a new API call to do what I want, or...?
Comment 2 Gustavo J. A. M. Carneiro 2009-01-13 14:29:37 EST
Committed a cleaned up patch.