diff --git a/common/realtime.py b/common/realtime.py index dd97ea3d78..e7265406ac 100644 --- a/common/realtime.py +++ b/common/realtime.py @@ -4,7 +4,7 @@ import os 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 @@ class Ratekeeper: 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 @@ class Ratekeeper: 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 0000000000..38e5e1d498 --- /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 0000000000..7c415721f4 --- /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 acbd3209d4..06d2ff3162 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08bec056de9bb978a9b50680c699f5a604d7405d105997c0a60be522dcfc7eb5 -size 629836 +oid sha256:6181d338c8da4314745ebb305485a8c22130288f3faa9740fb1782288c06bc0b +size 614543 diff --git a/pyproject.toml b/pyproject.toml index 6e4741ddaf..7b780c87f0 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 0764ff77c3..bf92710fee 100755 --- a/scripts/waste.py +++ b/scripts/waste.py @@ -3,7 +3,7 @@ import os 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 3ac80aad91..1e33b7b3f0 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -6,7 +6,7 @@ import numpy as np 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.fill_model_msg import fill_model_msg, fill_pose_ 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 @@ class ModelState: 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("modeld") config_realtime_process(7, 54) cloudlog.warning("setting up CL context") @@ -286,7 +286,7 @@ if __name__ == "__main__": 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/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 75585e2f14..7b44a3b80e 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -36,26 +36,26 @@ PROCS = { # Baseline CPU usage by process "selfdrive.controls.controlsd": 32.0, "selfdrive.car.card": 22.0, - "./loggerd": 14.0, - "./encoderd": 17.0, - "./camerad": 14.5, - "./locationd": 11.0, + "loggerd": 14.0, + "encoderd": 17.0, + "camerad": 14.5, + "locationd": 11.0, "selfdrive.controls.plannerd": 11.0, - "./ui": 18.0, + "ui": 18.0, "selfdrive.locationd.paramsd": 9.0, - "./sensord": 7.0, + "sensord": 7.0, "selfdrive.controls.radard": 7.0, - "selfdrive.modeld.modeld": 13.0, + "modeld": 13.0, "selfdrive.modeld.dmonitoringmodeld": 8.0, "system.hardware.hardwared": 3.87, "selfdrive.locationd.calibrationd": 2.0, "selfdrive.locationd.torqued": 5.0, "selfdrive.ui.soundd": 3.5, "selfdrive.monitoring.dmonitoringd": 4.0, - "./proclogd": 1.54, + "proclogd": 1.54, "system.logmessaged": 0.2, "system.tombstoned": 0, - "./logcatd": 0, + "logcatd": 0, "system.micd": 6.0, "system.timed": 0, "selfdrive.pandad.pandad": 0, @@ -67,12 +67,12 @@ PROCS = { PROCS.update({ "tici": { - "./pandad": 4.0, - "./ubloxd": 0.02, + "pandad": 4.0, + "ubloxd": 0.02, "system.ubloxd.pigeond": 6.0, }, "tizi": { - "./pandad": 19.0, + "pandad": 19.0, "system.qcomgpsd.qcomgpsd": 1.0, } }.get(HARDWARE.get_device_type(), {})) @@ -247,8 +247,7 @@ class TestOnroad: for pl in self.service_msgs['procLog']: for x in pl.procLog.procs: if len(x.cmdline) > 0: - n = list(x.cmdline)[0] - plogs_by_proc[n].append(x) + plogs_by_proc[x.name].append(x) print(plogs_by_proc.keys()) cpu_ok = True @@ -256,8 +255,9 @@ class TestOnroad: for proc_name, expected_cpu in PROCS.items(): err = "" + exp = "???" cpu_usage = 0. - x = plogs_by_proc[proc_name] + x = plogs_by_proc[proc_name[-15:]] if len(x) > 2: cpu_time = cputime_total(x[-1]) - cputime_total(x[0]) cpu_usage = cpu_time / dt * 100. @@ -309,7 +309,7 @@ class TestOnroad: assert max(mems) - min(mems) <= 3.0 def test_gpu_usage(self): - assert self.gpu_procs == {"weston", "ui", "camerad", "selfdrive.modeld.modeld"} + assert self.gpu_procs == {"weston", "ui", "camerad", "modeld"} def test_camera_processing_time(self): result = "\n" diff --git a/system/manager/process.py b/system/manager/process.py index 36f299ae62..9214e417c1 100644 --- a/system/manager/process.py +++ b/system/manager/process.py @@ -8,7 +8,7 @@ from collections.abc import Callable, ValuesView 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()