1*a97c2a1fSXin Li /******************************************************************************
2*a97c2a1fSXin Li *
3*a97c2a1fSXin Li * Copyright (C) 2015 The Android Open Source Project
4*a97c2a1fSXin Li *
5*a97c2a1fSXin Li * Licensed under the Apache License, Version 2.0 (the "License");
6*a97c2a1fSXin Li * you may not use this file except in compliance with the License.
7*a97c2a1fSXin Li * You may obtain a copy of the License at:
8*a97c2a1fSXin Li *
9*a97c2a1fSXin Li * http://www.apache.org/licenses/LICENSE-2.0
10*a97c2a1fSXin Li *
11*a97c2a1fSXin Li * Unless required by applicable law or agreed to in writing, software
12*a97c2a1fSXin Li * distributed under the License is distributed on an "AS IS" BASIS,
13*a97c2a1fSXin Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*a97c2a1fSXin Li * See the License for the specific language governing permissions and
15*a97c2a1fSXin Li * limitations under the License.
16*a97c2a1fSXin Li *
17*a97c2a1fSXin Li *****************************************************************************
18*a97c2a1fSXin Li * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*a97c2a1fSXin Li */
20*a97c2a1fSXin Li /**
21*a97c2a1fSXin Li *******************************************************************************
22*a97c2a1fSXin Li * @file
23*a97c2a1fSXin Li * impeg2d_job_queue.c
24*a97c2a1fSXin Li *
25*a97c2a1fSXin Li * @brief
26*a97c2a1fSXin Li * Contains functions for job queue
27*a97c2a1fSXin Li *
28*a97c2a1fSXin Li * @author
29*a97c2a1fSXin Li * Harish
30*a97c2a1fSXin Li *
31*a97c2a1fSXin Li * @par List of Functions:
32*a97c2a1fSXin Li *
33*a97c2a1fSXin Li * @remarks
34*a97c2a1fSXin Li * None
35*a97c2a1fSXin Li *
36*a97c2a1fSXin Li *******************************************************************************
37*a97c2a1fSXin Li */
38*a97c2a1fSXin Li /*****************************************************************************/
39*a97c2a1fSXin Li /* File Includes */
40*a97c2a1fSXin Li /*****************************************************************************/
41*a97c2a1fSXin Li #include <stdio.h>
42*a97c2a1fSXin Li #include <stddef.h>
43*a97c2a1fSXin Li #include <stdlib.h>
44*a97c2a1fSXin Li #include <string.h>
45*a97c2a1fSXin Li #include <assert.h>
46*a97c2a1fSXin Li
47*a97c2a1fSXin Li #include "iv_datatypedef.h"
48*a97c2a1fSXin Li #include "iv.h"
49*a97c2a1fSXin Li #include "ithread.h"
50*a97c2a1fSXin Li #include "impeg2_macros.h"
51*a97c2a1fSXin Li #include "impeg2_job_queue.h"
52*a97c2a1fSXin Li
53*a97c2a1fSXin Li /**
54*a97c2a1fSXin Li *******************************************************************************
55*a97c2a1fSXin Li *
56*a97c2a1fSXin Li * @brief Returns size for job queue context. Does not include job queue buffer
57*a97c2a1fSXin Li * requirements
58*a97c2a1fSXin Li *
59*a97c2a1fSXin Li * @par Description
60*a97c2a1fSXin Li * Returns size for job queue context. Does not include job queue buffer
61*a97c2a1fSXin Li * requirements. Buffer size required to store the jobs should be allocated in
62*a97c2a1fSXin Li * addition to the value returned here.
63*a97c2a1fSXin Li *
64*a97c2a1fSXin Li * @returns Size of the job queue context
65*a97c2a1fSXin Li *
66*a97c2a1fSXin Li * @remarks
67*a97c2a1fSXin Li *
68*a97c2a1fSXin Li *******************************************************************************
69*a97c2a1fSXin Li */
impeg2_jobq_ctxt_size()70*a97c2a1fSXin Li WORD32 impeg2_jobq_ctxt_size()
71*a97c2a1fSXin Li {
72*a97c2a1fSXin Li WORD32 i4_size;
73*a97c2a1fSXin Li i4_size = sizeof(jobq_t);
74*a97c2a1fSXin Li i4_size += ithread_get_mutex_lock_size();
75*a97c2a1fSXin Li return i4_size;
76*a97c2a1fSXin Li }
77*a97c2a1fSXin Li
78*a97c2a1fSXin Li /**
79*a97c2a1fSXin Li *******************************************************************************
80*a97c2a1fSXin Li *
81*a97c2a1fSXin Li * @brief
82*a97c2a1fSXin Li * Locks the jobq conext
83*a97c2a1fSXin Li *
84*a97c2a1fSXin Li * @par Description
85*a97c2a1fSXin Li * Locks the jobq conext by calling ithread_mutex_lock()
86*a97c2a1fSXin Li *
87*a97c2a1fSXin Li * @param[in] ps_jobq
88*a97c2a1fSXin Li * Job Queue context
89*a97c2a1fSXin Li *
90*a97c2a1fSXin Li * @returns IMPEG2D_FAIL if mutex lock fails else IV_SUCCESS
91*a97c2a1fSXin Li *
92*a97c2a1fSXin Li * @remarks
93*a97c2a1fSXin Li *
94*a97c2a1fSXin Li *******************************************************************************
95*a97c2a1fSXin Li */
impeg2_jobq_lock(jobq_t * ps_jobq)96*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_lock(jobq_t *ps_jobq)
97*a97c2a1fSXin Li {
98*a97c2a1fSXin Li WORD32 i4_ret_val;
99*a97c2a1fSXin Li i4_ret_val = ithread_mutex_lock(ps_jobq->pv_mutex);
100*a97c2a1fSXin Li if(i4_ret_val)
101*a97c2a1fSXin Li {
102*a97c2a1fSXin Li return IV_FAIL;
103*a97c2a1fSXin Li }
104*a97c2a1fSXin Li return IV_SUCCESS;
105*a97c2a1fSXin Li }
106*a97c2a1fSXin Li
107*a97c2a1fSXin Li /**
108*a97c2a1fSXin Li *******************************************************************************
109*a97c2a1fSXin Li *
110*a97c2a1fSXin Li * @brief
111*a97c2a1fSXin Li * Unlocks the jobq conext
112*a97c2a1fSXin Li *
113*a97c2a1fSXin Li * @par Description
114*a97c2a1fSXin Li * Unlocks the jobq conext by calling ithread_mutex_unlock()
115*a97c2a1fSXin Li *
116*a97c2a1fSXin Li * @param[in] ps_jobq
117*a97c2a1fSXin Li * Job Queue context
118*a97c2a1fSXin Li *
119*a97c2a1fSXin Li * @returns IMPEG2D_FAIL if mutex unlock fails else IV_SUCCESS
120*a97c2a1fSXin Li *
121*a97c2a1fSXin Li * @remarks
122*a97c2a1fSXin Li *
123*a97c2a1fSXin Li *******************************************************************************
124*a97c2a1fSXin Li */
125*a97c2a1fSXin Li
impeg2_jobq_unlock(jobq_t * ps_jobq)126*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_unlock(jobq_t *ps_jobq)
127*a97c2a1fSXin Li {
128*a97c2a1fSXin Li WORD32 i4_ret_val;
129*a97c2a1fSXin Li i4_ret_val = ithread_mutex_unlock(ps_jobq->pv_mutex);
130*a97c2a1fSXin Li if(i4_ret_val)
131*a97c2a1fSXin Li {
132*a97c2a1fSXin Li return IV_FAIL;
133*a97c2a1fSXin Li }
134*a97c2a1fSXin Li return IV_SUCCESS;
135*a97c2a1fSXin Li
136*a97c2a1fSXin Li }
137*a97c2a1fSXin Li /**
138*a97c2a1fSXin Li *******************************************************************************
139*a97c2a1fSXin Li *
140*a97c2a1fSXin Li * @brief
141*a97c2a1fSXin Li * Yeilds the thread
142*a97c2a1fSXin Li *
143*a97c2a1fSXin Li * @par Description
144*a97c2a1fSXin Li * Unlocks the jobq conext by calling
145*a97c2a1fSXin Li * impeg2_jobq_unlock(), ithread_yield() and then impeg2_jobq_lock()
146*a97c2a1fSXin Li * jobq is unlocked before to ensure the jobq can be accessed by other threads
147*a97c2a1fSXin Li * If unlock is not done before calling yield then no other thread can access
148*a97c2a1fSXin Li * the jobq functions and update jobq.
149*a97c2a1fSXin Li *
150*a97c2a1fSXin Li * @param[in] ps_jobq
151*a97c2a1fSXin Li * Job Queue context
152*a97c2a1fSXin Li *
153*a97c2a1fSXin Li * @returns IMPEG2D_FAIL if mutex lock unlock or yield fails else IV_SUCCESS
154*a97c2a1fSXin Li *
155*a97c2a1fSXin Li * @remarks
156*a97c2a1fSXin Li *
157*a97c2a1fSXin Li *******************************************************************************
158*a97c2a1fSXin Li */
impeg2_jobq_yield(jobq_t * ps_jobq)159*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_yield(jobq_t *ps_jobq)
160*a97c2a1fSXin Li {
161*a97c2a1fSXin Li
162*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret = IV_SUCCESS;
163*a97c2a1fSXin Li
164*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret_tmp;
165*a97c2a1fSXin Li e_ret_tmp = impeg2_jobq_unlock(ps_jobq);
166*a97c2a1fSXin Li RETURN_IF((e_ret_tmp != IV_SUCCESS), e_ret_tmp);
167*a97c2a1fSXin Li
168*a97c2a1fSXin Li //NOP(1024 * 8);
169*a97c2a1fSXin Li ithread_yield();
170*a97c2a1fSXin Li
171*a97c2a1fSXin Li e_ret_tmp = impeg2_jobq_lock(ps_jobq);
172*a97c2a1fSXin Li RETURN_IF((e_ret_tmp != IV_SUCCESS), e_ret_tmp);
173*a97c2a1fSXin Li return e_ret;
174*a97c2a1fSXin Li }
175*a97c2a1fSXin Li
176*a97c2a1fSXin Li
177*a97c2a1fSXin Li /**
178*a97c2a1fSXin Li *******************************************************************************
179*a97c2a1fSXin Li *
180*a97c2a1fSXin Li * @brief free the job queue pointers
181*a97c2a1fSXin Li *
182*a97c2a1fSXin Li * @par Description
183*a97c2a1fSXin Li * Frees the jobq context
184*a97c2a1fSXin Li *
185*a97c2a1fSXin Li * @param[in] pv_buf
186*a97c2a1fSXin Li * Memoy for job queue buffer and job queue context
187*a97c2a1fSXin Li *
188*a97c2a1fSXin Li * @returns Pointer to job queue context
189*a97c2a1fSXin Li *
190*a97c2a1fSXin Li * @remarks
191*a97c2a1fSXin Li * Since it will be called only once by master thread this is not thread safe.
192*a97c2a1fSXin Li *
193*a97c2a1fSXin Li *******************************************************************************
194*a97c2a1fSXin Li */
impeg2_jobq_free(jobq_t * ps_jobq)195*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_free(jobq_t *ps_jobq)
196*a97c2a1fSXin Li {
197*a97c2a1fSXin Li WORD32 i4_ret;
198*a97c2a1fSXin Li i4_ret = ithread_mutex_destroy(ps_jobq->pv_mutex);
199*a97c2a1fSXin Li
200*a97c2a1fSXin Li if(0 == i4_ret)
201*a97c2a1fSXin Li return IV_SUCCESS;
202*a97c2a1fSXin Li else
203*a97c2a1fSXin Li return IV_FAIL;
204*a97c2a1fSXin Li }
205*a97c2a1fSXin Li
206*a97c2a1fSXin Li /**
207*a97c2a1fSXin Li *******************************************************************************
208*a97c2a1fSXin Li *
209*a97c2a1fSXin Li * @brief Initialize the job queue
210*a97c2a1fSXin Li *
211*a97c2a1fSXin Li * @par Description
212*a97c2a1fSXin Li * Initializes the jobq context and sets write and read pointers to start of
213*a97c2a1fSXin Li * job queue buffer
214*a97c2a1fSXin Li *
215*a97c2a1fSXin Li * @param[in] pv_buf
216*a97c2a1fSXin Li * Memoy for job queue buffer and job queue context
217*a97c2a1fSXin Li *
218*a97c2a1fSXin Li * @param[in] buf_size
219*a97c2a1fSXin Li * Size of the total memory allocated
220*a97c2a1fSXin Li *
221*a97c2a1fSXin Li * @returns Pointer to job queue context
222*a97c2a1fSXin Li *
223*a97c2a1fSXin Li * @remarks
224*a97c2a1fSXin Li * Since it will be called only once by master thread this is not thread safe.
225*a97c2a1fSXin Li *
226*a97c2a1fSXin Li *******************************************************************************
227*a97c2a1fSXin Li */
impeg2_jobq_init(void * pv_buf,WORD32 i4_buf_size)228*a97c2a1fSXin Li void* impeg2_jobq_init(void *pv_buf, WORD32 i4_buf_size)
229*a97c2a1fSXin Li {
230*a97c2a1fSXin Li jobq_t *ps_jobq;
231*a97c2a1fSXin Li UWORD8 *pu1_buf;
232*a97c2a1fSXin Li pu1_buf = (UWORD8 *)pv_buf;
233*a97c2a1fSXin Li
234*a97c2a1fSXin Li ps_jobq = (jobq_t *)pu1_buf;
235*a97c2a1fSXin Li pu1_buf += sizeof(jobq_t);
236*a97c2a1fSXin Li i4_buf_size -= sizeof(jobq_t);
237*a97c2a1fSXin Li
238*a97c2a1fSXin Li ps_jobq->pv_mutex = pu1_buf;
239*a97c2a1fSXin Li pu1_buf += ithread_get_mutex_lock_size();
240*a97c2a1fSXin Li i4_buf_size -= ithread_get_mutex_lock_size();
241*a97c2a1fSXin Li
242*a97c2a1fSXin Li if(i4_buf_size <= 0)
243*a97c2a1fSXin Li return NULL;
244*a97c2a1fSXin Li
245*a97c2a1fSXin Li ithread_mutex_init(ps_jobq->pv_mutex);
246*a97c2a1fSXin Li
247*a97c2a1fSXin Li ps_jobq->pv_buf_base = pu1_buf;
248*a97c2a1fSXin Li ps_jobq->pv_buf_wr = pu1_buf;
249*a97c2a1fSXin Li ps_jobq->pv_buf_rd = pu1_buf;
250*a97c2a1fSXin Li ps_jobq->pv_buf_end = pu1_buf + i4_buf_size;
251*a97c2a1fSXin Li ps_jobq->i4_terminate = 0;
252*a97c2a1fSXin Li
253*a97c2a1fSXin Li
254*a97c2a1fSXin Li return ps_jobq;
255*a97c2a1fSXin Li }
256*a97c2a1fSXin Li /**
257*a97c2a1fSXin Li *******************************************************************************
258*a97c2a1fSXin Li *
259*a97c2a1fSXin Li * @brief
260*a97c2a1fSXin Li * Resets the jobq conext
261*a97c2a1fSXin Li *
262*a97c2a1fSXin Li * @par Description
263*a97c2a1fSXin Li * Resets the jobq conext by initilizing job queue context elements
264*a97c2a1fSXin Li *
265*a97c2a1fSXin Li * @param[in] ps_jobq
266*a97c2a1fSXin Li * Job Queue context
267*a97c2a1fSXin Li *
268*a97c2a1fSXin Li * @returns IMPEG2D_FAIL if lock unlock fails else IV_SUCCESS
269*a97c2a1fSXin Li *
270*a97c2a1fSXin Li * @remarks
271*a97c2a1fSXin Li *
272*a97c2a1fSXin Li *******************************************************************************
273*a97c2a1fSXin Li */
impeg2_jobq_reset(jobq_t * ps_jobq)274*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_reset(jobq_t *ps_jobq)
275*a97c2a1fSXin Li {
276*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret = IV_SUCCESS;
277*a97c2a1fSXin Li e_ret = impeg2_jobq_lock(ps_jobq);
278*a97c2a1fSXin Li RETURN_IF((e_ret != IV_SUCCESS), e_ret);
279*a97c2a1fSXin Li
280*a97c2a1fSXin Li ps_jobq->pv_buf_wr = ps_jobq->pv_buf_base;
281*a97c2a1fSXin Li ps_jobq->pv_buf_rd = ps_jobq->pv_buf_base;
282*a97c2a1fSXin Li ps_jobq->i4_terminate = 0;
283*a97c2a1fSXin Li e_ret = impeg2_jobq_unlock(ps_jobq);
284*a97c2a1fSXin Li RETURN_IF((e_ret != IV_SUCCESS), e_ret);
285*a97c2a1fSXin Li
286*a97c2a1fSXin Li return e_ret;
287*a97c2a1fSXin Li }
288*a97c2a1fSXin Li
289*a97c2a1fSXin Li /**
290*a97c2a1fSXin Li *******************************************************************************
291*a97c2a1fSXin Li *
292*a97c2a1fSXin Li * @brief
293*a97c2a1fSXin Li * Deinitializes the jobq conext
294*a97c2a1fSXin Li *
295*a97c2a1fSXin Li * @par Description
296*a97c2a1fSXin Li * Deinitializes the jobq conext by calling impeg2_jobq_reset()
297*a97c2a1fSXin Li * and then destrying the mutex created
298*a97c2a1fSXin Li *
299*a97c2a1fSXin Li * @param[in] ps_jobq
300*a97c2a1fSXin Li * Job Queue context
301*a97c2a1fSXin Li *
302*a97c2a1fSXin Li * @returns IMPEG2D_FAIL if lock unlock fails else IV_SUCCESS
303*a97c2a1fSXin Li *
304*a97c2a1fSXin Li * @remarks
305*a97c2a1fSXin Li *
306*a97c2a1fSXin Li *******************************************************************************
307*a97c2a1fSXin Li */
impeg2_jobq_deinit(jobq_t * ps_jobq)308*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_deinit(jobq_t *ps_jobq)
309*a97c2a1fSXin Li {
310*a97c2a1fSXin Li WORD32 i4_ret_val;
311*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret = IV_SUCCESS;
312*a97c2a1fSXin Li
313*a97c2a1fSXin Li e_ret = impeg2_jobq_reset(ps_jobq);
314*a97c2a1fSXin Li RETURN_IF((e_ret != IV_SUCCESS), e_ret);
315*a97c2a1fSXin Li
316*a97c2a1fSXin Li i4_ret_val = ithread_mutex_destroy(ps_jobq->pv_mutex);
317*a97c2a1fSXin Li if(i4_ret_val)
318*a97c2a1fSXin Li {
319*a97c2a1fSXin Li return IV_FAIL;
320*a97c2a1fSXin Li }
321*a97c2a1fSXin Li
322*a97c2a1fSXin Li return IV_SUCCESS;
323*a97c2a1fSXin Li }
324*a97c2a1fSXin Li
325*a97c2a1fSXin Li
326*a97c2a1fSXin Li /**
327*a97c2a1fSXin Li *******************************************************************************
328*a97c2a1fSXin Li *
329*a97c2a1fSXin Li * @brief
330*a97c2a1fSXin Li * Terminates the jobq
331*a97c2a1fSXin Li *
332*a97c2a1fSXin Li * @par Description
333*a97c2a1fSXin Li * Terminates the jobq by setting a flag in context.
334*a97c2a1fSXin Li *
335*a97c2a1fSXin Li * @param[in] ps_jobq
336*a97c2a1fSXin Li * Job Queue context
337*a97c2a1fSXin Li *
338*a97c2a1fSXin Li * @returns IMPEG2D_FAIL if lock unlock fails else IV_SUCCESS
339*a97c2a1fSXin Li *
340*a97c2a1fSXin Li * @remarks
341*a97c2a1fSXin Li *
342*a97c2a1fSXin Li *******************************************************************************
343*a97c2a1fSXin Li */
344*a97c2a1fSXin Li
impeg2_jobq_terminate(jobq_t * ps_jobq)345*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_terminate(jobq_t *ps_jobq)
346*a97c2a1fSXin Li {
347*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret = IV_SUCCESS;
348*a97c2a1fSXin Li e_ret = impeg2_jobq_lock(ps_jobq);
349*a97c2a1fSXin Li RETURN_IF((e_ret != IV_SUCCESS), e_ret);
350*a97c2a1fSXin Li
351*a97c2a1fSXin Li ps_jobq->i4_terminate = 1;
352*a97c2a1fSXin Li
353*a97c2a1fSXin Li e_ret = impeg2_jobq_unlock(ps_jobq);
354*a97c2a1fSXin Li RETURN_IF((e_ret != IV_SUCCESS), e_ret);
355*a97c2a1fSXin Li return e_ret;
356*a97c2a1fSXin Li }
357*a97c2a1fSXin Li
358*a97c2a1fSXin Li
359*a97c2a1fSXin Li /**
360*a97c2a1fSXin Li *******************************************************************************
361*a97c2a1fSXin Li *
362*a97c2a1fSXin Li * @brief Adds a job to the queue
363*a97c2a1fSXin Li *
364*a97c2a1fSXin Li * @par Description
365*a97c2a1fSXin Li * Adds a job to the queue and updates wr address to next location.
366*a97c2a1fSXin Li * Format/content of the job structure is abstracted and hence size of the job
367*a97c2a1fSXin Li * buffer is being passed.
368*a97c2a1fSXin Li *
369*a97c2a1fSXin Li * @param[in] ps_jobq
370*a97c2a1fSXin Li * Job Queue context
371*a97c2a1fSXin Li *
372*a97c2a1fSXin Li * @param[in] pv_job
373*a97c2a1fSXin Li * Pointer to the location that contains details of the job to be added
374*a97c2a1fSXin Li *
375*a97c2a1fSXin Li * @param[in] job_size
376*a97c2a1fSXin Li * Size of the job buffer
377*a97c2a1fSXin Li *
378*a97c2a1fSXin Li * @param[in] blocking
379*a97c2a1fSXin Li * To signal if the write is blocking or non-blocking.
380*a97c2a1fSXin Li *
381*a97c2a1fSXin Li * @returns
382*a97c2a1fSXin Li *
383*a97c2a1fSXin Li * @remarks
384*a97c2a1fSXin Li * Job Queue buffer is assumed to be allocated to handle worst case number of jobs
385*a97c2a1fSXin Li * Wrap around is not supported
386*a97c2a1fSXin Li *
387*a97c2a1fSXin Li *******************************************************************************
388*a97c2a1fSXin Li */
impeg2_jobq_queue(jobq_t * ps_jobq,void * pv_job,WORD32 i4_job_size,WORD32 i4_blocking,WORD32 i4_lock)389*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_queue(jobq_t *ps_jobq,
390*a97c2a1fSXin Li void *pv_job,
391*a97c2a1fSXin Li WORD32 i4_job_size,
392*a97c2a1fSXin Li WORD32 i4_blocking,
393*a97c2a1fSXin Li WORD32 i4_lock)
394*a97c2a1fSXin Li {
395*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret = IV_SUCCESS;
396*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret_tmp;
397*a97c2a1fSXin Li UWORD8 *pu1_buf;
398*a97c2a1fSXin Li UNUSED(i4_blocking);
399*a97c2a1fSXin Li
400*a97c2a1fSXin Li if(i4_lock)
401*a97c2a1fSXin Li {
402*a97c2a1fSXin Li e_ret_tmp = impeg2_jobq_lock(ps_jobq);
403*a97c2a1fSXin Li RETURN_IF((e_ret_tmp != IV_SUCCESS), e_ret_tmp);
404*a97c2a1fSXin Li }
405*a97c2a1fSXin Li pu1_buf = (UWORD8 *)ps_jobq->pv_buf_wr;
406*a97c2a1fSXin Li if((UWORD8 *)ps_jobq->pv_buf_end >= (pu1_buf + i4_job_size))
407*a97c2a1fSXin Li {
408*a97c2a1fSXin Li memcpy(ps_jobq->pv_buf_wr, pv_job, i4_job_size);
409*a97c2a1fSXin Li ps_jobq->pv_buf_wr = (UWORD8 *)ps_jobq->pv_buf_wr + i4_job_size;
410*a97c2a1fSXin Li e_ret = IV_SUCCESS;
411*a97c2a1fSXin Li }
412*a97c2a1fSXin Li else
413*a97c2a1fSXin Li {
414*a97c2a1fSXin Li /* Handle wrap around case */
415*a97c2a1fSXin Li /* Wait for pv_buf_rd to consume first job_size number of bytes
416*a97c2a1fSXin Li * from the beginning of job queue
417*a97c2a1fSXin Li */
418*a97c2a1fSXin Li e_ret = IV_FAIL;
419*a97c2a1fSXin Li }
420*a97c2a1fSXin Li
421*a97c2a1fSXin Li ps_jobq->i4_terminate = 0;
422*a97c2a1fSXin Li
423*a97c2a1fSXin Li if(i4_lock)
424*a97c2a1fSXin Li {
425*a97c2a1fSXin Li e_ret_tmp = impeg2_jobq_unlock(ps_jobq);
426*a97c2a1fSXin Li RETURN_IF((e_ret_tmp != IV_SUCCESS), e_ret_tmp);
427*a97c2a1fSXin Li }
428*a97c2a1fSXin Li
429*a97c2a1fSXin Li return e_ret;
430*a97c2a1fSXin Li }
431*a97c2a1fSXin Li /**
432*a97c2a1fSXin Li *******************************************************************************
433*a97c2a1fSXin Li *
434*a97c2a1fSXin Li * @brief Gets next from the Job queue
435*a97c2a1fSXin Li *
436*a97c2a1fSXin Li * @par Description
437*a97c2a1fSXin Li * Gets next job from the job queue and updates rd address to next location.
438*a97c2a1fSXin Li * Format/content of the job structure is abstracted and hence size of the job
439*a97c2a1fSXin Li * buffer is being passed. If it is a blocking call and if there is no new job
440*a97c2a1fSXin Li * then this functions unlocks the mutext and calls yield and then locks it back.
441*a97c2a1fSXin Li * and continues till a job is available or terminate is set
442*a97c2a1fSXin Li *
443*a97c2a1fSXin Li * @param[in] ps_jobq
444*a97c2a1fSXin Li * Job Queue context
445*a97c2a1fSXin Li *
446*a97c2a1fSXin Li * @param[out] pv_job
447*a97c2a1fSXin Li * Pointer to the location that contains details of the job to be written
448*a97c2a1fSXin Li *
449*a97c2a1fSXin Li * @param[in] job_size
450*a97c2a1fSXin Li * Size of the job buffer
451*a97c2a1fSXin Li *
452*a97c2a1fSXin Li * @param[in] blocking
453*a97c2a1fSXin Li * To signal if the read is blocking or non-blocking.
454*a97c2a1fSXin Li *
455*a97c2a1fSXin Li * @returns
456*a97c2a1fSXin Li *
457*a97c2a1fSXin Li * @remarks
458*a97c2a1fSXin Li * Job Queue buffer is assumed to be allocated to handle worst case number of jobs
459*a97c2a1fSXin Li * Wrap around is not supported
460*a97c2a1fSXin Li *
461*a97c2a1fSXin Li *******************************************************************************
462*a97c2a1fSXin Li */
impeg2_jobq_dequeue(jobq_t * ps_jobq,void * pv_job,WORD32 i4_job_size,WORD32 i4_blocking,WORD32 i4_lock)463*a97c2a1fSXin Li IV_API_CALL_STATUS_T impeg2_jobq_dequeue(jobq_t *ps_jobq,
464*a97c2a1fSXin Li void *pv_job,
465*a97c2a1fSXin Li WORD32 i4_job_size,
466*a97c2a1fSXin Li WORD32 i4_blocking,
467*a97c2a1fSXin Li WORD32 i4_lock)
468*a97c2a1fSXin Li {
469*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret;
470*a97c2a1fSXin Li IV_API_CALL_STATUS_T e_ret_tmp;
471*a97c2a1fSXin Li volatile UWORD8 *pu1_buf;
472*a97c2a1fSXin Li if(i4_lock)
473*a97c2a1fSXin Li {
474*a97c2a1fSXin Li e_ret_tmp = impeg2_jobq_lock(ps_jobq);
475*a97c2a1fSXin Li RETURN_IF((e_ret_tmp != IV_SUCCESS), e_ret_tmp);
476*a97c2a1fSXin Li }
477*a97c2a1fSXin Li pu1_buf = (UWORD8 *)ps_jobq->pv_buf_rd;
478*a97c2a1fSXin Li
479*a97c2a1fSXin Li
480*a97c2a1fSXin Li if((UWORD8 *)ps_jobq->pv_buf_end >= (pu1_buf + i4_job_size))
481*a97c2a1fSXin Li {
482*a97c2a1fSXin Li while(1)
483*a97c2a1fSXin Li {
484*a97c2a1fSXin Li pu1_buf = (UWORD8 *)ps_jobq->pv_buf_rd;
485*a97c2a1fSXin Li if((UWORD8 *)ps_jobq->pv_buf_wr >= (pu1_buf + i4_job_size))
486*a97c2a1fSXin Li {
487*a97c2a1fSXin Li memcpy(pv_job, ps_jobq->pv_buf_rd, i4_job_size);
488*a97c2a1fSXin Li ps_jobq->pv_buf_rd = (UWORD8 *)ps_jobq->pv_buf_rd + i4_job_size;
489*a97c2a1fSXin Li e_ret = IV_SUCCESS;
490*a97c2a1fSXin Li break;
491*a97c2a1fSXin Li }
492*a97c2a1fSXin Li else
493*a97c2a1fSXin Li {
494*a97c2a1fSXin Li /* If all the entries have been dequeued, then break and return */
495*a97c2a1fSXin Li if(1 == ps_jobq->i4_terminate)
496*a97c2a1fSXin Li {
497*a97c2a1fSXin Li e_ret = IV_FAIL;
498*a97c2a1fSXin Li break;
499*a97c2a1fSXin Li }
500*a97c2a1fSXin Li
501*a97c2a1fSXin Li if((1 == i4_blocking) && (1 == i4_lock))
502*a97c2a1fSXin Li {
503*a97c2a1fSXin Li impeg2_jobq_yield(ps_jobq);
504*a97c2a1fSXin Li
505*a97c2a1fSXin Li }
506*a97c2a1fSXin Li else
507*a97c2a1fSXin Li {
508*a97c2a1fSXin Li /* If there is no job available,
509*a97c2a1fSXin Li * and this is non blocking call then return fail */
510*a97c2a1fSXin Li e_ret = IV_FAIL;
511*a97c2a1fSXin Li }
512*a97c2a1fSXin Li }
513*a97c2a1fSXin Li }
514*a97c2a1fSXin Li }
515*a97c2a1fSXin Li else
516*a97c2a1fSXin Li {
517*a97c2a1fSXin Li /* Handle wrap around case */
518*a97c2a1fSXin Li /* Wait for pv_buf_rd to consume first i4_job_size number of bytes
519*a97c2a1fSXin Li * from the beginning of job queue
520*a97c2a1fSXin Li */
521*a97c2a1fSXin Li e_ret = IV_FAIL;
522*a97c2a1fSXin Li }
523*a97c2a1fSXin Li if(i4_lock)
524*a97c2a1fSXin Li {
525*a97c2a1fSXin Li e_ret_tmp = impeg2_jobq_unlock(ps_jobq);
526*a97c2a1fSXin Li RETURN_IF((e_ret_tmp != IV_SUCCESS), e_ret_tmp);
527*a97c2a1fSXin Li }
528*a97c2a1fSXin Li
529*a97c2a1fSXin Li return e_ret;
530*a97c2a1fSXin Li }
531