Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 17 additions & 31 deletions mypyc/doc/differences_from_python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -293,40 +293,26 @@ attribute tends to be faster than a plain global variable in compiled code::
Free threading
--------------

Mypyc supports free threading, but it doesn't provide the exact
memory safety guarantees as Python in compiled modules under
free threading when there are race conditions.

Additionally, optimized primitive operations in compiled code may have
different atomicity properties compared to CPython. Use explicit
synchronization if code depends on operations being atomic. This is
already the recommended approach for normal Python code.

Currently, compiled code must ensure that proper synchronization is
used to prevent data races involving non-final attributes in native
classes, unless the attribute has a value type such as ``bool``,
``float`` or ``i64``. You can use explicit
synchronization, such as via
:ref:`librt.threading.Lock <librt-threading-lock>` (or
:py:class:`threading.Lock`, which is less efficient than
``librt.threading.Lock``) if there is a possibility of such a data
race.
Mypyc supports free threading. However, optimized primitive operations in
compiled code may have different atomicity properties compared to CPython.
Use explicit synchronization if code depends on operations being atomic and
race conditions are possible. This is already the recommended approach for
normal Python code. You can often use :ref:`librt.threading.Lock <librt-threading-lock>`
(or :py:class:`threading.Lock`, which is less efficient than
``librt.threading.Lock``) to fix data races.

Since mypyc 2.3, the vast majority of operations are memory safe even if
there are race conditions (unlike earlier mypyc releases). This includes
list operations and access to native instance attributes (except for
a few less common use cases that will be fixed in future releases).

.. note::

We are working on improving memory safety in free-threading
builds of Python, and hope to make all normal Python features
memory safe, while providing more efficient but less safe
opt-in, non-standard features.

As libraries often won't be able to control the concurrent access by
user code, we recommend that modules document that multi-threaded
access is only supported via public interfaces that ensure correct
synchronization. Marking attributes as internal using an underscore
attribute prefix is another possibility, but this is not enforced at
runtime. Another option is to document that multithreaded access is
not supported, or that particular objects should not be used from
multiple threads concurrently.
Operations that aren't safe under race conditions in interpreted CPython
are not expected to be memory safe in compiled code either.
Some :ref:`librt <librt>` features are heavily optimized for performance and
don't guarantee memory safety when there are race conditions
(notably the :ref:`vec <librt-vecs>` type).

It's always safe to perform read-only operations concurrently. Using
objects with final attributes and tuple objects can help prevent
Expand Down
16 changes: 12 additions & 4 deletions mypyc/doc/librt_vecs.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _librt-vecs:

librt.vecs
==========

Expand Down Expand Up @@ -198,15 +200,21 @@ with no unnecessary temporary objects.
Thread safety
-------------

The ``vec`` type is heavily optimized for performance, and this means that ``vec``
gives fewer thread safety guarantees than built-in types such as ``list``.
``vec`` is a lower-level type where implicit synchronization would have a very
significant performance cost. However, since vec lengths are immutable, some race
conditions that lists can be susceptible to are not possible with vecs.

In free-threaded Python builds, it's unsafe to write or modify an item if other
threads might be concurrently accessing *the same item*. For example, writing ``v[4]``
is not safe to do if another thread might be reading ``v[4]``. Similarly, two
threads concurrently calling ``append`` or ``remove`` on the same vec object is not safe.

This is different from list objects, since vec is a lower-level type where implicit
synchronization would have a significant performance cost. However, since vec lengths
are immutable, some race conditions that lists can be susceptible to are not possible
with vecs.
Similarly, assigning to an instance attribute of a native class with a ``vec`` type
is unsafe if another thread might be accessing the same attribute concurrently
(in a free-threaded Python build only). Using ``Final`` attributes is a way
to prevent this race condition, since ``Final`` attributes cannot be rebound.

Implementation details
----------------------
Expand Down
Loading