xref: /aosp_15_r20/external/libvpx/vp9/decoder/vp9_job_queue.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1 /*
2  *  Copyright (c) 2018 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include <assert.h>
12 #include <string.h>
13 
14 #include "vpx/vpx_integer.h"
15 #include "vpx_util/vpx_pthread.h"
16 
17 #include "vp9/decoder/vp9_job_queue.h"
18 
vp9_jobq_init(JobQueueRowMt * jobq,uint8_t * buf,size_t buf_size)19 void vp9_jobq_init(JobQueueRowMt *jobq, uint8_t *buf, size_t buf_size) {
20 #if CONFIG_MULTITHREAD
21   pthread_mutex_init(&jobq->mutex, NULL);
22   pthread_cond_init(&jobq->cond, NULL);
23 #endif
24   jobq->buf_base = buf;
25   jobq->buf_wr = buf;
26   jobq->buf_rd = buf;
27   jobq->buf_end = buf + buf_size;
28   jobq->terminate = 0;
29 }
30 
vp9_jobq_reset(JobQueueRowMt * jobq)31 void vp9_jobq_reset(JobQueueRowMt *jobq) {
32 #if CONFIG_MULTITHREAD
33   pthread_mutex_lock(&jobq->mutex);
34 #endif
35   jobq->buf_wr = jobq->buf_base;
36   jobq->buf_rd = jobq->buf_base;
37   jobq->terminate = 0;
38 #if CONFIG_MULTITHREAD
39   pthread_mutex_unlock(&jobq->mutex);
40 #endif
41 }
42 
vp9_jobq_deinit(JobQueueRowMt * jobq)43 void vp9_jobq_deinit(JobQueueRowMt *jobq) {
44   vp9_jobq_reset(jobq);
45 #if CONFIG_MULTITHREAD
46   pthread_mutex_destroy(&jobq->mutex);
47   pthread_cond_destroy(&jobq->cond);
48 #endif
49 }
50 
vp9_jobq_terminate(JobQueueRowMt * jobq)51 void vp9_jobq_terminate(JobQueueRowMt *jobq) {
52 #if CONFIG_MULTITHREAD
53   pthread_mutex_lock(&jobq->mutex);
54 #endif
55   jobq->terminate = 1;
56 #if CONFIG_MULTITHREAD
57   pthread_cond_broadcast(&jobq->cond);
58   pthread_mutex_unlock(&jobq->mutex);
59 #endif
60 }
61 
vp9_jobq_queue(JobQueueRowMt * jobq,void * job,size_t job_size)62 int vp9_jobq_queue(JobQueueRowMt *jobq, void *job, size_t job_size) {
63   int ret = 0;
64 #if CONFIG_MULTITHREAD
65   pthread_mutex_lock(&jobq->mutex);
66 #endif
67   if (jobq->buf_end >= jobq->buf_wr + job_size) {
68     memcpy(jobq->buf_wr, job, job_size);
69     jobq->buf_wr = jobq->buf_wr + job_size;
70 #if CONFIG_MULTITHREAD
71     pthread_cond_signal(&jobq->cond);
72 #endif
73     ret = 0;
74   } else {
75     /* Wrap around case is not supported */
76     assert(0);
77     ret = 1;
78   }
79 #if CONFIG_MULTITHREAD
80   pthread_mutex_unlock(&jobq->mutex);
81 #endif
82   return ret;
83 }
84 
vp9_jobq_dequeue(JobQueueRowMt * jobq,void * job,size_t job_size,int blocking)85 int vp9_jobq_dequeue(JobQueueRowMt *jobq, void *job, size_t job_size,
86                      int blocking) {
87   int ret = 0;
88 #if CONFIG_MULTITHREAD
89   pthread_mutex_lock(&jobq->mutex);
90 #endif
91   if (jobq->buf_end >= jobq->buf_rd + job_size) {
92     while (1) {
93       if (jobq->buf_wr >= jobq->buf_rd + job_size) {
94         memcpy(job, jobq->buf_rd, job_size);
95         jobq->buf_rd = jobq->buf_rd + job_size;
96         ret = 0;
97         break;
98       } else {
99         /* If all the entries have been dequeued, then break and return */
100         if (jobq->terminate == 1) {
101           ret = 1;
102           break;
103         }
104         if (blocking == 1) {
105 #if CONFIG_MULTITHREAD
106           pthread_cond_wait(&jobq->cond, &jobq->mutex);
107 #endif
108         } else {
109           /* If there is no job available,
110            * and this is non blocking call then return fail */
111           ret = 1;
112           break;
113         }
114       }
115     }
116   } else {
117     /* Wrap around case is not supported */
118     ret = 1;
119   }
120 #if CONFIG_MULTITHREAD
121   pthread_mutex_unlock(&jobq->mutex);
122 #endif
123 
124   return ret;
125 }
126