Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-19 09:50:45

0001 #ifndef Py_INTERNAL_CEVAL_STATE_H
0002 #define Py_INTERNAL_CEVAL_STATE_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006 
0007 #ifndef Py_BUILD_CORE
0008 #  error "this header requires Py_BUILD_CORE define"
0009 #endif
0010 
0011 #include "pycore_lock.h"            // PyMutex
0012 #include "pycore_gil.h"             // struct _gil_runtime_state
0013 
0014 
0015 typedef int (*_Py_pending_call_func)(void *);
0016 
0017 struct _pending_call {
0018     _Py_pending_call_func func;
0019     void *arg;
0020     int flags;
0021 };
0022 
0023 #define PENDINGCALLSARRAYSIZE 300
0024 
0025 #define MAXPENDINGCALLS PENDINGCALLSARRAYSIZE
0026 /* For interpreter-level pending calls, we want to avoid spending too
0027    much time on pending calls in any one thread, so we apply a limit. */
0028 #if MAXPENDINGCALLS > 100
0029 #  define MAXPENDINGCALLSLOOP 100
0030 #else
0031 #  define MAXPENDINGCALLSLOOP MAXPENDINGCALLS
0032 #endif
0033 
0034 /* We keep the number small to preserve as much compatibility
0035    as possible with earlier versions. */
0036 #define MAXPENDINGCALLS_MAIN 32
0037 /* For the main thread, we want to make sure all pending calls are
0038    run at once, for the sake of prompt signal handling.  This is
0039    unlikely to cause any problems since there should be very few
0040    pending calls for the main thread. */
0041 #define MAXPENDINGCALLSLOOP_MAIN 0
0042 
0043 struct _pending_calls {
0044     PyThreadState *handling_thread;
0045     PyMutex mutex;
0046     /* Request for running pending calls. */
0047     int32_t npending;
0048     /* The maximum allowed number of pending calls.
0049        If the queue fills up to this point then _PyEval_AddPendingCall()
0050        will return _Py_ADD_PENDING_FULL. */
0051     int32_t max;
0052     /* We don't want a flood of pending calls to interrupt any one thread
0053        for too long, so we keep a limit on the number handled per pass.
0054        A value of 0 means there is no limit (other than the maximum
0055        size of the list of pending calls). */
0056     int32_t maxloop;
0057     struct _pending_call calls[PENDINGCALLSARRAYSIZE];
0058     int first;
0059     int next;
0060 };
0061 
0062 
0063 typedef enum {
0064     PERF_STATUS_FAILED = -1,  // Perf trampoline is in an invalid state
0065     PERF_STATUS_NO_INIT = 0,  // Perf trampoline is not initialized
0066     PERF_STATUS_OK = 1,       // Perf trampoline is ready to be executed
0067 } perf_status_t;
0068 
0069 #ifdef PY_HAVE_PERF_TRAMPOLINE
0070 struct code_arena_st;
0071 
0072 struct trampoline_api_st {
0073     void* (*init_state)(void);
0074     void (*write_state)(void* state, const void *code_addr,
0075                         unsigned int code_size, PyCodeObject* code);
0076     int (*free_state)(void* state);
0077     void *state;
0078     Py_ssize_t code_padding;
0079 };
0080 #endif
0081 
0082 
0083 struct _ceval_runtime_state {
0084     struct {
0085 #ifdef PY_HAVE_PERF_TRAMPOLINE
0086         perf_status_t status;
0087         int perf_trampoline_type;
0088         Py_ssize_t extra_code_index;
0089         struct code_arena_st *code_arena;
0090         struct trampoline_api_st trampoline_api;
0091         FILE *map_file;
0092         Py_ssize_t persist_after_fork;
0093 #else
0094         int _not_used;
0095 #endif
0096     } perf;
0097     /* Pending calls to be made only on the main thread. */
0098     // The signal machinery falls back on this
0099     // so it must be especially stable and efficient.
0100     // For example, we use a preallocated array
0101     // for the list of pending calls.
0102     struct _pending_calls pending_mainthread;
0103     PyMutex sys_trace_profile_mutex;
0104 };
0105 
0106 
0107 #ifdef PY_HAVE_PERF_TRAMPOLINE
0108 # define _PyEval_RUNTIME_PERF_INIT \
0109     { \
0110         .status = PERF_STATUS_NO_INIT, \
0111         .extra_code_index = -1, \
0112         .persist_after_fork = 0, \
0113     }
0114 #else
0115 # define _PyEval_RUNTIME_PERF_INIT {0}
0116 #endif
0117 
0118 
0119 struct _ceval_state {
0120     /* This variable holds the global instrumentation version. When a thread is
0121        running, this value is overlaid onto PyThreadState.eval_breaker so that
0122        changes in the instrumentation version will trigger the eval breaker. */
0123     uintptr_t instrumentation_version;
0124     int recursion_limit;
0125     struct _gil_runtime_state *gil;
0126     int own_gil;
0127     struct _pending_calls pending;
0128 };
0129 
0130 
0131 #ifdef __cplusplus
0132 }
0133 #endif
0134 #endif /* !Py_INTERNAL_CEVAL_STATE_H */