| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -245,6 +245,16 @@ _Py_ClearExecutorDeletionList(PyInterpreterState *interp) | |
| ts = PyThreadState_Next(ts); | ||
| HEAD_UNLOCK(runtime); | ||
| } | ||
|
|
||
| /* Create a list to collect executors that need to be freed. | ||
| * This avoids calling _PyExecutor_Free while holding the lock, | ||
| * which could trigger destructors and cause deadlock. */ | ||
| PyObject *to_free = PyList_New(0); | ||
| if (to_free == NULL) { | ||
| goto error; | ||
| } | ||
|
|
||
| EXECUTOR_LIST_LOCK(interp); | ||
|
Comment thread
Fidget-Spinner marked this conversation as resolved.
|
||
| _PyExecutorObject **prev_to_next_ptr = &interp->executor_deletion_list_head; | ||
| _PyExecutorObject *exec = *prev_to_next_ptr; | ||
| while (exec != NULL) { | ||
| Expand All | @@ -255,24 +265,48 @@ _Py_ClearExecutorDeletionList(PyInterpreterState *interp) | |
| } | ||
| else { | ||
| *prev_to_next_ptr = exec->vm_data.links.next; | ||
| _PyExecutor_Free(exec); | ||
| if (PyList_Append(to_free, (PyObject *)exec)) { | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| goto error; | ||
| } | ||
| } | ||
| exec = *prev_to_next_ptr; | ||
| } | ||
| interp->executor_deletion_list_remaining_capacity = EXECUTOR_DELETE_LIST_MAX; | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
|
|
||
| for (Py_ssize_t i = 0; i < PyList_GET_SIZE(to_free); i++) { | ||
| _PyExecutorObject *exec = (_PyExecutorObject *)PyList_GET_ITEM(to_free, i); | ||
| PyList_SET_ITEM(to_free, i, NULL); | ||
| _PyExecutor_Free(exec); | ||
| } | ||
| Py_DECREF(to_free); | ||
| return; | ||
|
|
||
| error: | ||
| PyErr_Clear(); | ||
| Py_XDECREF(to_free); | ||
| } | ||
|
|
||
| static void | ||
| add_to_pending_deletion_list(_PyExecutorObject *self) | ||
| { | ||
| PyInterpreterState *interp = PyInterpreterState_Get(); | ||
| EXECUTOR_LIST_LOCK(interp); | ||
| self->vm_data.links.next = interp->executor_deletion_list_head; | ||
| interp->executor_deletion_list_head = self; | ||
| if (interp->executor_deletion_list_remaining_capacity > 0) { | ||
| interp->executor_deletion_list_remaining_capacity--; | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| } | ||
| else { | ||
| /* Release the lock before calling _Py_ClearExecutorDeletionList | ||
| * to avoid deadlock, since it also tries to acquire the same lock */ | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| _Py_ClearExecutorDeletionList(interp); | ||
| EXECUTOR_LIST_LOCK(interp); | ||
|
Comment thread
Comment on lines
+303
to
+307
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityDo we still need this?
Sorry, something went wrong.
All reactions
|
||
| interp->executor_deletion_list_head = self; | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| } | ||
| } | ||
|
|
||
| Expand Down Expand Up | @@ -1450,6 +1484,7 @@ static void | |
| link_executor(_PyExecutorObject *executor) | ||
| { | ||
| PyInterpreterState *interp = _PyInterpreterState_GET(); | ||
| EXECUTOR_LIST_LOCK(interp); | ||
| _PyExecutorLinkListNode *links = &executor->vm_data.links; | ||
| _PyExecutorObject *head = interp->executor_list_head; | ||
| if (head == NULL) { | ||
| Expand All | @@ -1467,6 +1502,7 @@ link_executor(_PyExecutorObject *executor) | |
| executor->vm_data.linked = true; | ||
| /* executor_list_head must be first in list */ | ||
| assert(interp->executor_list_head->vm_data.links.previous == NULL); | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| } | ||
|
|
||
| static void | ||
| Expand All | @@ -1475,6 +1511,8 @@ unlink_executor(_PyExecutorObject *executor) | |
| if (!executor->vm_data.linked) { | ||
| return; | ||
| } | ||
| PyInterpreterState *interp = PyInterpreterState_Get(); | ||
| EXECUTOR_LIST_LOCK(interp); | ||
| _PyExecutorLinkListNode *links = &executor->vm_data.links; | ||
| assert(executor->vm_data.valid); | ||
| _PyExecutorObject *next = links->next; | ||
| Expand All | @@ -1487,11 +1525,11 @@ unlink_executor(_PyExecutorObject *executor) | |
| } | ||
| else { | ||
| // prev == NULL implies that executor is the list head | ||
| PyInterpreterState *interp = PyInterpreterState_Get(); | ||
| assert(interp->executor_list_head == executor); | ||
| interp->executor_list_head = next; | ||
| } | ||
| executor->vm_data.linked = false; | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| } | ||
|
|
||
| /* This must be called by optimizers before using the executor */ | ||
| Expand Down Expand Up | @@ -1616,16 +1654,19 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is | |
| } | ||
| /* Clearing an executor can deallocate others, so we need to make a list of | ||
| * executors to invalidate first */ | ||
| EXECUTOR_LIST_LOCK(interp); | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThis is fine. nice.!
Sorry, something went wrong.
All reactions
|
||
| for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) { | ||
| assert(exec->vm_data.valid); | ||
| _PyExecutorObject *next = exec->vm_data.links.next; | ||
| if (bloom_filter_may_contain(&exec->vm_data.bloom, &obj_filter) && | ||
| PyList_Append(invalidate, (PyObject *)exec)) | ||
| { | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| goto error; | ||
| } | ||
| exec = next; | ||
| } | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) { | ||
| PyObject *exec = PyList_GET_ITEM(invalidate, i); | ||
| executor_clear(exec); | ||
| Expand All | @@ -1646,6 +1687,7 @@ _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is | |
| void | ||
| _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation) | ||
| { | ||
| EXECUTOR_LIST_LOCK(interp); | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThis should be a stop the world event.
Sorry, something went wrong.
All reactions
|
||
| while (interp->executor_list_head) { | ||
| _PyExecutorObject *executor = interp->executor_list_head; | ||
| assert(executor->vm_data.valid == 1 && executor->vm_data.linked == 1); | ||
| Expand All | @@ -1660,6 +1702,7 @@ _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation) | |
| OPT_STAT_INC(executors_invalidated); | ||
| } | ||
| } | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| } | ||
|
|
||
| void | ||
| Expand All | @@ -1674,11 +1717,13 @@ _Py_Executors_InvalidateCold(PyInterpreterState *interp) | |
|
|
||
| /* Clearing an executor can deallocate others, so we need to make a list of | ||
| * executors to invalidate first */ | ||
| EXECUTOR_LIST_LOCK(interp); | ||
| for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) { | ||
| assert(exec->vm_data.valid); | ||
| _PyExecutorObject *next = exec->vm_data.links.next; | ||
|
|
||
| if (!exec->vm_data.warm && PyList_Append(invalidate, (PyObject *)exec) < 0) { | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| goto error; | ||
| } | ||
| else { | ||
| Expand All | @@ -1687,6 +1732,7 @@ _Py_Executors_InvalidateCold(PyInterpreterState *interp) | |
|
|
||
| exec = next; | ||
| } | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| for (Py_ssize_t i = 0; i < PyList_GET_SIZE(invalidate); i++) { | ||
| PyObject *exec = PyList_GET_ITEM(invalidate, i); | ||
| executor_clear(exec); | ||
| Expand Down Expand Up | @@ -1810,10 +1856,12 @@ _PyDumpExecutors(FILE *out) | |
| fprintf(out, "digraph ideal {\n\n"); | ||
| fprintf(out, " rankdir = \"LR\"\n\n"); | ||
| PyInterpreterState *interp = PyInterpreterState_Get(); | ||
| EXECUTOR_LIST_LOCK(interp); | ||
| for (_PyExecutorObject *exec = interp->executor_list_head; exec != NULL;) { | ||
| executor_to_gv(exec, out); | ||
| exec = exec->vm_data.links.next; | ||
| } | ||
| EXECUTOR_LIST_UNLOCK(interp); | ||
| fprintf(out, "}\n\n"); | ||
| return 0; | ||
| } | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.