1 #ifndef Py_INTERNAL_CEVAL_STATE_H 2 #define Py_INTERNAL_CEVAL_STATE_H 3 #ifdef __cplusplus 4 extern "C" { 5 #endif 6 7 #ifndef Py_BUILD_CORE 8 # error "this header requires Py_BUILD_CORE define" 9 #endif 10 11 #include "pycore_lock.h" // PyMutex 12 #include "pycore_gil.h" // struct _gil_runtime_state 13 14 15 typedef int (*_Py_pending_call_func)(void *); 16 17 struct _pending_call { 18 _Py_pending_call_func func; 19 void *arg; 20 int flags; 21 }; 22 23 #define PENDINGCALLSARRAYSIZE 300 24 25 #define MAXPENDINGCALLS PENDINGCALLSARRAYSIZE 26 /* For interpreter-level pending calls, we want to avoid spending too 27 much time on pending calls in any one thread, so we apply a limit. */ 28 #if MAXPENDINGCALLS > 100 29 # define MAXPENDINGCALLSLOOP 100 30 #else 31 # define MAXPENDINGCALLSLOOP MAXPENDINGCALLS 32 #endif 33 34 /* We keep the number small to preserve as much compatibility 35 as possible with earlier versions. */ 36 #define MAXPENDINGCALLS_MAIN 32 37 /* For the main thread, we want to make sure all pending calls are 38 run at once, for the sake of prompt signal handling. This is 39 unlikely to cause any problems since there should be very few 40 pending calls for the main thread. */ 41 #define MAXPENDINGCALLSLOOP_MAIN 0 42 43 struct _pending_calls { 44 PyThreadState *handling_thread; 45 PyMutex mutex; 46 /* Request for running pending calls. */ 47 int32_t npending; 48 /* The maximum allowed number of pending calls. 49 If the queue fills up to this point then _PyEval_AddPendingCall() 50 will return _Py_ADD_PENDING_FULL. */ 51 int32_t max; 52 /* We don't want a flood of pending calls to interrupt any one thread 53 for too long, so we keep a limit on the number handled per pass. 54 A value of 0 means there is no limit (other than the maximum 55 size of the list of pending calls). */ 56 int32_t maxloop; 57 struct _pending_call calls[PENDINGCALLSARRAYSIZE]; 58 int first; 59 int next; 60 }; 61 62 63 typedef enum { 64 PERF_STATUS_FAILED = -1, // Perf trampoline is in an invalid state 65 PERF_STATUS_NO_INIT = 0, // Perf trampoline is not initialized 66 PERF_STATUS_OK = 1, // Perf trampoline is ready to be executed 67 } perf_status_t; 68 69 #ifdef PY_HAVE_PERF_TRAMPOLINE 70 struct code_arena_st; 71 72 struct trampoline_api_st { 73 void* (*init_state)(void); 74 void (*write_state)(void* state, const void *code_addr, 75 unsigned int code_size, PyCodeObject* code); 76 int (*free_state)(void* state); 77 void *state; 78 Py_ssize_t code_padding; 79 }; 80 #endif 81 82 83 struct _ceval_runtime_state { 84 struct { 85 #ifdef PY_HAVE_PERF_TRAMPOLINE 86 perf_status_t status; 87 int perf_trampoline_type; 88 Py_ssize_t extra_code_index; 89 struct code_arena_st *code_arena; 90 struct trampoline_api_st trampoline_api; 91 FILE *map_file; 92 Py_ssize_t persist_after_fork; 93 #else 94 int _not_used; 95 #endif 96 } perf; 97 /* Pending calls to be made only on the main thread. */ 98 // The signal machinery falls back on this 99 // so it must be especially stable and efficient. 100 // For example, we use a preallocated array 101 // for the list of pending calls. 102 struct _pending_calls pending_mainthread; 103 PyMutex sys_trace_profile_mutex; 104 }; 105 106 107 #ifdef PY_HAVE_PERF_TRAMPOLINE 108 # define _PyEval_RUNTIME_PERF_INIT \ 109 { \ 110 .status = PERF_STATUS_NO_INIT, \ 111 .extra_code_index = -1, \ 112 .persist_after_fork = 0, \ 113 } 114 #else 115 # define _PyEval_RUNTIME_PERF_INIT {0} 116 #endif 117 118 119 struct _ceval_state { 120 /* This variable holds the global instrumentation version. When a thread is 121 running, this value is overlaid onto PyThreadState.eval_breaker so that 122 changes in the instrumentation version will trigger the eval breaker. */ 123 uintptr_t instrumentation_version; 124 int recursion_limit; 125 struct _gil_runtime_state *gil; 126 int own_gil; 127 struct _pending_calls pending; 128 }; 129 130 131 #ifdef __cplusplus 132 } 133 #endif 134 #endif /* !Py_INTERNAL_CEVAL_STATE_H */ 135