@@ -499,42 +499,66 @@ PyEval_ThreadsInitialized(void)
499499 return _PyEval_ThreadsInitialized ();
500500}
501501
502+ static inline int
503+ current_thread_holds_gil (struct _gil_runtime_state * gil , PyThreadState * tstate )
504+ {
505+ if (((PyThreadState * )_Py_atomic_load_relaxed (& gil -> last_holder )) != tstate ) {
506+ return 0 ;
507+ }
508+ return _Py_atomic_load_relaxed (& gil -> locked );
509+ }
510+
511+ static void
512+ init_shared_gil (PyInterpreterState * interp , struct _gil_runtime_state * gil )
513+ {
514+ assert (gil_created (gil ));
515+ interp -> ceval .gil = gil ;
516+ interp -> ceval .own_gil = 0 ;
517+ }
518+
519+ static void
520+ init_own_gil (PyInterpreterState * interp , struct _gil_runtime_state * gil )
521+ {
522+ assert (!gil_created (gil ));
523+ create_gil (gil );
524+ assert (gil_created (gil ));
525+ interp -> ceval .gil = gil ;
526+ interp -> ceval .own_gil = 1 ;
527+ }
528+
502529PyStatus
503530_PyEval_InitGIL (PyThreadState * tstate , int own_gil )
504531{
505532 assert (tstate -> interp -> ceval .gil == NULL );
533+ int locked ;
506534 if (!own_gil ) {
507535 PyInterpreterState * main_interp = _PyInterpreterState_Main ();
508536 assert (tstate -> interp != main_interp );
509537 struct _gil_runtime_state * gil = main_interp -> ceval .gil ;
510- assert (gil_created (gil ));
511- tstate -> interp -> ceval .gil = gil ;
512- tstate -> interp -> ceval .own_gil = 0 ;
513- return _PyStatus_OK ();
538+ init_shared_gil (tstate -> interp , gil );
539+ locked = current_thread_holds_gil (gil , tstate );
514540 }
515-
516541 /* XXX per-interpreter GIL */
517- struct _gil_runtime_state * gil = & tstate -> interp -> runtime -> ceval .gil ;
518- if (!_Py_IsMainInterpreter (tstate -> interp )) {
542+ else if (!_Py_IsMainInterpreter (tstate -> interp )) {
519543 /* Currently, the GIL is shared by all interpreters,
520544 and only the main interpreter is responsible to create
521545 and destroy it. */
522- assert ( gil_created ( gil )) ;
523- tstate -> interp -> ceval . gil = gil ;
546+ struct _gil_runtime_state * main_gil = _PyInterpreterState_Main () -> ceval . gil ;
547+ init_shared_gil ( tstate -> interp , main_gil ) ;
524548 // XXX For now we lie.
525549 tstate -> interp -> ceval .own_gil = 1 ;
526- return _PyStatus_OK ();
550+ locked = current_thread_holds_gil (main_gil , tstate );
551+ }
552+ else {
553+ PyThread_init_thread ();
554+ // XXX per-interpreter GIL: switch to interp->_gil.
555+ init_own_gil (tstate -> interp , & tstate -> interp -> runtime -> ceval .gil );
556+ locked = 0 ;
557+ }
558+ if (!locked ) {
559+ take_gil (tstate );
527560 }
528- assert (own_gil );
529-
530- assert (!gil_created (gil ));
531561
532- PyThread_init_thread ();
533- create_gil (gil );
534- assert (gil_created (gil ));
535- tstate -> interp -> ceval .gil = gil ;
536- tstate -> interp -> ceval .own_gil = 1 ;
537- take_gil (tstate );
538562 return _PyStatus_OK ();
539563}
540564
@@ -611,9 +635,17 @@ PyEval_ReleaseLock(void)
611635 drop_gil (ceval , tstate );
612636}
613637
638+ void
639+ _PyEval_AcquireLock (PyThreadState * tstate )
640+ {
641+ _Py_EnsureTstateNotNULL (tstate );
642+ take_gil (tstate );
643+ }
644+
614645void
615646_PyEval_ReleaseLock (PyThreadState * tstate )
616647{
648+ _Py_EnsureTstateNotNULL (tstate );
617649 struct _ceval_state * ceval = & tstate -> interp -> ceval ;
618650 drop_gil (ceval , tstate );
619651}
@@ -625,7 +657,7 @@ PyEval_AcquireThread(PyThreadState *tstate)
625657
626658 take_gil (tstate );
627659
628- if (_PyThreadState_Swap ( tstate -> interp -> runtime , tstate ) != NULL ) {
660+ if (_PyThreadState_SwapNoGIL ( tstate ) != NULL ) {
629661 Py_FatalError ("non-NULL old thread state" );
630662 }
631663}
@@ -635,8 +667,7 @@ PyEval_ReleaseThread(PyThreadState *tstate)
635667{
636668 assert (is_tstate_valid (tstate ));
637669
638- _PyRuntimeState * runtime = tstate -> interp -> runtime ;
639- PyThreadState * new_tstate = _PyThreadState_Swap (runtime , NULL );
670+ PyThreadState * new_tstate = _PyThreadState_SwapNoGIL (NULL );
640671 if (new_tstate != tstate ) {
641672 Py_FatalError ("wrong thread state" );
642673 }
@@ -684,8 +715,7 @@ _PyEval_SignalAsyncExc(PyInterpreterState *interp)
684715PyThreadState *
685716PyEval_SaveThread (void )
686717{
687- _PyRuntimeState * runtime = & _PyRuntime ;
688- PyThreadState * tstate = _PyThreadState_Swap (runtime , NULL );
718+ PyThreadState * tstate = _PyThreadState_SwapNoGIL (NULL );
689719 _Py_EnsureTstateNotNULL (tstate );
690720
691721 struct _ceval_state * ceval = & tstate -> interp -> ceval ;
@@ -701,7 +731,7 @@ PyEval_RestoreThread(PyThreadState *tstate)
701731
702732 take_gil (tstate );
703733
704- _PyThreadState_Swap ( tstate -> interp -> runtime , tstate );
734+ _PyThreadState_SwapNoGIL ( tstate );
705735}
706736
707737
@@ -1005,7 +1035,7 @@ _Py_HandlePending(PyThreadState *tstate)
10051035 /* GIL drop request */
10061036 if (_Py_atomic_load_relaxed_int32 (& interp_ceval_state -> gil_drop_request )) {
10071037 /* Give another thread a chance */
1008- if (_PyThreadState_Swap ( runtime , NULL ) != tstate ) {
1038+ if (_PyThreadState_SwapNoGIL ( NULL ) != tstate ) {
10091039 Py_FatalError ("tstate mix-up" );
10101040 }
10111041 drop_gil (interp_ceval_state , tstate );
@@ -1014,7 +1044,7 @@ _Py_HandlePending(PyThreadState *tstate)
10141044
10151045 take_gil (tstate );
10161046
1017- if (_PyThreadState_Swap ( runtime , tstate ) != NULL ) {
1047+ if (_PyThreadState_SwapNoGIL ( tstate ) != NULL ) {
10181048 Py_FatalError ("orphan tstate" );
10191049 }
10201050 }
0 commit comments