Libtimecontrol lets you control the rate at which time runs in a Linux child process. Note: This is an experimental library with some known issues (see "known issues" for details.)
Installation
$ pip install libtimecontrol
Usage
import os
import subprocess
from libtimecontrol import TimeController
controller = TimeController()
# Make time run 25x faster in child processes.
controller.set_speedup(25)
# Launch a time controlled child process.
# Due to limitations on time controlling, the watch interval and date output aren't
# affected by the time control. However watch's process time is correctly time
# controlled which can be seen by how quickly watch's printed time, seen in the top
# right corner of its output, is moving.
env = os.environ
subprocess.run(
["watch", "-n1", "date"],
env=env | controller.child_flags(),
)
How it works
We use LD_PRELOAD to override the libc time functions with custom ones that read virtual
clocks. The virtual clocks are initialized to match the system's real clocks when a
program loads. After that, the virtual clocks advance relative to the real clock by
the value of the last set_speed's speedup value, starting with a speedup of 1.
Known Issues
Noise in your stdout
Preloading the 32-bit and 64-bit time control libraries at the same time will dump "ERROR: ld.so: object '.../libtime_control32_dlsym.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored." errors to the console. These can safely be ignored, but they do add noise to your logs.
Multiple Dlsym Overrides in LD_PRELOAD
When running in the DLSYM preload mode, this library may be ignored if other libraries in your LD_PRELOAD are also performing dlsym-based overrides. If you encounter this error, try putting this library's preloads in front of any other LD_PRELOAD libraries, as I've tried to make this library correctly invoke the next dlsym in the preload chain, when there is one.
Edge Cases
There are a few cases where the time control behavior isn't quite correct. I don't plan on implementing fixes or reviewing/accepting pull requests for these, but do feel free to fork the project if you want to fix these things.
-
Per-process virtual clocks can be skewed relative to each other, since each process's virtual clock starts at the real-clock's time when a time controlled process launches. This could be fixed by storing the virtual clock in across processes in shared memory.
-
Each sleep's duration is calculated at sleep time and any calls to
set_speedupdon't update any ongoing sleep's duration. This means if you callset_speedup(.01)andsleep(1), the thread will sleep for 100 seconds, even if you callset_speedup(2)a second after thesleepcall. This could be fixed by making the sleep implementation listen for speedup changes. -
No timeout parameters in libc are affected by the time control. This means a call like
select(..., /*timeout=*/one_sec)will run with a one second timeout regardless of the set speedup. This is why for examplewatch's watch interval is unaffected by the time control, it uses a select timeout for timing itself. One could update this library so that it adjusts all of the timeouts, but it's not clear that that wouldn't affect programs' stability.
Related Projects
Libfaketime is another project that fakes a processes time. It's more mature, but isn't as focused on realtime time control.
Metadata
Release files for libtimecontrol 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| libtimecontrol-0.2.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details for libtimecontrol-0.2.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
Release files / libtimecontrol-0.2.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
| Download URL | libtimecontrol-0.2.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
|---|---|
| Size | 275.0 kB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
ed0a7c6f03735b25a8508e52183a18241b094a772ea429fdba92274f9492b399
|
|
BLAKE2b-256 checksum How to use checksums |
adbdf5c974fda19db2a08909feca401108fc1626550f61c253f2151c534a2931
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Security for libtimecontrol 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.