Download venv/lib/python3.10/site-packages/Cython/Utility/Synchronization.c from Matt300209/eval_venv: direct link, hf CLI and curl.
- Browser
- Download file 17.1 kB
-
https://huggingface.co/Matt300209/eval_venv/resolve/main/venv/lib/python3.10/site-packages/Cython/Utility/Synchronization.c
- Command line
-
hf download hf://Matt300209/eval_venv/venv/lib/python3.10/site-packages/Cython/Utility/Synchronization.c
-
curl -L -o Synchronization.c https://huggingface.co/Matt300209/eval_venv/resolve/main/venv/lib/python3.10/site-packages/Cython/Utility/Synchronization.c
17.1 kB
| /////////// Atomics.proto ///////////// | |
| //@proto_block: utility_code_proto_before_types | |
| // using CYTHON_ATOMICS as a cdef extern bint in the Cython memoryview code | |
| // interacts badly with "import *". Therefore, define a helper function-like macro | |
| // For standard C/C++ atomics, get the headers first so we have ATOMIC_INT_LOCK_FREE | |
| // defined when we decide to use them. | |
| // C11 atomics are available and ATOMIC_INT_LOCK_FREE is definitely on | |
| // C++11 atomics are available and ATOMIC_INT_LOCK_FREE is definitely on | |
| /* gcc >= 4.1.2 */ | |
| static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { | |
| __pyx_nonatomic_int_type old = __sync_val_compare_and_swap(value, *expected, desired); | |
| int result = old == *expected; | |
| *expected = old; | |
| return result; | |
| } | |
| // the legacy gcc sync builtins don't seem to have plain "load" or "store". | |
| /* msvc */ | |
| static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { | |
| __pyx_nonatomic_int_type old = _InterlockedCompareExchange(value, desired, *expected); | |
| int result = old == *expected; | |
| *expected = old; | |
| return result; | |
| } | |
| // Microsoft says that simple reads are guaranteed to be atomic. | |
| // https://learn.microsoft.com/en-gb/windows/win32/sync/interlocked-variable-access?redirectedfrom=MSDN | |
| // The volatile cast is what CPython does. | |
| // compare/exchange is probably overkill nonsense, but plain "load" intrinsics are hard to get. | |
| /////////////////////// CriticalSections.proto ///////////////////// | |
| //@proto_block: utility_code_proto_before_types | |
| ////////////////////// PyThreadTypeLock.proto ////////// | |
| //@proto_block: utility_code_proto_before_types | |
| // This lock type always uses PyThread_type_lock. The main reason | |
| // to use it is if you are using the Limited API and want to | |
| // share locks between modules. | |
| static void __Pyx__Locks_PyThreadTypeLock_Lock(__Pyx_Locks_PyThreadTypeLock lock); /* proto */ | |
| static void __Pyx__Locks_PyThreadTypeLock_LockGil(__Pyx_Locks_PyThreadTypeLock lock); /* proto */ | |
| // CYTHON_INLINE because these may be unused | |
| static CYTHON_INLINE void __Pyx_Locks_PyThreadTypeLock_Lock(__Pyx_Locks_PyThreadTypeLock lock) { | |
| __Pyx__Locks_PyThreadTypeLock_Lock(lock); | |
| } | |
| static CYTHON_INLINE void __Pyx_Locks_PyThreadTypeLock_LockGil(__Pyx_Locks_PyThreadTypeLock lock) { | |
| __Pyx__Locks_PyThreadTypeLock_LockGil(lock); | |
| } | |
| ////////////////////// PyThreadTypeLock //////////////// | |
| static void __Pyx__Locks_PyThreadTypeLock_LockGil_spin(__Pyx_Locks_PyThreadTypeLock lock) { | |
| while (1) { | |
| int res; | |
| Py_BEGIN_ALLOW_THREADS | |
| // Don't block indefinitely. This ensures we don't deadlock (forever) on | |
| // | |
| // with nogil: | |
| // with lock: | |
| // with gil: | |
| // ... | |
| // | |
| // Arguably that's user error, but it seems better to try to help them out. | |
| res = PyThread_acquire_lock_timed(lock, CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME, 0); | |
| res = PyThread_acquire_lock(lock, WAIT_LOCK); | |
| // Wait on the GIL while holding the lock. But importantly we never do the inverse | |
| // and wait on the lock while holding the GIL. | |
| Py_END_ALLOW_THREADS | |
| if (likely(res == PY_LOCK_ACQUIRED)) { | |
| // All good - we got the lock | |
| return; | |
| } | |
| } | |
| } | |
| static CYTHON_INLINE void __Pyx__Locks_PyThreadTypeLock_LockGil(__Pyx_Locks_PyThreadTypeLock lock) { | |
| // This is possibly dubious - it makes things faster in the uncontended case, but | |
| // in the heavily-contended case it makes it more likely that one thread will dominate. | |
| if (likely(PyThread_acquire_lock_timed(lock, 0, 0) == PY_LOCK_ACQUIRED)) { | |
| // All good - we got the lock | |
| return; | |
| } | |
| __Pyx__Locks_PyThreadTypeLock_LockGil_spin(lock); | |
| } | |
| static void __Pyx__Locks_PyThreadTypeLock_Lock(__Pyx_Locks_PyThreadTypeLock lock) { | |
| int has_gil = 0; | |
| if (__PYX_LIMITED_VERSION_HEX >= 0x030d0000 || __Pyx_get_runtime_version() >= 0x030d0000) { | |
| // Swap the existing thread state to see if we had the GIL. | |
| // Requires re-acquiring the thread state if we had it, but no-op if we didn't. | |
| PyThreadState *tstate = PyThreadState_Swap(NULL); | |
| has_gil = tstate != NULL; | |
| if (has_gil) | |
| PyThreadState_Swap(tstate); | |
| } else { | |
| // We can't tell if we have the GIL. Therefore make sure we do have it | |
| // and then restore whatever state was there before. | |
| PyGILState_STATE state = PyGILState_Ensure(); | |
| __Pyx_Locks_PyThreadTypeLock_LockNogil(lock); | |
| PyGILState_Release(state); | |
| return; | |
| } | |
| has_gil = PyGILState_Check(); | |
| has_gil = _PyThreadState_UncheckedGet() != NULL; | |
| has_gil = PyThreadState_GetUnchecked() != NULL; | |
| if (has_gil) { | |
| __Pyx_Locks_PyThreadTypeLock_LockGil(lock); | |
| } else { | |
| __Pyx_Locks_PyThreadTypeLock_LockNogil(lock); | |
| } | |
| } | |
| ////////////////////// PyMutex.proto //////////////////// | |
| //@proto_block: utility_code_proto_before_types | |
| //@requires: PyThreadTypeLock | |
| // We support two implementations - a Py3.13+ version using PyMutex and | |
| // an older version using PyThread_type_lock. | |
| // In principle it'd be possible to also use things like c++ std::mutex | |
| // (in the absence of PyMutex). I've decided against this for ABI reasons. | |
| // With the Limited API There is an ABI problem - if a lock is ever | |
| // shared between two modules then they must agree on the definition, | |
| // and so Limited API sharing with regular API will disagree. | |
| // Therefore I explicitly ban Limited API modules from using | |
| // CythonLockType in a public way. However, they can use | |
| // CythonCompatibleLockType which will always be PyThread_type_lock. | |
| // Py_Mutex takes care of all GIL handling itself | |
| //////////////////////////// CythonPyMutexPublicCheck /////////////////////////////////// | |
| /* CYTHON_UNSAFE_IGNORE_PYMUTEX_ABI_COMPATIBILITY is left for an advanced user who | |
| * wants to disable this error. However, please don't complain to us when your code | |
| * breaks. Whatever you do, the Limited API version always uses the "compatible" lock | |
| * type anyway, so you're only saving yourself a few extra characters typing. | |
| */ | |
| ////////////////////////// SharedInFreeThreading.proto ////////////////// | |