| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent bab21fa commit 2ebc5ce
72 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -93,6 +93,11 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void); | |||
| 93 | 93 | PyThreadState_GET()->overflowed = 0; \ | |
| 94 | 94 | } while(0) | |
| 95 | 95 | PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); | |
| 96 | + /* XXX _Py_CheckRecursionLimit should be changed to | ||
| 97 | + _PyRuntime.ceval.check_recursion_limit. However, due to the macros | ||
| 98 | + in which it's used, _Py_CheckRecursionLimit is stuck in the stable | ||
| 99 | + ABI. It should be removed therefrom when possible. | ||
| 100 | + */ | ||
| 96 | 101 | PyAPI_DATA(int) _Py_CheckRecursionLimit; | |
| 97 | 102 | ||
| 98 | 103 | #ifdef USE_STACKCHECK | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,53 @@ | |||
| 1 | + #ifndef Py_INTERNAL_CEVAL_H | ||
| 2 | + #define Py_INTERNAL_CEVAL_H | ||
| 3 | + #ifdef __cplusplus | ||
| 4 | + extern "C" { | ||
| 5 | + #endif | ||
| 6 | + | ||
| 7 | + #include "pyatomic.h" | ||
| 8 | + #include "pythread.h" | ||
| 9 | + | ||
| 10 | + struct _pending_calls { | ||
| 11 | + unsigned long main_thread; | ||
| 12 | + PyThread_type_lock lock; | ||
| 13 | + /* Request for running pending calls. */ | ||
| 14 | + _Py_atomic_int calls_to_do; | ||
| 15 | + /* Request for looking at the `async_exc` field of the current | ||
| 16 | + thread state. | ||
| 17 | + Guarded by the GIL. */ | ||
| 18 | + int async_exc; | ||
| 19 | + #define NPENDINGCALLS 32 | ||
| 20 | + struct { | ||
| 21 | + int (*func)(void *); | ||
| 22 | + void *arg; | ||
| 23 | + } calls[NPENDINGCALLS]; | ||
| 24 | + int first; | ||
| 25 | + int last; | ||
| 26 | + }; | ||
| 27 | + | ||
| 28 | + #include "internal/gil.h" | ||
| 29 | + | ||
| 30 | + struct _ceval_runtime_state { | ||
| 31 | + int recursion_limit; | ||
| 32 | + int check_recursion_limit; | ||
| 33 | + /* Records whether tracing is on for any thread. Counts the number | ||
| 34 | + of threads for which tstate->c_tracefunc is non-NULL, so if the | ||
| 35 | + value is 0, we know we don't have to check this thread's | ||
| 36 | + c_tracefunc. This speeds up the if statement in | ||
| 37 | + PyEval_EvalFrameEx() after fast_next_opcode. */ | ||
| 38 | + int tracing_possible; | ||
| 39 | + /* This single variable consolidates all requests to break out of | ||
| 40 | + the fast path in the eval loop. */ | ||
| 41 | + _Py_atomic_int eval_breaker; | ||
| 42 | + /* Request for dropping the GIL */ | ||
| 43 | + _Py_atomic_int gil_drop_request; | ||
| 44 | + struct _pending_calls pending; | ||
| 45 | + struct _gil_runtime_state gil; | ||
| 46 | + }; | ||
| 47 | + | ||
| 48 | + PyAPI_FUNC(void) _PyEval_Initialize(struct _ceval_runtime_state *); | ||
| 49 | + | ||
| 50 | + #ifdef __cplusplus | ||
| 51 | + } | ||
| 52 | + #endif | ||
| 53 | + #endif /* !Py_INTERNAL_CEVAL_H */ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,91 @@ | |||
| 1 | + #ifndef Py_INTERNAL_CONDVAR_H | ||
| 2 | + #define Py_INTERNAL_CONDVAR_H | ||
| 3 | + | ||
| 4 | + #ifndef _POSIX_THREADS | ||
| 5 | + /* This means pthreads are not implemented in libc headers, hence the macro | ||
| 6 | + not present in unistd.h. But they still can be implemented as an external | ||
| 7 | + library (e.g. gnu pth in pthread emulation) */ | ||
| 8 | + # ifdef HAVE_PTHREAD_H | ||
| 9 | + # include <pthread.h> /* _POSIX_THREADS */ | ||
| 10 | + # endif | ||
| 11 | + #endif | ||
| 12 | + | ||
| 13 | + #ifdef _POSIX_THREADS | ||
| 14 | + /* | ||
| 15 | + * POSIX support | ||
| 16 | + */ | ||
| 17 | + #define Py_HAVE_CONDVAR | ||
| 18 | + | ||
| 19 | + #include <pthread.h> | ||
| 20 | + | ||
| 21 | + #define PyMUTEX_T pthread_mutex_t | ||
| 22 | + #define PyCOND_T pthread_cond_t | ||
| 23 | + | ||
| 24 | + #elif defined(NT_THREADS) | ||
| 25 | + /* | ||
| 26 | + * Windows (XP, 2003 server and later, as well as (hopefully) CE) support | ||
| 27 | + * | ||
| 28 | + * Emulated condition variables ones that work with XP and later, plus | ||
| 29 | + * example native support on VISTA and onwards. | ||
| 30 | + */ | ||
| 31 | + #define Py_HAVE_CONDVAR | ||
| 32 | + | ||
| 33 | + /* include windows if it hasn't been done before */ | ||
| 34 | + #define WIN32_LEAN_AND_MEAN | ||
| 35 | + #include <windows.h> | ||
| 36 | + | ||
| 37 | + /* options */ | ||
| 38 | + /* non-emulated condition variables are provided for those that want | ||
| 39 | + * to target Windows Vista. Modify this macro to enable them. | ||
| 40 | + */ | ||
| 41 | + #ifndef _PY_EMULATED_WIN_CV | ||
| 42 | + #define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */ | ||
| 43 | + #endif | ||
| 44 | + | ||
| 45 | + /* fall back to emulation if not targeting Vista */ | ||
| 46 | + #if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA | ||
| 47 | + #undef _PY_EMULATED_WIN_CV | ||
| 48 | + #define _PY_EMULATED_WIN_CV 1 | ||
| 49 | + #endif | ||
| 50 | + | ||
| 51 | + #if _PY_EMULATED_WIN_CV | ||
| 52 | + | ||
| 53 | + typedef CRITICAL_SECTION PyMUTEX_T; | ||
| 54 | + | ||
| 55 | + /* The ConditionVariable object. From XP onwards it is easily emulated | ||
| 56 | + with a Semaphore. | ||
| 57 | + Semaphores are available on Windows XP (2003 server) and later. | ||
| 58 | + We use a Semaphore rather than an auto-reset event, because although | ||
| 59 | + an auto-resent event might appear to solve the lost-wakeup bug (race | ||
| 60 | + condition between releasing the outer lock and waiting) because it | ||
| 61 | + maintains state even though a wait hasn't happened, there is still | ||
| 62 | + a lost wakeup problem if more than one thread are interrupted in the | ||
| 63 | + critical place. A semaphore solves that, because its state is | ||
| 64 | + counted, not Boolean. | ||
| 65 | + Because it is ok to signal a condition variable with no one | ||
| 66 | + waiting, we need to keep track of the number of | ||
| 67 | + waiting threads. Otherwise, the semaphore's state could rise | ||
| 68 | + without bound. This also helps reduce the number of "spurious wakeups" | ||
| 69 | + that would otherwise happen. | ||
| 70 | + */ | ||
| 71 | + | ||
| 72 | + typedef struct _PyCOND_T | ||
| 73 | + { | ||
| 74 | + HANDLE sem; | ||
| 75 | + int waiting; /* to allow PyCOND_SIGNAL to be a no-op */ | ||
| 76 | + } PyCOND_T; | ||
| 77 | + | ||
| 78 | + #else /* !_PY_EMULATED_WIN_CV */ | ||
| 79 | + | ||
| 80 | + /* Use native Win7 primitives if build target is Win7 or higher */ | ||
| 81 | + | ||
| 82 | + /* SRWLOCK is faster and better than CriticalSection */ | ||
| 83 | + typedef SRWLOCK PyMUTEX_T; | ||
| 84 | + | ||
| 85 | + typedef CONDITION_VARIABLE PyCOND_T; | ||
| 86 | + | ||
| 87 | + #endif /* _PY_EMULATED_WIN_CV */ | ||
| 88 | + | ||
| 89 | + #endif /* _POSIX_THREADS, NT_THREADS */ | ||
| 90 | + | ||
| 91 | + #endif /* Py_INTERNAL_CONDVAR_H */ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,46 @@ | |||
| 1 | + #ifndef Py_INTERNAL_GIL_H | ||
| 2 | + #define Py_INTERNAL_GIL_H | ||
| 3 | + #ifdef __cplusplus | ||
| 4 | + extern "C" { | ||
| 5 | + #endif | ||
| 6 | + | ||
| 7 | + #include "pyatomic.h" | ||
| 8 | + | ||
| 9 | + #include "internal/condvar.h" | ||
| 10 | + #ifndef Py_HAVE_CONDVAR | ||
| 11 | + #error You need either a POSIX-compatible or a Windows system! | ||
| 12 | + #endif | ||
| 13 | + | ||
| 14 | + /* Enable if you want to force the switching of threads at least | ||
| 15 | + every `interval`. */ | ||
| 16 | + #undef FORCE_SWITCHING | ||
| 17 | + #define FORCE_SWITCHING | ||
| 18 | + | ||
| 19 | + struct _gil_runtime_state { | ||
| 20 | + /* microseconds (the Python API uses seconds, though) */ | ||
| 21 | + unsigned long interval; | ||
| 22 | + /* Last PyThreadState holding / having held the GIL. This helps us | ||
| 23 | + know whether anyone else was scheduled after we dropped the GIL. */ | ||
| 24 | + _Py_atomic_address last_holder; | ||
| 25 | + /* Whether the GIL is already taken (-1 if uninitialized). This is | ||
| 26 | + atomic because it can be read without any lock taken in ceval.c. */ | ||
| 27 | + _Py_atomic_int locked; | ||
| 28 | + /* Number of GIL switches since the beginning. */ | ||
| 29 | + unsigned long switch_number; | ||
| 30 | + /* This condition variable allows one or several threads to wait | ||
| 31 | + until the GIL is released. In addition, the mutex also protects | ||
| 32 | + the above variables. */ | ||
| 33 | + PyCOND_T cond; | ||
| 34 | + PyMUTEX_T mutex; | ||
| 35 | + #ifdef FORCE_SWITCHING | ||
| 36 | + /* This condition variable helps the GIL-releasing thread wait for | ||
| 37 | + a GIL-awaiting thread to be scheduled and take the GIL. */ | ||
| 38 | + PyCOND_T switch_cond; | ||
| 39 | + PyMUTEX_T switch_mutex; | ||
| 40 | + #endif | ||
| 41 | + }; | ||
| 42 | + | ||
| 43 | + #ifdef __cplusplus | ||
| 44 | + } | ||
| 45 | + #endif | ||
| 46 | + #endif /* !Py_INTERNAL_GIL_H */ | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments