/work/svt-av1/Source/Lib/Codec/kernel_dispatch.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright(c) 2025 Meta Platforms, Inc. and affiliates. |
3 | | * |
4 | | * This source code is subject to the terms of the BSD 2 Clause License and |
5 | | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
6 | | * was not distributed with this source code in the LICENSE file, you can |
7 | | * obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open |
8 | | * Media Patent License 1.0 was not distributed with this source code in the |
9 | | * PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license. |
10 | | */ |
11 | | |
12 | | #include "kernel_dispatch.h" |
13 | | |
14 | | #if CONFIG_SINGLE_THREAD_KERNEL |
15 | | #include <string.h> |
16 | | #include <assert.h> |
17 | | #include "enc_handle.h" // for EbThreadContext (struct _EbThreadContext) |
18 | | |
19 | 533 | void svt_kernel_dispatcher_init(SvtKernelDispatcher* dispatcher) { |
20 | 533 | memset(dispatcher, 0, sizeof(*dispatcher)); |
21 | 533 | } |
22 | | |
23 | | void svt_kernel_dispatcher_register(SvtKernelDispatcher* dispatcher, SvtKernelIterFn iter_fn, void* context, |
24 | 0 | EbFifo* input_fifo, const char* name) { |
25 | 0 | assert(dispatcher->num_kernels < SVT_MAX_KERNELS); |
26 | 0 | SvtKernelDesc* desc = &dispatcher->kernels[dispatcher->num_kernels++]; |
27 | 0 | desc->iter_fn = iter_fn; |
28 | 0 | desc->context = context; |
29 | 0 | desc->input_fifo = input_fifo; |
30 | 0 | desc->name = name; |
31 | 0 | } |
32 | | |
33 | 0 | void svt_kernel_dispatcher_run(SvtKernelDispatcher* dispatcher) { |
34 | 0 | bool progress; |
35 | 0 | do { |
36 | 0 | progress = false; |
37 | 0 | for (uint32_t i = 0; i < dispatcher->num_kernels; i++) { |
38 | 0 | SvtKernelDesc* desc = &dispatcher->kernels[i]; |
39 | | // Process all pending items for this kernel before moving to next |
40 | 0 | while (svt_fifo_has_items_st(desc->input_fifo)) { |
41 | 0 | EbErrorType err = desc->iter_fn(desc->context); |
42 | 0 | if (err == EB_NoErrorFifoShutdown) { |
43 | 0 | return; |
44 | 0 | } |
45 | 0 | progress = true; |
46 | 0 | } |
47 | 0 | } |
48 | 0 | } while (progress); |
49 | 0 | } |
50 | | |
51 | | EbErrorType svt_create_kernel_or_thread(EbHandle* thread_handle, void* (*kernel_fn)(void*), SvtKernelIterFn iter_fn, |
52 | | EbThreadContext* thread_ctx, EbFifo* input_fifo, const char* name, |
53 | 0 | SvtKernelDispatcher* dispatcher) { |
54 | 0 | if (dispatcher && dispatcher->active && iter_fn) { |
55 | | // Single-thread mode: register kernel for cooperative dispatch |
56 | 0 | svt_kernel_dispatcher_register(dispatcher, iter_fn, thread_ctx->priv, input_fifo, name); |
57 | 0 | *thread_handle = NULL; |
58 | 0 | } else { |
59 | | // Multi-thread mode: create OS thread with original kernel function |
60 | 0 | *thread_handle = svt_create_thread(kernel_fn, thread_ctx, name); |
61 | 0 | if (!*thread_handle) { |
62 | 0 | return EB_ErrorInsufficientResources; |
63 | 0 | } |
64 | 0 | EB_ADD_MEM(*thread_handle, 1, EB_THREAD); |
65 | 0 | } |
66 | 0 | return EB_ErrorNone; |
67 | 0 | } |
68 | | |
69 | | #endif // CONFIG_SINGLE_THREAD_KERNEL |