> On Sep 24, 2024, at 22:16, Nuo Mi <nuomi2...@gmail.com> wrote:
>
> Due to the nature of multithreading, using a "ready check" mechanism may
> introduce a deadlock. For example:
>
> Suppose all tasks have been submitted to the executor, and the last thread
> checks the entire list and finds
> no ready tasks. It then goes to sleep, waiting for a new task. However, for
> some multithreading-related reason,
> a task becomes ready after the check. Since no other thread is aware of this
> and no new tasks are being added to
> the executor, a deadlock occurs.
>
> In VVC, this function is unnecessary because we use a scoreboard. All tasks
> submitted to the executor are ready tasks.
> ---
> libavcodec/vvc/thread.c | 8 --------
> libavutil/executor.c | 6 ++----
> libavutil/executor.h | 3 ---
> 3 files changed, 2 insertions(+), 15 deletions(-)
>
> diff --git a/libavcodec/vvc/thread.c b/libavcodec/vvc/thread.c
> index 86a7753c6a..6208cc1811 100644
> --- a/libavcodec/vvc/thread.c
> +++ b/libavcodec/vvc/thread.c
> @@ -372,13 +372,6 @@ static int task_is_stage_ready(VVCTask *t, int add)
> return task_has_target_score(t, stage, score);
> }
>
> -static int task_ready(const AVTask *_t, void *user_data)
> -{
> - VVCTask *t = (VVCTask*)_t;
> -
> - return task_is_stage_ready(t, 0);
> -}
> -
> #define CHECK(a, b) \
> do { \
> if ((a) != (b)) \
> @@ -689,7 +682,6 @@ AVExecutor* ff_vvc_executor_alloc(VVCContext *s, const
> int thread_count)
> s,
> sizeof(VVCLocalContext),
> task_priority_higher,
> - task_ready,
> task_run,
> };
> return av_executor_alloc(&callbacks, thread_count);
> diff --git a/libavutil/executor.c b/libavutil/executor.c
> index bfce2ac444..64e6cc0775 100644
> --- a/libavutil/executor.c
> +++ b/libavutil/executor.c
> @@ -79,10 +79,8 @@ static void add_task(AVTask **prev, AVTask *t)
> static int run_one_task(AVExecutor *e, void *lc)
> {
> AVTaskCallbacks *cb = &e->cb;
> - AVTask **prev;
> + AVTask **prev = &e->tasks;
>
> - for (prev = &e->tasks; *prev && !cb->ready(*prev, cb->user_data); prev =
> &(*prev)->next)
> - /* nothing */;
> if (*prev) {
> AVTask *t = remove_task(prev, *prev);
> if (e->thread_count > 0)
> @@ -143,7 +141,7 @@ AVExecutor* av_executor_alloc(const AVTaskCallbacks *cb,
> int thread_count)
> {
> AVExecutor *e;
> int has_lock = 0, has_cond = 0;
> - if (!cb || !cb->user_data || !cb->ready || !cb->run ||
> !cb->priority_higher)
> + if (!cb || !cb->user_data || !cb->run || !cb->priority_higher)
> return NULL;
>
> e = av_mallocz(sizeof(*e));
> diff --git a/libavutil/executor.h b/libavutil/executor.h
> index 0eb21c10c8..7af53c92ce 100644
> --- a/libavutil/executor.h
> +++ b/libavutil/executor.h
> @@ -36,9 +36,6 @@ typedef struct AVTaskCallbacks {
> // return 1 if a's priority > b's priority
> int (*priority_higher)(const AVTask *a, const AVTask *b);
>
> - // task is ready for run
> - int (*ready)(const AVTask *t, void *user_data);
> -
> // run the task
> int (*run)(AVTask *t, void *local_context, void *user_data);
> } AVTaskCallbacks;
Unfortunately executor.h is a public header, this is API/ABI break.
> --
> 2.34.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".