• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "vp9/decoder/vp9_job_queue.h"
17 
vp9_jobq_init(JobQueueRowMt * jobq,uint8_t * buf,size_t buf_size)18 void vp9_jobq_init(JobQueueRowMt *jobq, uint8_t *buf, size_t buf_size) {
19 #if CONFIG_MULTITHREAD
20   pthread_mutex_init(&jobq->mutex, NULL);
21   pthread_cond_init(&jobq->cond, NULL);
22 #endif
23   jobq->buf_base = buf;
24   jobq->buf_wr = buf;
25   jobq->buf_rd = buf;
26   jobq->buf_end = buf + buf_size;
27   jobq->terminate = 0;
28 }
29 
vp9_jobq_reset(JobQueueRowMt * jobq)30 void vp9_jobq_reset(JobQueueRowMt *jobq) {
31 #if CONFIG_MULTITHREAD
32   pthread_mutex_lock(&jobq->mutex);
33 #endif
34   jobq->buf_wr = jobq->buf_base;
35   jobq->buf_rd = jobq->buf_base;
36   jobq->terminate = 0;
37 #if CONFIG_MULTITHREAD
38   pthread_mutex_unlock(&jobq->mutex);
39 #endif
40 }
41 
vp9_jobq_deinit(JobQueueRowMt * jobq)42 void vp9_jobq_deinit(JobQueueRowMt *jobq) {
43   vp9_jobq_reset(jobq);
44 #if CONFIG_MULTITHREAD
45   pthread_mutex_destroy(&jobq->mutex);
46   pthread_cond_destroy(&jobq->cond);
47 #endif
48 }
49 
vp9_jobq_terminate(JobQueueRowMt * jobq)50 void vp9_jobq_terminate(JobQueueRowMt *jobq) {
51 #if CONFIG_MULTITHREAD
52   pthread_mutex_lock(&jobq->mutex);
53 #endif
54   jobq->terminate = 1;
55 #if CONFIG_MULTITHREAD
56   pthread_cond_broadcast(&jobq->cond);
57   pthread_mutex_unlock(&jobq->mutex);
58 #endif
59 }
60 
vp9_jobq_queue(JobQueueRowMt * jobq,void * job,size_t job_size)61 int vp9_jobq_queue(JobQueueRowMt *jobq, void *job, size_t job_size) {
62   int ret = 0;
63 #if CONFIG_MULTITHREAD
64   pthread_mutex_lock(&jobq->mutex);
65 #endif
66   if (jobq->buf_end >= jobq->buf_wr + job_size) {
67     memcpy(jobq->buf_wr, job, job_size);
68     jobq->buf_wr = jobq->buf_wr + job_size;
69 #if CONFIG_MULTITHREAD
70     pthread_cond_signal(&jobq->cond);
71 #endif
72     ret = 0;
73   } else {
74     /* Wrap around case is not supported */
75     assert(0);
76     ret = 1;
77   }
78 #if CONFIG_MULTITHREAD
79   pthread_mutex_unlock(&jobq->mutex);
80 #endif
81   return ret;
82 }
83 
vp9_jobq_dequeue(JobQueueRowMt * jobq,void * job,size_t job_size,int blocking)84 int vp9_jobq_dequeue(JobQueueRowMt *jobq, void *job, size_t job_size,
85                      int blocking) {
86   int ret = 0;
87 #if CONFIG_MULTITHREAD
88   pthread_mutex_lock(&jobq->mutex);
89 #endif
90   if (jobq->buf_end >= jobq->buf_rd + job_size) {
91     while (1) {
92       if (jobq->buf_wr >= jobq->buf_rd + job_size) {
93         memcpy(job, jobq->buf_rd, job_size);
94         jobq->buf_rd = jobq->buf_rd + job_size;
95         ret = 0;
96         break;
97       } else {
98         /* If all the entries have been dequeued, then break and return */
99         if (jobq->terminate == 1) {
100           ret = 1;
101           break;
102         }
103         if (blocking == 1) {
104 #if CONFIG_MULTITHREAD
105           pthread_cond_wait(&jobq->cond, &jobq->mutex);
106 #endif
107         } else {
108           /* If there is no job available,
109            * and this is non blocking call then return fail */
110           ret = 1;
111           break;
112         }
113       }
114     }
115   } else {
116     /* Wrap around case is not supported */
117     ret = 1;
118   }
119 #if CONFIG_MULTITHREAD
120   pthread_mutex_unlock(&jobq->mutex);
121 #endif
122 
123   return ret;
124 }
125