GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — cpython/Python/pystate.c at main · python/cpython Expand file tree/ Copy pathpystate.cMore file actions 3807 lines (3252 loc) · 112 KB / Copy pathpystate.cFile metadata and controls3807 lines (3252 loc) · 112 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 /* Thread and interpreter state structures and their interfaces */ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_audit.h" // _Py_AuditHookEntry #include "pycore_backoff.h" // JUMP_BACKWARD_INITIAL_VALUE, SIDE_EXIT_INITIAL_VALUE #include "pycore_ceval.h" // _PyEval_AcquireLock() #include "pycore_codecs.h" // _PyCodec_Fini() #include "pycore_critical_section.h" // _PyCriticalSection_Resume() #include "pycore_dtoa.h" // _dtoa_state_INIT() #include "pycore_freelist.h" // _PyObject_ClearFreeLists() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_interpframe.h" // _PyThreadState_HasStackSpace() #include "pycore_object.h" // _Py_ClearImmortal() #include "pycore_obmalloc.h" // _PyMem_obmalloc_state_on_heap() #include "pycore_opcode_utils.h" // NUM_COMMON_CONSTANTS #include "pycore_optimizer.h" // JIT_CLEANUP_THRESHOLD #include "pycore_parking_lot.h" // _PyParkingLot_AfterFork() #include "pycore_pyerrors.h" // _PyErr_Clear() #include "pycore_pylifecycle.h" // _PyAST_Fini() #include "pycore_pymem.h" // _PyMem_DebugEnabled() #include "pycore_runtime.h" // _PyRuntime #include "pycore_runtime_init.h" // _PyRuntimeState_INIT #include "pycore_stackref.h" // PyStackRef_AsPyObjectBorrow() #include "pycore_stats.h" // FT_STAT_WORLD_STOP_INC() #include "pycore_time.h" // _PyTime_Init() #include "pycore_uniqueid.h" // _PyObject_FinalizePerThreadRefcounts() /* -------------------------------------------------------------------------- CAUTION Always use PyMem_RawMalloc() and PyMem_RawFree() directly in this file. A number of these functions are advertised as safe to call when the GIL isn't held, and in a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's debugging obmalloc functions. Those aren't thread-safe (they rely on the GIL to avoid the expense of doing their own locking). -------------------------------------------------------------------------- */ #ifdef HAVE_DLOPEN # ifdef HAVE_DLFCN_H # include <dlfcn.h> # endif # if !HAVE_DECL_RTLD_LAZY # define RTLD_LAZY 1 # endif #endif /****************************************/ /* helpers for the current thread state */ /****************************************/ // API for the current thread state is further down. /* "current" means one of: - bound to the current OS thread - holds the GIL */ //------------------------------------------------- // a highly efficient lookup for the current thread //------------------------------------------------- /* The stored thread state is set by PyThreadState_Swap(). For each of these functions, the GIL must be held by the current thread. */ /* The attached thread state for the current thread. */ _Py_thread_local PyThreadState *_Py_tss_tstate = NULL; /* The "bound" thread state used by PyGILState_Ensure(), also known as a "gilstate." */ _Py_thread_local PyThreadState *_Py_tss_gilstate = NULL; /* The interpreter of the attached thread state, and is same as tstate->interp. */ _Py_thread_local PyInterpreterState *_Py_tss_interp = NULL; static inline PyThreadState * current_fast_get(void) { return _Py_tss_tstate; } static inline void current_fast_set(_PyRuntimeState *Py_UNUSED(runtime), PyThreadState *tstate) { assert(tstate != NULL); _Py_tss_tstate = tstate; assert(tstate->interp != NULL); _Py_tss_interp = tstate->interp; } static inline void current_fast_clear(_PyRuntimeState *Py_UNUSED(runtime)) { _Py_tss_tstate = NULL; _Py_tss_interp = NULL; } #define tstate_verify_not_active(tstate) \ if (tstate == current_fast_get()) { \ _Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate); \ } PyThreadState * _PyThreadState_GetCurrent(void) { return current_fast_get(); } //--------------------------------------------- // The thread state used by PyGILState_Ensure() //--------------------------------------------- /* The stored thread state is set by bind_tstate() (AKA PyThreadState_Bind(). The GIL does no need to be held for these. */ static inline PyThreadState * gilstate_get(void) { return _Py_tss_gilstate; } static inline void gilstate_set(PyThreadState *tstate) { assert(tstate != NULL); _Py_tss_gilstate = tstate; } static inline void gilstate_clear(void) { _Py_tss_gilstate = NULL; } #ifndef NDEBUG static inline int tstate_is_alive(PyThreadState *tstate); static inline int tstate_is_bound(PyThreadState *tstate) { return tstate->_status.bound && !tstate->_status.unbound; } #endif // !NDEBUG static void bind_gilstate_tstate(PyThreadState *); static void unbind_gilstate_tstate(PyThreadState *); static void tstate_mimalloc_bind(PyThreadState *); static void bind_tstate(PyThreadState *tstate) { assert(tstate != NULL); assert(tstate_is_alive(tstate) && !tstate->_status.bound); assert(!tstate->_status.unbound); // just in case assert(!tstate->_status.bound_gilstate); assert(tstate != gilstate_get()); assert(!tstate->_status.active); assert(tstate->thread_id == 0); assert(tstate->native_thread_id == 0); // Currently we don't necessarily store the thread state // in thread-local storage (e.g. per-interpreter). tstate->thread_id = PyThread_get_thread_ident(); #ifdef PY_HAVE_THREAD_NATIVE_ID tstate->native_thread_id = PyThread_get_thread_native_id(); #endif #ifdef Py_GIL_DISABLED // Initialize biased reference counting inter-thread queue. Note that this // needs to be initialized from the active thread. _Py_brc_init_thread(tstate); #endif // mimalloc state needs to be initialized from the active thread. tstate_mimalloc_bind(tstate); tstate->_status.bound = 1; } static void unbind_tstate(PyThreadState *tstate) { assert(tstate != NULL); assert(tstate_is_bound(tstate)); #ifndef HAVE_PTHREAD_STUBS assert(tstate->thread_id > 0); #endif #ifdef PY_HAVE_THREAD_NATIVE_ID assert(tstate->native_thread_id > 0); #endif // We leave thread_id and native_thread_id alone // since they can be useful for debugging. // Check the `_status` field to know if these values // are still valid. // We leave tstate->_status.bound set to 1 // to indicate it was previously bound. tstate->_status.unbound = 1; } /* Stick the thread state for this thread in thread specific storage. When a thread state is created for a thread by some mechanism other than PyGILState_Ensure(), it's important that the GILState machinery knows about it so it doesn't try to create another thread state for the thread. (This is a better fix for SF bug #1010677 than the first one attempted.) The only situation where you can legitimately have more than one thread state for an OS level thread is when there are multiple interpreters. Before 3.12, the PyGILState_*() APIs didn't work with multiple interpreters (see bpo-10915 and bpo-15751), so this function used to set TSS only once. Thus, the first thread state created for that given OS level thread would "win", which seemed reasonable behaviour. */ static void bind_gilstate_tstate(PyThreadState *tstate) { assert(tstate != NULL); assert(tstate_is_alive(tstate)); assert(tstate_is_bound(tstate)); // XXX assert(!tstate->_status.active); assert(!tstate->_status.bound_gilstate); PyThreadState *tcur = gilstate_get(); assert(tstate != tcur); if (tcur != NULL) { tcur->_status.bound_gilstate = 0; } gilstate_set(tstate); tstate->_status.bound_gilstate = 1; } static void unbind_gilstate_tstate(PyThreadState *tstate) { assert(tstate != NULL); // XXX assert(tstate_is_alive(tstate)); assert(tstate_is_bound(tstate)); // XXX assert(!tstate->_status.active); assert(tstate->_status.bound_gilstate); assert(tstate == gilstate_get()); gilstate_clear(); tstate->_status.bound_gilstate = 0; } //---------------------------------------------- // the thread state that currently holds the GIL //---------------------------------------------- /* This is not exported, as it is not reliable! It can only ever be compared to the state for the *current* thread. * If not equal, then it doesn't matter that the actual value may change immediately after comparison, as it can't possibly change to the current thread's state. * If equal, then the current thread holds the lock, so the value can't change until we yield the lock. */ static int holds_gil(PyThreadState *tstate) { // XXX Fall back to tstate->interp->runtime->ceval.gil.last_holder // (and tstate->interp->runtime->ceval.gil.locked). assert(tstate != NULL); /* Must be the tstate for this thread */ assert(tstate == gilstate_get()); return tstate == current_fast_get(); } /****************************/ /* the global runtime state */ /****************************/ //---------- // lifecycle //---------- /* Suppress deprecation warning for PyBytesObject.ob_shash */ _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS /* We use "initial" if the runtime gets re-used (e.g. Py_Finalize() followed by Py_Initialize(). Note that we initialize "initial" relative to _PyRuntime, to ensure pre-initialized pointers point to the active runtime state (and not "initial"). */ static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime, ""); _Py_COMP_DIAG_POP /* Remote profilers access interpreter and thread states without synchronizing with their lifetime. Until the runtime is finalized, keep deleted states in per-type free lists, so that a stale access only reaches a state of the same type. */ typedef struct state_header { struct state_header *next; // Next entry in the free list void *mem; // Block to free at finalization } state_header; static struct { PyMutex mutex; state_header *tstates; state_header *interpreters; } state_freelists; #define LOCKS_INIT(runtime) \ { \ &(runtime)->interpreters.mutex, \ &state_freelists.mutex, \ &(runtime)->xi.data_lookup.registry.mutex, \ &(runtime)->unicode_state.ids.mutex, \ &(runtime)->imports.extensions.mutex, \ &(runtime)->ceval.pending_mainthread.mutex, \ &(runtime)->atexit.mutex, \ &(runtime)->audit_hooks.mutex, \ &(runtime)->allocators.mutex, \ &(runtime)->_main_interpreter.types.mutex, \ &(runtime)->_main_interpreter.code_state.mutex, \ &(runtime)->_main_interpreter.dict_state.watcher_mutex, \ } static void init_runtime(_PyRuntimeState *runtime, void *open_code_hook, void *open_code_userdata, _Py_AuditHookEntry *audit_hook_head, Py_ssize_t unicode_next_index) { assert(!runtime->preinitializing); assert(!runtime->preinitialized); assert(!_PyRuntimeState_GetCoreInitialized(runtime)); assert(!_PyRuntimeState_GetInitialized(runtime)); assert(!runtime->_initialized); runtime->open_code_hook = open_code_hook; runtime->open_code_userdata = open_code_userdata; runtime->audit_hooks.head = audit_hook_head; PyPreConfig_InitPythonConfig(&runtime->preconfig); // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); runtime->unicode_state.ids.next_index = unicode_next_index; runtime->_initialized = 1; } PyStatus _PyRuntimeState_Init(_PyRuntimeState *runtime) { /* We preserve the hook across init, because there is currently no public API to set it between runtime initialization and interpreter initialization. */ void *open_code_hook = runtime->open_code_hook; void *open_code_userdata = runtime->open_code_userdata; _Py_AuditHookEntry *audit_hook_head = runtime->audit_hooks.head; // bpo-42882: Preserve next_index value if Py_Initialize()/Py_Finalize() // is called multiple times. Py_ssize_t unicode_next_index = runtime->unicode_state.ids.next_index; if (runtime->_initialized) { // Py_Initialize() must be running again. // Reset to _PyRuntimeState_INIT. memcpy(runtime, &initial, sizeof(*runtime)); // Preserve the cookie from the original runtime. memcpy(runtime->debug_offsets.cookie, _Py_Debug_Cookie, 8); assert(!runtime->_initialized); } PyStatus status = _PyTime_Init(&runtime->time); if (_PyStatus_EXCEPTION(status)) { return status; } init_runtime(runtime, open_code_hook, open_code_userdata, audit_hook_head, unicode_next_index); return _PyStatus_OK(); } void _PyRuntimeState_Fini(_PyRuntimeState *runtime) { #ifdef Py_REF_DEBUG /* The count is cleared by _Py_FinalizeRefTotal(). */ assert(runtime->object_state.interpreter_leaks == 0); #endif gilstate_clear(); state_header **lists[] = {&state_freelists.tstates, &state_freelists.interpreters}; for (size_t i = 0; i < Py_ARRAY_LENGTH(lists); i++) { PyMutex_LockFlags(&state_freelists.mutex, _Py_LOCK_DONT_DETACH); state_header *entry = *lists[i]; *lists[i] = NULL; PyMutex_Unlock(&state_freelists.mutex); while (entry != NULL) { state_header *next = entry->next; PyMem_RawFree(entry->mem); entry = next; } } } #ifdef HAVE_FORK /* This function is called from PyOS_AfterFork_Child to ensure that newly created child processes do not share locks with the parent. */ PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) { // This was initially set in _PyRuntimeState_Init(). runtime->main_thread = PyThread_get_thread_ident(); // Clears the parking lot. Any waiting threads are dead. This must be // called before releasing any locks that use the parking lot. _PyParkingLot_AfterFork(); // Re-initialize global locks PyMutex *locks[] = LOCKS_INIT(runtime); for (size_t i = 0; i < Py_ARRAY_LENGTH(locks); i++) { _PyMutex_at_fork_reinit(locks[i]); } #ifdef Py_GIL_DISABLED for (PyInterpreterState *interp = runtime->interpreters.head; interp != NULL; interp = interp->next) { for (int i = 0; i < NUM_WEAKREF_LIST_LOCKS; i++) { _PyMutex_at_fork_reinit(&interp->weakref_locks[i]); } } #endif _PyThread_AfterFork(&runtime->threads); return _PyStatus_OK(); } #endif /*************************************/ /* the per-interpreter runtime state */ /*************************************/ //---------- // lifecycle //---------- /* Calling this indicates that the runtime is ready to create interpreters. */ PyStatus _PyInterpreterState_Enable(_PyRuntimeState *runtime) { struct pyinterpreters *interpreters = &runtime->interpreters; interpreters->next_id = 0; return _PyStatus_OK(); } static void * alloc_state(state_header **freelist, size_t size, size_t alignment) { PyMutex_LockFlags(&state_freelists.mutex, _Py_LOCK_DONT_DETACH); state_header *entry = *freelist; if (entry != NULL) { *freelist = entry->next; } PyMutex_Unlock(&state_freelists.mutex); if (entry != NULL) { return entry + 1; } size_t allocsize = size + sizeof(state_header) + alignment - 1; void *mem = PyMem_RawCalloc(1, allocsize); if (mem == NULL) { return NULL; } void *ptr = _Py_ALIGN_UP((char *)mem + sizeof(state_header), alignment); ((state_header *)ptr - 1)->mem = mem; assert(_Py_IS_ALIGNED(ptr, alignment)); return ptr; } static void recycle_state(state_header **freelist, void *state, size_t size) { memset(state, 0, size); state_header *entry = (state_header *)state - 1; PyMutex_LockFlags(&state_freelists.mutex, _Py_LOCK_DONT_DETACH); entry->next = *freelist; // Keep the list consistent for a child forked by another thread. _Py_atomic_store_ptr_release(freelist, entry); PyMutex_Unlock(&state_freelists.mutex); } static PyInterpreterState * alloc_interpreter(void) { return alloc_state(&state_freelists.interpreters, sizeof(PyInterpreterState), _Alignof(PyInterpreterState)); } static void free_interpreter(PyInterpreterState *interp) { #ifdef Py_GIL_DISABLED mi_subproc_t *subproc = interp->mimalloc.subproc; if (subproc != NULL) { // Delete the sub-process only when no abandoned segment points to it. if (mi_atomic_load_relaxed(&subproc->abandoned_count) == 0) { mi_subproc_delete(subproc); } interp->mimalloc.subproc = NULL; } #endif #ifdef Py_STATS if (interp->pystats_struct) { PyMem_RawFree(interp->pystats_struct); interp->pystats_struct = NULL; } #endif // The main interpreter is statically allocated so // should not be freed. if (interp != &_PyRuntime._main_interpreter) { if (_PyMem_obmalloc_state_on_heap(interp)) { // interpreter has its own obmalloc state, free it PyMem_RawFree(interp->obmalloc); interp->obmalloc = NULL; } assert(_Py_IS_ALIGNED(interp, _Alignof(PyInterpreterState))); // A daemon thread may still own the embedded initial thread state. if (interp->_initialized && _Py_atomic_load_ptr(&interp->threads.preallocated) == NULL) { return; } recycle_state(&state_freelists.interpreters, interp, sizeof(*interp)); } } #ifndef NDEBUG static inline int check_interpreter_whence(long); #endif /* Get the interpreter state to a minimal consistent state. Further init happens in pylifecycle.c before it can be used. All fields not initialized here are expected to be zeroed out, e.g. by PyMem_RawCalloc() or memset(), or otherwise pre-initialized. The runtime state is not manipulated. Instead it is assumed that the interpreter is getting added to the runtime. Note that the main interpreter was statically initialized as part of the runtime and most state is already set properly. That leaves a small number of fields to initialize dynamically, as well as some that are initialized lazily. For subinterpreters we memcpy() the main interpreter in PyInterpreterState_New(), leaving it in the same mostly-initialized state. The only difference is that the interpreter has some self-referential state that is statically initializexd to the main interpreter. We fix those fields here, in addition to the other dynamically initialized fields. */ static inline bool is_env_enabled(const char *env_name) { char *env = Py_GETENV(env_name); return env && *env != '\0' && *env != '0'; } static inline bool is_env_disabled(const char *env_name) { char *env = Py_GETENV(env_name); return env != NULL && *env == '0'; } static inline void init_policy(uint16_t *target, const char *env_name, uint16_t default_value, long min_value, long max_value) { *target = default_value; char *env = Py_GETENV(env_name); if (env && *env != '\0') { long value = atol(env); if (value >= min_value && value <= max_value) { *target = (uint16_t)value; } } } static PyStatus init_interpreter(PyInterpreterState *interp, _PyRuntimeState *runtime, int64_t id, PyInterpreterState *next, long whence) { if (interp->_initialized) { return _PyStatus_ERR("interpreter already initialized"); } assert(interp->_whence == _PyInterpreterState_WHENCE_NOTSET); assert(check_interpreter_whence(whence) == 0); interp->_whence = whence; assert(runtime != NULL); interp->runtime = runtime; assert(id > 0 || (id == 0 && interp == runtime->interpreters.main)); interp->id = id; interp->id_refcount = 0; assert(runtime->interpreters.head == interp); assert(next != NULL || (interp == runtime->interpreters.main)); interp->next = next; interp->threads.preallocated = &interp->_initial_thread; // We would call _PyObject_InitState() at this point // if interp->feature_flags were alredy set. _PyEval_InitState(interp); _PyGC_InitState(&interp->gc); PyConfig_InitPythonConfig(&interp->config); #ifdef Py_GIL_DISABLED _Py_brc_init_state(interp); interp->mimalloc.subproc = mi_subproc_new(); if (interp->mimalloc.subproc == NULL) { return _PyStatus_NO_MEMORY(); } #endif llist_init(&interp->mem_free_queue.head); llist_init(&interp->asyncio_tasks_head); interp->asyncio_tasks_lock = (PyMutex){0}; for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) { interp->monitors.tools[i] = 0; } for (int t = 0; t < PY_MONITORING_TOOL_IDS; t++) { for (int e = 0; e < _PY_MONITORING_EVENTS; e++) { interp->monitoring_callables[t][e] = NULL; } interp->monitoring_tool_versions[t] = 0; } interp->_code_object_generation = 0; interp->jit = false; interp->compiling = false; interp->executor_blooms = NULL; interp->executor_ptrs = NULL; interp->executor_count = 0; interp->executor_capacity = 0; interp->executor_deletion_list_head = NULL; interp->executor_creation_counter = JIT_CLEANUP_THRESHOLD; // Initialize optimization configuration from environment variables // PYTHON_JIT_STRESS sets aggressive defaults for testing, but can be overridden uint16_t jump_default = JUMP_BACKWARD_INITIAL_VALUE; uint16_t resume_default = RESUME_INITIAL_VALUE; uint16_t side_exit_default = SIDE_EXIT_INITIAL_VALUE; if (is_env_enabled("PYTHON_JIT_STRESS")) { jump_default = 63; side_exit_default = 63; resume_default = 127; } init_policy(&interp->opt_config.jump_backward_initial_value, "PYTHON_JIT_JUMP_BACKWARD_INITIAL_VALUE", jump_default, 1, MAX_VALUE); init_policy(&interp->opt_config.jump_backward_initial_backoff, "PYTHON_JIT_JUMP_BACKWARD_INITIAL_BACKOFF", JUMP_BACKWARD_INITIAL_BACKOFF, 0, MAX_BACKOFF); init_policy(&interp->opt_config.resume_initial_value, "PYTHON_JIT_RESUME_INITIAL_VALUE", resume_default, 1, MAX_VALUE); init_policy(&interp->opt_config.resume_initial_backoff, "PYTHON_JIT_RESUME_INITIAL_BACKOFF", RESUME_INITIAL_BACKOFF, 0, MAX_BACKOFF); init_policy(&interp->opt_config.side_exit_initial_value, "PYTHON_JIT_SIDE_EXIT_INITIAL_VALUE", side_exit_default, 1, MAX_VALUE); init_policy(&interp->opt_config.side_exit_initial_backoff, "PYTHON_JIT_SIDE_EXIT_INITIAL_BACKOFF", SIDE_EXIT_INITIAL_BACKOFF, 0, MAX_BACKOFF); // Trace fitness configuration init_policy(&interp->opt_config.fitness_initial, "PYTHON_JIT_FITNESS_INITIAL", FITNESS_INITIAL, EXIT_QUALITY_CLOSE_LOOP, FITNESS_INITIAL); interp->opt_config.specialization_enabled = !is_env_enabled("PYTHON_SPECIALIZATION_OFF"); interp->opt_config.uops_optimize_enabled = !is_env_disabled("PYTHON_UOPS_OPTIMIZE"); if (interp != &runtime->_main_interpreter) { /* Fix the self-referential, statically initialized fields. */ interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp); } #if !defined(Py_GIL_DISABLED) && defined(Py_STACKREF_DEBUG) interp->next_stackref = INITIAL_STACKREF_INDEX; _Py_hashtable_allocator_t alloc = { .malloc = malloc, .free = free, }; interp->open_stackrefs_table = _Py_hashtable_new_full( _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct, NULL, NULL, &alloc ); if (interp->open_stackrefs_table == NULL) { return _PyStatus_NO_MEMORY(); } # ifdef Py_STACKREF_CLOSE_DEBUG interp->closed_stackrefs_table = _Py_hashtable_new_full( _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct, NULL, NULL, &alloc ); if (interp->closed_stackrefs_table == NULL) { return _PyStatus_NO_MEMORY(); } # endif _Py_stackref_associate(interp, Py_None, PyStackRef_None); _Py_stackref_associate(interp, Py_False, PyStackRef_False); _Py_stackref_associate(interp, Py_True, PyStackRef_True); #endif interp->_initialized = 1; return _PyStatus_OK(); } PyStatus _PyInterpreterState_New(PyThreadState *tstate, PyInterpreterState **pinterp) { *pinterp = NULL; // Don't get runtime from tstate since tstate can be NULL _PyRuntimeState *runtime = &_PyRuntime; // tstate is NULL when pycore_create_interpreter() calls // _PyInterpreterState_New() to create the main interpreter. if (tstate != NULL) { if (_PySys_Audit(tstate, "cpython.PyInterpreterState_New", NULL) < 0) { return _PyStatus_ERR("sys.audit failed"); } } /* We completely serialize creation of multiple interpreters, since it simplifies things here and blocking concurrent calls isn't a problem. Regardless, we must fully block subinterpreter creation until after the main interpreter is created. */ HEAD_LOCK(runtime); struct pyinterpreters *interpreters = &runtime->interpreters; int64_t id = interpreters->next_id; interpreters->next_id += 1; // Allocate the interpreter and add it to the runtime state. PyInterpreterState *interp; PyStatus status; PyInterpreterState *old_head = interpreters->head; if (old_head == NULL) { // We are creating the main interpreter. assert(interpreters->main == NULL); assert(id == 0); interp = &runtime->_main_interpreter; assert(interp->id == 0); assert(interp->next == NULL); interpreters->main = interp; } else { assert(interpreters->main != NULL); assert(id != 0); interp = alloc_interpreter(); if (interp == NULL) { status = _PyStatus_NO_MEMORY(); goto error; } // Set to _PyInterpreterState_INIT. memcpy(interp, &initial._main_interpreter, sizeof(*interp)); if (id < 0) { /* overflow or Py_Initialize() not called yet! */ status = _PyStatus_ERR("failed to get an interpreter ID"); goto error; } } interpreters->head = interp; long whence = _PyInterpreterState_WHENCE_UNKNOWN; status = init_interpreter(interp, runtime, id, old_head, whence); if (_PyStatus_EXCEPTION(status)) { goto error; } HEAD_UNLOCK(runtime); assert(interp != NULL); *pinterp = interp; return _PyStatus_OK(); error: HEAD_UNLOCK(runtime); if (interp != NULL) { free_interpreter(interp); } return status; } PyInterpreterState * PyInterpreterState_New(void) { // tstate can be NULL PyThreadState *tstate = current_fast_get(); PyInterpreterState *interp; PyStatus status = _PyInterpreterState_New(tstate, &interp); if (_PyStatus_EXCEPTION(status)) { Py_ExitStatusException(status); } assert(interp != NULL); return interp; } #if !defined(Py_GIL_DISABLED) && defined(Py_STACKREF_DEBUG) extern void _Py_stackref_report_leaks(PyInterpreterState *interp); #endif static int common_const_is_initialized(_PyStackRef ref) { #if !defined(Py_GIL_DISABLED) && defined(Py_STACKREF_DEBUG) return !PyStackRef_IsNull(ref); #else return ref.bits != 0 && !PyStackRef_IsNull(ref); #endif } static void common_constants_clear(PyInterpreterState *interp) { for (int i = 0; i < NUM_COMMON_CONSTANTS; i++) { _PyStackRef ref = interp->common_consts[i]; if (!common_const_is_initialized(ref)) { continue; } PyObject *obj = PyStackRef_AsPyObjectBorrow(ref); PyStackRef_XCLOSE(ref); interp->common_consts[i] = PyStackRef_NULL; // Refcount reclamation skips heap immortals; release manually. if (_Py_IsImmortal(obj) && !_Py_IsStaticImmortal(obj)) { _Py_ClearImmortal(obj); } } } static void interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) { assert(interp != NULL); assert(tstate != NULL); _PyRuntimeState *runtime = interp->runtime; /* XXX Conditions we need to enforce: * the GIL must be held by the current thread * tstate must be the "current" thread state (current_fast_get()) * tstate->interp must be interp * for the main interpreter, tstate must be the main thread */ // XXX Ideally, we would not rely on any thread state in this function // (and we would drop the "tstate" argument). if (_PySys_Audit(tstate, "cpython.PyInterpreterState_Clear", NULL) < 0) { _PyErr_Clear(tstate); } // Clear the current/main thread state last. _Py_FOR_EACH_TSTATE_BEGIN(interp, p) { // See https://github.com/python/cpython/issues/102126 // Must be called without HEAD_LOCK held as it can deadlock // if any finalizer tries to acquire that lock. HEAD_UNLOCK(runtime); PyThreadState_Clear(p); HEAD_LOCK(runtime); } _Py_FOR_EACH_TSTATE_END(interp); if (tstate->interp == interp) { /* We fix tstate->_status below when we for sure aren't using it (e.g. no longer need the GIL). */ // XXX Eliminate the need to do this. tstate->_status.cleared = 0; } /* It is possible that any of the objects below have a finalizer that runs Python code or otherwise relies on a thread state or even the interpreter state. For now we trust that isn't a problem. */ // XXX Make sure we properly deal with problematic finalizers. Py_CLEAR(interp->audit_hooks); // gh-140257: Threads have already been cleared, but daemon threads may // still access eval_breaker atomically via take_gil() right before they // hang. Use an atomic store to prevent data races during finalization. interp->ceval.instrumentation_version = 0; _Py_atomic_store_uintptr(&tstate->eval_breaker, 0); for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) { interp->monitors.tools[i] = 0; } for (int t = 0; t < PY_MONITORING_TOOL_IDS; t++) { for (int e = 0; e < _PY_MONITORING_EVENTS; e++) { Py_CLEAR(interp->monitoring_callables[t][e]); } } for (int t = 0; t < PY_MONITORING_TOOL_IDS; t++) { Py_CLEAR(interp->monitoring_tool_names[t]); } interp->_code_object_generation = 0; #ifdef Py_GIL_DISABLED interp->tlbc_indices.tlbc_generation = 0; #endif PyConfig_Clear(&interp->config); _PyCodec_Fini(interp); assert(interp->imports.modules == NULL); assert(interp->imports.modules_by_index == NULL); assert(interp->imports.importlib == NULL); assert(interp->imports.import_func == NULL); Py_CLEAR(interp->sysdict_copy); Py_CLEAR(interp->builtins_copy); Py_CLEAR(interp->dict); #ifdef HAVE_FORK Py_CLEAR(interp->before_forkers); Py_CLEAR(interp->after_forkers_parent); Py_CLEAR(interp->after_forkers_child); #endif #ifdef _Py_TIER2 _Py_ClearExecutorDeletionList(interp); #endif _PyAST_Fini(interp); _PyAtExit_Fini(interp); // All Python types must be destroyed before the last GC collection. Python // types create a reference cycle to themselves in their in their // PyTypeObject.tp_mro member (the tuple contains the type). /* Last garbage collection on this interpreter */ _PyGC_CollectNoFail(tstate); _PyGC_Fini(interp); // Finalize warnings after last gc so that any finalizers can // access warnings state _PyWarnings_Fini(interp); struct _PyExecutorObject *cold = interp->cold_executor; if (cold != NULL) { interp->cold_executor = NULL; assert(cold->vm_data.valid); assert(!cold->vm_data.cold); _PyExecutor_Free(cold); |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |