@@ -244,6 +244,7 @@ _Py_ClearExecutorDeletionList(PyInterpreterState *interp)
244244        ts  =  PyThreadState_Next (ts );
245245        HEAD_UNLOCK (runtime );
246246    }
247+     EXECUTOR_LIST_LOCK (interp );
247248    _PyExecutorObject  * * prev_to_next_ptr  =  & interp -> executor_deletion_list_head ;
248249    _PyExecutorObject  * exec  =  * prev_to_next_ptr ;
249250    while  (exec  !=  NULL ) {
@@ -259,12 +260,14 @@ _Py_ClearExecutorDeletionList(PyInterpreterState *interp)
259260        exec  =  * prev_to_next_ptr ;
260261    }
261262    interp -> executor_deletion_list_remaining_capacity  =  EXECUTOR_DELETE_LIST_MAX ;
263+     EXECUTOR_LIST_UNLOCK (interp );
262264}
263265
264266static  void 
265267add_to_pending_deletion_list (_PyExecutorObject  * self )
266268{
267269    PyInterpreterState  * interp  =  PyInterpreterState_Get ();
270+     EXECUTOR_LIST_LOCK (interp );
268271    self -> vm_data .links .next  =  interp -> executor_deletion_list_head ;
269272    interp -> executor_deletion_list_head  =  self ;
270273    if  (interp -> executor_deletion_list_remaining_capacity  >  0 ) {
@@ -273,6 +276,7 @@ add_to_pending_deletion_list(_PyExecutorObject *self)
273276    else  {
274277        _Py_ClearExecutorDeletionList (interp );
275278    }
279+     EXECUTOR_LIST_UNLOCK (interp );
276280}
277281
278282static  void 
@@ -1441,6 +1445,7 @@ static void
14411445link_executor (_PyExecutorObject  * executor )
14421446{
14431447    PyInterpreterState  * interp  =  _PyInterpreterState_GET ();
1448+     EXECUTOR_LIST_LOCK (interp );
14441449    _PyExecutorLinkListNode  * links  =  & executor -> vm_data .links ;
14451450    _PyExecutorObject  * head  =  interp -> executor_list_head ;
14461451    if  (head  ==  NULL ) {
@@ -1458,6 +1463,7 @@ link_executor(_PyExecutorObject *executor)
14581463    executor -> vm_data .linked  =  true;
14591464    /* executor_list_head must be first in list */ 
14601465    assert (interp -> executor_list_head -> vm_data .links .previous  ==  NULL );
1466+     EXECUTOR_LIST_UNLOCK (interp );
14611467}
14621468
14631469static  void 
@@ -1466,6 +1472,8 @@ unlink_executor(_PyExecutorObject *executor)
14661472    if  (!executor -> vm_data .linked ) {
14671473        return ;
14681474    }
1475+     PyInterpreterState  * interp  =  PyInterpreterState_Get ();
1476+     EXECUTOR_LIST_LOCK (interp );
14691477    _PyExecutorLinkListNode  * links  =  & executor -> vm_data .links ;
14701478    assert (executor -> vm_data .valid );
14711479    _PyExecutorObject  * next  =  links -> next ;
@@ -1478,11 +1486,11 @@ unlink_executor(_PyExecutorObject *executor)
14781486    }
14791487    else  {
14801488        // prev == NULL implies that executor is the list head 
1481-         PyInterpreterState  * interp  =  PyInterpreterState_Get ();
14821489        assert (interp -> executor_list_head  ==  executor );
14831490        interp -> executor_list_head  =  next ;
14841491    }
14851492    executor -> vm_data .linked  =  false;
1493+     EXECUTOR_LIST_UNLOCK (interp );
14861494}
14871495
14881496/* This must be called by optimizers before using the executor */ 
@@ -1607,16 +1615,19 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is
16071615    }
16081616    /* Clearing an executor can deallocate others, so we need to make a list of 
16091617     * executors to invalidate first */ 
1618+     EXECUTOR_LIST_LOCK (interp );
16101619    for  (_PyExecutorObject  * exec  =  interp -> executor_list_head ; exec  !=  NULL ;) {
16111620        assert (exec -> vm_data .valid );
16121621        _PyExecutorObject  * next  =  exec -> vm_data .links .next ;
16131622        if  (bloom_filter_may_contain (& exec -> vm_data .bloom , & obj_filter ) && 
16141623            PyList_Append (invalidate , (PyObject  * )exec ))
16151624        {
1625+             EXECUTOR_LIST_UNLOCK (interp );
16161626            goto error ;
16171627        }
16181628        exec  =  next ;
16191629    }
1630+     EXECUTOR_LIST_UNLOCK (interp );
16201631    for  (Py_ssize_t  i  =  0 ; i  <  PyList_GET_SIZE (invalidate ); i ++ ) {
16211632        PyObject  * exec  =  PyList_GET_ITEM (invalidate , i );
16221633        executor_clear (exec );
@@ -1637,6 +1648,7 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is
16371648void 
16381649_Py_Executors_InvalidateAll (PyInterpreterState  * interp , int  is_invalidation )
16391650{
1651+     EXECUTOR_LIST_LOCK (interp );
16401652    while  (interp -> executor_list_head ) {
16411653        _PyExecutorObject  * executor  =  interp -> executor_list_head ;
16421654        assert (executor -> vm_data .valid  ==  1  &&  executor -> vm_data .linked  ==  1 );
@@ -1651,6 +1663,7 @@ _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation)
16511663            OPT_STAT_INC (executors_invalidated );
16521664        }
16531665    }
1666+     EXECUTOR_LIST_UNLOCK (interp );
16541667}
16551668
16561669void 
@@ -1665,11 +1678,13 @@ _Py_Executors_InvalidateCold(PyInterpreterState *interp)
16651678
16661679    /* Clearing an executor can deallocate others, so we need to make a list of 
16671680     * executors to invalidate first */ 
1681+     EXECUTOR_LIST_LOCK (interp );
16681682    for  (_PyExecutorObject  * exec  =  interp -> executor_list_head ; exec  !=  NULL ;) {
16691683        assert (exec -> vm_data .valid );
16701684        _PyExecutorObject  * next  =  exec -> vm_data .links .next ;
16711685
16721686        if  (!exec -> vm_data .warm  &&  PyList_Append (invalidate , (PyObject  * )exec ) <  0 ) {
1687+             EXECUTOR_LIST_UNLOCK (interp );
16731688            goto error ;
16741689        }
16751690        else  {
@@ -1678,6 +1693,7 @@ _Py_Executors_InvalidateCold(PyInterpreterState *interp)
16781693
16791694        exec  =  next ;
16801695    }
1696+     EXECUTOR_LIST_UNLOCK (interp );
16811697    for  (Py_ssize_t  i  =  0 ; i  <  PyList_GET_SIZE (invalidate ); i ++ ) {
16821698        PyObject  * exec  =  PyList_GET_ITEM (invalidate , i );
16831699        executor_clear (exec );
@@ -1801,10 +1817,12 @@ _PyDumpExecutors(FILE *out)
18011817    fprintf (out , "digraph ideal {\n\n" );
18021818    fprintf (out , "    rankdir = \"LR\"\n\n" );
18031819    PyInterpreterState  * interp  =  PyInterpreterState_Get ();
1820+     EXECUTOR_LIST_LOCK (interp );
18041821    for  (_PyExecutorObject  * exec  =  interp -> executor_list_head ; exec  !=  NULL ;) {
18051822        executor_to_gv (exec , out );
18061823        exec  =  exec -> vm_data .links .next ;
18071824    }
1825+     EXECUTOR_LIST_UNLOCK (interp );
18081826    fprintf (out , "}\n\n" );
18091827    return  0 ;
18101828}
0 commit comments