diff --git a/common/realtime.py b/common/realtime.py index dd97ea3d787ccf..e7265406accf36 100644 --- a/common/realtime.py +++ b/common/realtime.py @@ -4,7 +4,7 @@ import time from collections import deque -from setproctitle import getproctitle +from openpilot.common.threadname import getthreadname from openpilot.system.hardware import PC @@ -52,7 +52,7 @@ def __init__(self, rate: float, print_delay_threshold: float | None = 0.0) -> No self._print_delay_threshold = print_delay_threshold self._frame = 0 self._remaining = 0.0 - self._process_name = getproctitle() + self._thread_name = getthreadname() self._dts = deque([self._interval], maxlen=100) self._last_monitor_time = time.monotonic() @@ -87,7 +87,7 @@ def monitor_time(self) -> bool: remaining = self._next_frame_time - time.monotonic() self._next_frame_time += self._interval if self._print_delay_threshold is not None and remaining < -self._print_delay_threshold: - print(f"{self._process_name} lagging by {-remaining * 1000:.2f} ms") + print(f"{self._thread_name} lagging by {-remaining * 1000:.2f} ms") lagged = True self._frame += 1 self._remaining = remaining diff --git a/common/tests/test_threadname.py b/common/tests/test_threadname.py new file mode 100644 index 00000000000000..38e5e1d498328c --- /dev/null +++ b/common/tests/test_threadname.py @@ -0,0 +1,8 @@ +from openpilot.common.threadname import setthreadname, getthreadname, LINUX + +class TestThreadName: + def test_set_get_threadname(self): + if LINUX: + name = 'TESTING' + setthreadname(name) + assert name == getthreadname() diff --git a/common/threadname.py b/common/threadname.py new file mode 100644 index 00000000000000..3db7a7d013ec54 --- /dev/null +++ b/common/threadname.py @@ -0,0 +1,19 @@ +import ctypes +import os + +LINUX = os.name == 'posix' and os.uname().sysname == 'Linux' + +if LINUX: + libc = ctypes.CDLL('libc.so.6') + +def setthreadname(name: str) -> None: + if LINUX: + name = name[:15] + '\0' + libc.prctl(15, str.encode(name), 0, 0, 0) + +def getthreadname() -> str: + if LINUX: + name = ctypes.create_string_buffer(16) + libc.prctl(16, name) + return name.value.decode('utf-8') + return "" diff --git a/poetry.lock b/poetry.lock index 8f8ba48cf9035d..37e6c78e10e730 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d9f6a97cc9f69ab14aaa50e64ee4bd0da11fa1b2fa8314d7b7ec4a380fe9e8f -size 618404 +oid sha256:e3c0ed6349feb2a75a11fab5939e40b757c735855c617b9147de3d614e0b6c50 +size 603428 diff --git a/pyproject.toml b/pyproject.toml index 007245540f8890..e1635728feda93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -137,7 +137,6 @@ future-fstrings = "*" # these should be removed psutil = "*" timezonefinder = "*" # just used for nav ETA -setproctitle = "*" pycryptodome = "*" # used in updated/casync, panda, body, and a test [tool.poetry.group.dev.dependencies] diff --git a/scripts/waste.py b/scripts/waste.py index 0764ff77c37cb6..bf92710feefe31 100755 --- a/scripts/waste.py +++ b/scripts/waste.py @@ -3,7 +3,7 @@ import time import numpy as np from multiprocessing import Process -from setproctitle import setproctitle +from openpilot.common.threadname import setthreadname def waste(core): os.sched_setaffinity(0, [core,]) @@ -16,7 +16,7 @@ def waste(core): j = 0 while 1: if (i % 100) == 0: - setproctitle("%3d: %8d" % (core, i)) + setthreadname("%3d: %8d" % (core, i)) lt = time.monotonic() print("%3d: %8d %f %.2f" % (core, i, lt-st, j)) st = lt diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 3ac80aad91110a..b037d1861fac58 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -6,7 +6,7 @@ import cereal.messaging as messaging from cereal import car, log from pathlib import Path -from setproctitle import setproctitle +from openpilot.common.threadname import setthreadname from cereal.messaging import PubMaster, SubMaster from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from openpilot.common.swaglog import cloudlog @@ -24,7 +24,7 @@ from openpilot.selfdrive.modeld.constants import ModelConstants from openpilot.selfdrive.modeld.models.commonmodel_pyx import ModelFrame, CLContext -PROCESS_NAME = "selfdrive.modeld.modeld" +THREAD_NAME = "selfdrive.modeld.modeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') MODEL_PATHS = { @@ -114,9 +114,9 @@ def run(self, buf: VisionBuf, wbuf: VisionBuf, transform: np.ndarray, transform_ def main(demo=False): cloudlog.warning("modeld init") - sentry.set_tag("daemon", PROCESS_NAME) - cloudlog.bind(daemon=PROCESS_NAME) - setproctitle(PROCESS_NAME) + sentry.set_tag("daemon", THREAD_NAME) + cloudlog.bind(daemon=THREAD_NAME) + setthreadname(THREAD_NAME) config_realtime_process(7, 54) cloudlog.warning("setting up CL context") @@ -286,7 +286,7 @@ def main(demo=False): args = parser.parse_args() main(demo=args.demo) except KeyboardInterrupt: - cloudlog.warning(f"child {PROCESS_NAME} got SIGINT") + cloudlog.warning(f"child {THREAD_NAME} got SIGINT") except Exception: sentry.capture_exception() raise diff --git a/system/manager/process.py b/system/manager/process.py index 36f299ae628b22..9214e417c1ed39 100644 --- a/system/manager/process.py +++ b/system/manager/process.py @@ -8,7 +8,7 @@ from abc import ABC, abstractmethod from multiprocessing import Process -from setproctitle import setproctitle +from openpilot.common.threadname import setthreadname from cereal import car, log import cereal.messaging as messaging @@ -27,7 +27,7 @@ def launcher(proc: str, name: str) -> None: mod = importlib.import_module(proc) # rename the process - setproctitle(proc) + setthreadname(proc) # create new context since we forked messaging.context = messaging.Context()