summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--__pycache__/mini_scalene.cpython-311.pycbin13865 -> 0 bytes
-rw-r--r--__pycache__/replacement_poll_selector.cpython-311.pycbin2546 -> 0 bytes
-rw-r--r--__pycache__/sitecustomize.cpython-311.pycbin417 -> 0 bytes
-rw-r--r--mini_scalene.py15
-rw-r--r--replacement_epoll_selector.py27
-rw-r--r--replacement_poll_selector.py41
-rw-r--r--tests/overload.py29
-rw-r--r--tests/simult.py17
-rw-r--r--tests/successive_sleep.py15
10 files changed, 39 insertions, 106 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c18dd8d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+__pycache__/
diff --git a/__pycache__/mini_scalene.cpython-311.pyc b/__pycache__/mini_scalene.cpython-311.pyc
deleted file mode 100644
index 24b7268..0000000
--- a/__pycache__/mini_scalene.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/__pycache__/replacement_poll_selector.cpython-311.pyc b/__pycache__/replacement_poll_selector.cpython-311.pyc
deleted file mode 100644
index b346241..0000000
--- a/__pycache__/replacement_poll_selector.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/__pycache__/sitecustomize.cpython-311.pyc b/__pycache__/sitecustomize.cpython-311.pyc
deleted file mode 100644
index 4f5ff5a..0000000
--- a/__pycache__/sitecustomize.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/mini_scalene.py b/mini_scalene.py
index 569d7c0..f7a8ca9 100644
--- a/mini_scalene.py
+++ b/mini_scalene.py
@@ -1,3 +1,5 @@
+import selectors
+
import sys
import argparse
import threading
@@ -13,6 +15,7 @@ from typing import (
)
from types import FrameType
from collections import defaultdict
+import replacement_epoll_selector
the_globals = {
'__name__': '__main__',
@@ -64,7 +67,6 @@ class MiniScalene(object):
profile_async = True
def __init__(self):
- import replacement_poll_selector
signal.signal(signal.SIGPROF,
self.cpu_signal_handler)
signal.setitimer(signal.ITIMER_PROF,
@@ -80,12 +82,16 @@ class MiniScalene(object):
@staticmethod
def start(profile_async):
MiniScalene.profile_async = profile_async
- atexit.register(MiniScalene.exit_handler)
@staticmethod
- def exit_handler():
- '''Turn off profiling signals & pretty-print profiling information.'''
+ def stop():
+ '''Turn off profiling signals'''
MiniScalene.disable_signals()
+ MiniScalene.exit_handler()
+
+ @staticmethod
+ def exit_handler():
+ '''Pretty-print profiling information.'''
# If we've collected any samples, dump them.
print("CPU usage (Python):")
if MiniScalene.total_cpu_samples > 0:
@@ -250,6 +256,7 @@ def main():
code = compile(fp.read(), args.script, "exec")
MiniScalene().start(args.async_off)
exec(code, the_globals)
+ MiniScalene().stop()
except Exception:
traceback.print_exc()
diff --git a/replacement_epoll_selector.py b/replacement_epoll_selector.py
new file mode 100644
index 0000000..545bbc6
--- /dev/null
+++ b/replacement_epoll_selector.py
@@ -0,0 +1,27 @@
+import selectors
+import sys
+import time
+from typing import List, Tuple
+
+
+class ReplacementEpollSelector(selectors.EpollSelector):
+ def select(
+ self, timeout=None
+ ) -> List[Tuple[selectors.SelectorKey, int]]:
+ start_time = time.perf_counter()
+ if not timeout or timeout < 0:
+ interval = sys.getswitchinterval()
+ else:
+ interval = min(timeout, sys.getswitchinterval())
+ while True:
+ selected = super().select(interval)
+ if selected or timeout == 0 or not timeout:
+ return selected
+ end_time = time.perf_counter()
+ if end_time - start_time >= timeout:
+ return [] # None
+
+ReplacementEpollSelector.__qualname__ = (
+ "replacement_epoll_selector.ReplacementEpollSelector"
+)
+selectors.DefaultSelector = ReplacementEpollSelector
diff --git a/replacement_poll_selector.py b/replacement_poll_selector.py
deleted file mode 100644
index 0813a66..0000000
--- a/replacement_poll_selector.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import selectors
-import sys
-import threading
-import time
-from typing import List, Optional, Tuple
-
-from mini_scalene import MiniScalene
-
-
-@MiniScalene.shim
-def replacement_poll_selector(mini_scalene: MiniScalene) -> None:
- """
- A replacement for selectors.PollSelector that
- periodically wakes up to accept signals
- """
-
- class ReplacementPollSelector(selectors.PollSelector):
- def select(
- self, timeout: Optional[float] = -1
- ) -> List[Tuple[selectors.SelectorKey, int]]:
- tident = threading.get_ident()
- start_time = time.perf_counter()
- if not timeout or timeout < 0:
- interval = sys.getswitchinterval()
- else:
- interval = min(timeout, sys.getswitchinterval())
- while True:
- scalene.set_thread_sleeping(tident)
- selected = super().select(interval)
- scalene.reset_thread_sleeping(tident)
- if selected or timeout == 0:
- return selected
- end_time = time.perf_counter()
- if timeout and timeout != -1:
- if end_time - start_time >= timeout:
- return [] # None
-
- ReplacementPollSelector.__qualname__ = (
- "replacement_poll_selector.ReplacementPollSelector"
- )
- selectors.PollSelector = ReplacementPollSelector # type: ignore
diff --git a/tests/overload.py b/tests/overload.py
deleted file mode 100644
index 9bba9a1..0000000
--- a/tests/overload.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import asyncio
-import time
-
-async def busy_task():
- i = 0
- while i < 100:
- i += 1
- await asyncio.sleep(3.0)
- return 1
-
-async def main():
- tasks = [asyncio.create_task(busy_task()) for i in range(5)]
-
- start_time = time.time()
- try:
- # this is to prevent waiting in 'select' all day,
- # which makes the python intepreter not respond to
- # mini-scalene / SCALENE
- while True:
- if time.time() - start_time > 4.0:
- break
- # print(asyncio.all_tasks())
- await asyncio.sleep(0) # yield
- except KeyboardInterrupt:
- pass
- finally:
- print("Done.")
-
-asyncio.run(main())
diff --git a/tests/simult.py b/tests/simult.py
deleted file mode 100644
index 49d3e4b..0000000
--- a/tests/simult.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import asyncio
-
-
-async def count():
- print("before")
- await asyncio.sleep(3)
- print("after")
-
-
-async def main():
- await asyncio.gather(count(), count(), count())
- i = 0
- while i < 3000000:
- i += 1
- print("done")
-
-asyncio.run(main())
diff --git a/tests/successive_sleep.py b/tests/successive_sleep.py
deleted file mode 100644
index fc9df70..0000000
--- a/tests/successive_sleep.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import time
-
-
-def slow():
- time.sleep(0.4)
-
-
-def main():
- for i in range(3):
- time.sleep(0.2)
- slow()
-
-
-if __name__ == "__main__":
- main()