summaryrefslogtreecommitdiff
path: root/nemesis/nemesis.py
diff options
context:
space:
mode:
Diffstat (limited to 'nemesis/nemesis.py')
-rwxr-xr-xnemesis/nemesis.py64
1 files changed, 46 insertions, 18 deletions
diff --git a/nemesis/nemesis.py b/nemesis/nemesis.py
index eaf41f3..69d0c2b 100755
--- a/nemesis/nemesis.py
+++ b/nemesis/nemesis.py
@@ -25,16 +25,17 @@ Commentary:
Code:
'''
+from asyncio.base_events import _format_handle
+from collections import defaultdict
+from experiment import Experiment
import argparse
import asyncio
+import os
import signal
import sys
-import traceback
import time
+import traceback
import types
-import os
-from experiment import Experiment
-from asyncio.base_events import _format_handle
class Nemesis(object):
@@ -51,20 +52,21 @@ class Nemesis(object):
e_duration = None
# The number of seconds remaining in this performance experiment.
r_duration = None
+ # A mapping of event loops to the previous running coroutine.
+ prev_coro = defaultdict(lambda: None)
# temp
- task = None
+ coro = None
dilation = 1.0
@staticmethod
- def __init__(task, speedup, e_duration, w_time, signal_interval=0.01):
- os.environ["PYTHONASYNCIODEBUG"] = "1"
+ def __init__(coro, speedup, e_duration, w_time, signal_interval=0.01):
Nemesis.signal_interval = signal_interval
Nemesis.e_duration = e_duration
- Nemesis.r_duration = w_time
+ Nemesis.r_duration = 0
# temporary
- Nemesis.task = task
- Nemesis.speedup = speedup
+ Nemesis.coro = coro
+ Nemesis.speedup = max(speedup, 1.0)
@staticmethod
def start():
@@ -86,12 +88,13 @@ class Nemesis(object):
@staticmethod
def _start_experiment():
Nemesis.r_duration = Nemesis.e_duration
- Nemesis.curr_experiment = Experiment(Nemesis.task, Nemesis.speedup)
+ Nemesis.prev_coro = defaultdict(lambda: None)
+ Nemesis.curr_experiment = Experiment(Nemesis.coro, Nemesis.speedup)
@staticmethod
def _stop_experiment():
if Nemesis.curr_experiment is not None:
- print(f'finished running {Nemesis.curr_experiment.get_task()} with speedup {Nemesis.curr_experiment.get_speedup()}')
+ print(f'finished running {Nemesis.curr_experiment.get_coro()} with speedup {Nemesis.curr_experiment.get_speedup()}')
Nemesis.results.append(Nemesis.curr_experiment.get_results())
del Nemesis.curr_experiment
@@ -102,8 +105,17 @@ class Nemesis(object):
Nemesis.last_sample = curr_sample
if Nemesis.curr_experiment:
loops = Nemesis.curr_experiment.get_loops()
- # print(loops)
+ exp_coro = Nemesis.curr_experiment.get_coro()
for loop in loops:
+ coro = Nemesis._get_current_coro(loop)
+ prev_coro = Nemesis.prev_coro[loop]
+ if not prev_coro == coro:
+ if prev_coro == exp_coro:
+ loop.ping_exit_coro()
+ elif coro == exp_coro:
+ loop.ping_enter_coro()
+ Nemesis.prev_coro[loop] = coro
+
loop._update_ready(True)
handles = Nemesis._get_waiting_handles(loop)
Nemesis.curr_experiment.add_handles(handles, loop, passed_time)
@@ -122,11 +134,27 @@ class Nemesis(object):
handles.append(fmt_handle)
return handles
+ def _get_current_coro(loop):
+ tid = loop._thread_id
+ assert tid, f"{loop} is not running, yet we attempted to sample it!"
+
+ frame = sys._current_frames().get(tid)
+ fname = frame.f_code.co_filename
+ while not Nemesis._should_trace(fname):
+ if frame:
+ frame = frame.f_back
+ else:
+ break
+ if frame:
+ fname = frame.f_code.co_filename
+ if frame and frame.f_generator:
+ return frame.f_generator.cr_code.co_name
+ return None
+
@staticmethod
def _should_trace(filename):
'''Returns FALSE if filename is uninteresting to the user.
- Don't depend on this. It's good enough for testing.'''
- # FIXME Assume GuixSD. Makes filtering easy
+ Don't depend on this. It kind of sucks.'''
if not filename:
return False
if '/gnu/store' in filename:
@@ -172,10 +200,10 @@ if __name__ == "__main__":
type=float,
default=0.01)
parser.add_argument('-s', '--speedup',
- help='The amount of virtual speedup.',
+ help='The amount of virtual speedup. Cannot go below one. Default is 2.0.',
metavar='',
type=float,
- default=0.5)
+ default=2.0)
parser.add_argument('-c', '--task',
help='The task to virtually speedup.',
metavar='',
@@ -187,7 +215,7 @@ if __name__ == "__main__":
type=float,
default=4)
parser.add_argument('-w', '--warmup-time',
- help='Amount of time to wait until the first performance experiment. Default is the minimum time of 100 milliseconds',
+ help='Amount of time to wait until the first performance experiment. Default is 0 milliseconds',
metavar='',
type=float,
default=0.1)