@@ -229,6 +229,9 @@ static void _gil_initialize(struct _gil_runtime_state *gil)
229229
230230static int gil_created (struct _gil_runtime_state * gil )
231231{
232+ if (gil == NULL ) {
233+ return 0 ;
234+ }
232235 return (_Py_atomic_load_explicit (& gil -> locked , _Py_memory_order_acquire ) >= 0 );
233236}
234237
@@ -273,10 +276,9 @@ static void recreate_gil(struct _gil_runtime_state *gil)
273276#endif
274277
275278static void
276- drop_gil (struct _ceval_runtime_state * ceval , struct _ceval_state * ceval2 ,
277- PyThreadState * tstate )
279+ drop_gil (struct _ceval_state * ceval , PyThreadState * tstate )
278280{
279- struct _gil_runtime_state * gil = & ceval -> gil ;
281+ struct _gil_runtime_state * gil = ceval -> gil ;
280282 if (!_Py_atomic_load_relaxed (& gil -> locked )) {
281283 Py_FatalError ("drop_gil: GIL is not locked" );
282284 }
@@ -296,7 +298,7 @@ drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2,
296298 MUTEX_UNLOCK (gil -> mutex );
297299
298300#ifdef FORCE_SWITCHING
299- if (_Py_atomic_load_relaxed (& ceval2 -> gil_drop_request ) && tstate != NULL ) {
301+ if (_Py_atomic_load_relaxed (& ceval -> gil_drop_request ) && tstate != NULL ) {
300302 MUTEX_LOCK (gil -> switch_mutex );
301303 /* Not switched yet => wait */
302304 if (((PyThreadState * )_Py_atomic_load_relaxed (& gil -> last_holder )) == tstate )
@@ -358,9 +360,8 @@ take_gil(PyThreadState *tstate)
358360
359361 assert (is_tstate_valid (tstate ));
360362 PyInterpreterState * interp = tstate -> interp ;
361- struct _ceval_runtime_state * ceval = & interp -> runtime -> ceval ;
362- struct _ceval_state * ceval2 = & interp -> ceval ;
363- struct _gil_runtime_state * gil = & ceval -> gil ;
363+ struct _ceval_state * ceval = & interp -> ceval ;
364+ struct _gil_runtime_state * gil = ceval -> gil ;
364365
365366 /* Check that _PyEval_InitThreads() was called to create the lock */
366367 assert (gil_created (gil ));
@@ -434,12 +435,12 @@ take_gil(PyThreadState *tstate)
434435 in take_gil() while the main thread called
435436 wait_for_thread_shutdown() from Py_Finalize(). */
436437 MUTEX_UNLOCK (gil -> mutex );
437- drop_gil (ceval , ceval2 , tstate );
438+ drop_gil (ceval , tstate );
438439 PyThread_exit_thread ();
439440 }
440441 assert (is_tstate_valid (tstate ));
441442
442- if (_Py_atomic_load_relaxed (& ceval2 -> gil_drop_request )) {
443+ if (_Py_atomic_load_relaxed (& ceval -> gil_drop_request )) {
443444 RESET_GIL_DROP_REQUEST (interp );
444445 }
445446 else {
@@ -448,7 +449,7 @@ take_gil(PyThreadState *tstate)
448449 handle signals.
449450
450451 Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */
451- COMPUTE_EVAL_BREAKER (interp , ceval , ceval2 );
452+ COMPUTE_EVAL_BREAKER (interp , & _PyRuntime . ceval , ceval );
452453 }
453454
454455 /* Don't access tstate if the thread must exit */
@@ -463,63 +464,86 @@ take_gil(PyThreadState *tstate)
463464
464465void _PyEval_SetSwitchInterval (unsigned long microseconds )
465466{
466- struct _gil_runtime_state * gil = & _PyRuntime .ceval .gil ;
467+ /* XXX per-interpreter GIL */
468+ PyInterpreterState * interp = _PyInterpreterState_Main ();
469+ struct _gil_runtime_state * gil = interp -> ceval .gil ;
470+ assert (gil != NULL );
467471 gil -> interval = microseconds ;
468472}
469473
470474unsigned long _PyEval_GetSwitchInterval (void )
471475{
472- struct _gil_runtime_state * gil = & _PyRuntime .ceval .gil ;
476+ /* XXX per-interpreter GIL */
477+ PyInterpreterState * interp = _PyInterpreterState_Main ();
478+ struct _gil_runtime_state * gil = interp -> ceval .gil ;
479+ assert (gil != NULL );
473480 return gil -> interval ;
474481}
475482
476483
477484int
478- _PyEval_ThreadsInitialized (_PyRuntimeState * runtime )
485+ _PyEval_ThreadsInitialized (void )
479486{
480- return gil_created (& runtime -> ceval .gil );
487+ /* XXX per-interpreter GIL */
488+ PyInterpreterState * interp = _PyInterpreterState_Main ();
489+ if (interp == NULL ) {
490+ return 0 ;
491+ }
492+ struct _gil_runtime_state * gil = interp -> ceval .gil ;
493+ return gil_created (gil );
481494}
482495
483496int
484497PyEval_ThreadsInitialized (void )
485498{
486- _PyRuntimeState * runtime = & _PyRuntime ;
487- return _PyEval_ThreadsInitialized (runtime );
499+ return _PyEval_ThreadsInitialized ();
488500}
489501
490502PyStatus
491503_PyEval_InitGIL (PyThreadState * tstate )
492504{
505+ assert (tstate -> interp -> ceval .gil == NULL );
506+
507+ /* XXX per-interpreter GIL */
508+ struct _gil_runtime_state * gil = & tstate -> interp -> runtime -> ceval .gil ;
493509 if (!_Py_IsMainInterpreter (tstate -> interp )) {
494510 /* Currently, the GIL is shared by all interpreters,
495511 and only the main interpreter is responsible to create
496512 and destroy it. */
513+ assert (gil_created (gil ));
514+ tstate -> interp -> ceval .gil = gil ;
497515 return _PyStatus_OK ();
498516 }
499517
500- struct _gil_runtime_state * gil = & tstate -> interp -> runtime -> ceval .gil ;
501518 assert (!gil_created (gil ));
502519
503520 PyThread_init_thread ();
504521 create_gil (gil );
505-
506- take_gil (tstate );
507-
508522 assert (gil_created (gil ));
523+ tstate -> interp -> ceval .gil = gil ;
524+ take_gil (tstate );
509525 return _PyStatus_OK ();
510526}
511527
512528void
513529_PyEval_FiniGIL (PyInterpreterState * interp )
514530{
531+ if (interp -> ceval .gil == NULL ) {
532+ /* It was already finalized (or hasn't been initialized yet). */
533+ return ;
534+ }
535+
536+ /* XXX per-interpreter GIL */
537+ struct _gil_runtime_state * gil = & interp -> runtime -> ceval .gil ;
515538 if (!_Py_IsMainInterpreter (interp )) {
516539 /* Currently, the GIL is shared by all interpreters,
517540 and only the main interpreter is responsible to create
518541 and destroy it. */
542+ assert (interp -> ceval .gil == gil );
543+ interp -> ceval .gil = NULL ;
519544 return ;
520545 }
521546
522- struct _gil_runtime_state * gil = & interp -> runtime -> ceval .gil ;
523547 if (!gil_created (gil )) {
524548 /* First Py_InitializeFromConfig() call: the GIL doesn't exist
525549 yet: do nothing. */
@@ -528,6 +552,7 @@ _PyEval_FiniGIL(PyInterpreterState *interp)
528552
529553 destroy_gil (gil );
530554 assert (!gil_created (gil ));
555+ interp -> ceval .gil = NULL ;
531556}
532557
533558void
@@ -555,22 +580,19 @@ PyEval_AcquireLock(void)
555580void
556581PyEval_ReleaseLock (void )
557582{
558- _PyRuntimeState * runtime = & _PyRuntime ;
559583 PyThreadState * tstate = _PyThreadState_GET ();
560584 /* This function must succeed when the current thread state is NULL.
561585 We therefore avoid PyThreadState_Get() which dumps a fatal error
562586 in debug mode. */
563- struct _ceval_runtime_state * ceval = & runtime -> ceval ;
564- struct _ceval_state * ceval2 = & tstate -> interp -> ceval ;
565- drop_gil (ceval , ceval2 , tstate );
587+ struct _ceval_state * ceval = & tstate -> interp -> ceval ;
588+ drop_gil (ceval , tstate );
566589}
567590
568591void
569592_PyEval_ReleaseLock (PyThreadState * tstate )
570593{
571- struct _ceval_runtime_state * ceval = & tstate -> interp -> runtime -> ceval ;
572- struct _ceval_state * ceval2 = & tstate -> interp -> ceval ;
573- drop_gil (ceval , ceval2 , tstate );
594+ struct _ceval_state * ceval = & tstate -> interp -> ceval ;
595+ drop_gil (ceval , tstate );
574596}
575597
576598void
@@ -595,9 +617,8 @@ PyEval_ReleaseThread(PyThreadState *tstate)
595617 if (new_tstate != tstate ) {
596618 Py_FatalError ("wrong thread state" );
597619 }
598- struct _ceval_runtime_state * ceval = & runtime -> ceval ;
599- struct _ceval_state * ceval2 = & tstate -> interp -> ceval ;
600- drop_gil (ceval , ceval2 , tstate );
620+ struct _ceval_state * ceval = & tstate -> interp -> ceval ;
621+ drop_gil (ceval , tstate );
601622}
602623
603624#ifdef HAVE_FORK
@@ -607,9 +628,9 @@ PyEval_ReleaseThread(PyThreadState *tstate)
607628PyStatus
608629_PyEval_ReInitThreads (PyThreadState * tstate )
609630{
610- _PyRuntimeState * runtime = tstate -> interp -> runtime ;
631+ assert ( tstate -> interp == _PyInterpreterState_Main ()) ;
611632
612- struct _gil_runtime_state * gil = & runtime -> ceval .gil ;
633+ struct _gil_runtime_state * gil = tstate -> interp -> ceval .gil ;
613634 if (!gil_created (gil )) {
614635 return _PyStatus_OK ();
615636 }
@@ -644,10 +665,9 @@ PyEval_SaveThread(void)
644665 PyThreadState * tstate = _PyThreadState_Swap (runtime , NULL );
645666 _Py_EnsureTstateNotNULL (tstate );
646667
647- struct _ceval_runtime_state * ceval = & runtime -> ceval ;
648- struct _ceval_state * ceval2 = & tstate -> interp -> ceval ;
649- assert (gil_created (& ceval -> gil ));
650- drop_gil (ceval , ceval2 , tstate );
668+ struct _ceval_state * ceval = & tstate -> interp -> ceval ;
669+ assert (gil_created (ceval -> gil ));
670+ drop_gil (ceval , tstate );
651671 return tstate ;
652672}
653673
@@ -906,6 +926,7 @@ Py_MakePendingCalls(void)
906926void
907927_PyEval_InitRuntimeState (struct _ceval_runtime_state * ceval )
908928{
929+ /* XXX per-interpreter GIL */
909930 _gil_initialize (& ceval -> gil );
910931}
911932
@@ -964,7 +985,7 @@ _Py_HandlePending(PyThreadState *tstate)
964985 if (_PyThreadState_Swap (runtime , NULL ) != tstate ) {
965986 Py_FatalError ("tstate mix-up" );
966987 }
967- drop_gil (ceval , interp_ceval_state , tstate );
988+ drop_gil (interp_ceval_state , tstate );
968989
969990 /* Other threads may run now */
970991
0 commit comments