1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /*!
21 ******************************************************************************
22 * \file ihevce_dep_mngr.c
23 *
24 * \brief
25 *    This file contains all the functions related to Sync manager
26 *
27 * \date
28 *    12/12/2013
29 *
30 * \author
31 *    Ittiam
32 *
33 * List of Functions
34 *   <TODO: TO BE ADDED>
35 *
36 ******************************************************************************
37 */
38 
39 /*****************************************************************************/
40 /* File Includes                                                             */
41 /*****************************************************************************/
42 /* System include files */
43 #include <stdio.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <assert.h>
47 #include <stdarg.h>
48 #include <math.h>
49 
50 /* User include files */
51 #include "ihevc_typedefs.h"
52 #include "itt_video_api.h"
53 #include "ihevc_debug.h"
54 #include "ihevc_macros.h"
55 #include "ihevc_platform_macros.h"
56 
57 #include "ihevce_api.h"
58 #include "ihevce_dep_mngr_interface.h"
59 #include "ihevce_dep_mngr_private.h"
60 
61 #include "cast_types.h"
62 #include "osal.h"
63 #include "osal_defaults.h"
64 
65 /*****************************************************************************/
66 /* Function Definitions                                                      */
67 /*****************************************************************************/
68 
69 /*!
70 ******************************************************************************
71 * \if Function name : ihevce_dmgr_get_num_mem_recs \endif
72 *
73 * \brief
74 *    Number of memory records are returned for Dependency manager.
75 *
76 * \return
77 *    None
78 *
79 * \author
80 *  Ittiam
81 *
82 *****************************************************************************
83 */
ihevce_dmgr_get_num_mem_recs()84 WORD32 ihevce_dmgr_get_num_mem_recs()
85 {
86     return (NUM_DEP_MNGR_MEM_RECS);
87 }
88 
89 /*!
90 ******************************************************************************
91 * \if Function name : ihevce_dmgr_get_mem_recs \endif
92 *
93 * \brief
94 *    Memory requirements are returned for Dependency manager.
95 *
96 * \param[in,out]  ps_mem_tab : pointer to memory descriptors table
97 * \param[in] dep_mngr_mode : Mode of operation of dependency manager
98 * \param[in] max_num_vert_units : Maximum nunber of units to be processed
99 * \param[in] num_tile_cols : Number of column tiles for which encoder is working
100 * \param[in] num_threads : Number of threads among which sync will be established
101 * \param[in] i4_mem_space : memspace in which memory request should be done
102 *
103 * \return
104 *    None
105 *
106 * \author
107 *  Ittiam
108 *
109 *****************************************************************************
110 */
ihevce_dmgr_get_mem_recs(iv_mem_rec_t * ps_mem_tab,WORD32 dep_mngr_mode,WORD32 max_num_vert_units,WORD32 num_tile_cols,WORD32 num_threads,WORD32 i4_mem_space)111 WORD32 ihevce_dmgr_get_mem_recs(
112     iv_mem_rec_t *ps_mem_tab,
113     WORD32 dep_mngr_mode,
114     WORD32 max_num_vert_units,
115     WORD32 num_tile_cols,
116     WORD32 num_threads,
117     WORD32 i4_mem_space)
118 {
119     WORD32 num_vert_units;
120     WORD32 num_wait_thrd_ids;
121 
122     /* Dependency manager state structure */
123     ps_mem_tab[DEP_MNGR_CTXT].i4_mem_size = sizeof(dep_mngr_state_t);
124     ps_mem_tab[DEP_MNGR_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
125     ps_mem_tab[DEP_MNGR_CTXT].i4_mem_alignment = 8;
126 
127     /* SANITY CHECK */
128     ASSERT(
129         (DEP_MNGR_FRM_FRM_SYNC == dep_mngr_mode) || (DEP_MNGR_ROW_FRM_SYNC == dep_mngr_mode) ||
130         (DEP_MNGR_ROW_ROW_SYNC == dep_mngr_mode));
131 
132     /* Default value */
133     if(num_tile_cols < 1)
134     {
135         num_tile_cols = 1;
136     }
137 
138     /**************** Get Processed status Memory Requirements *********************/
139     if(DEP_MNGR_FRM_FRM_SYNC == dep_mngr_mode)
140     {
141         /* for frame to frame sync
142            2 words are used for holding num units processed prev
143            2 words are used for holding num units processed curr
144            */
145         num_vert_units = (2 + 2) * num_threads;
146     }
147     else
148     {
149         /* for both frm-row and row-row num vertical units in frame is allocated */
150         /* (* num_tile_cols) as each column tile can separately update and check */
151         num_vert_units = max_num_vert_units * num_tile_cols;
152     }
153 
154     ps_mem_tab[DEP_MNGR_UNITS_PRCSD_MEM].i4_mem_size = (sizeof(WORD32) * num_vert_units);
155     ps_mem_tab[DEP_MNGR_UNITS_PRCSD_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
156     ps_mem_tab[DEP_MNGR_UNITS_PRCSD_MEM].i4_mem_alignment = 8;
157 
158     /**************** Get Wait thread ids Memory Requirements *********************/
159     if(DEP_MNGR_FRM_FRM_SYNC == dep_mngr_mode)
160     {
161         /* for frame to frame sync number of threads worth memory is allocated */
162         num_wait_thrd_ids = num_threads;
163     }
164     else if(DEP_MNGR_ROW_ROW_SYNC == dep_mngr_mode)
165     {
166         /* for row to row sync number of vertical rows worth memory is allocated */
167         num_wait_thrd_ids = max_num_vert_units;
168     }
169     else
170     {
171         /* for row to frame sync number of threads * number of vertical rows worth memory is allocated */
172         num_wait_thrd_ids = max_num_vert_units * num_threads;
173     }
174 
175     ps_mem_tab[DEP_MNGR_WAIT_THRD_ID_MEM].i4_mem_size = (sizeof(WORD32) * num_wait_thrd_ids);
176     ps_mem_tab[DEP_MNGR_WAIT_THRD_ID_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
177     ps_mem_tab[DEP_MNGR_WAIT_THRD_ID_MEM].i4_mem_alignment = 8;
178 
179     /**************** Get Semaphore Requirements *********************/
180     ps_mem_tab[DEP_MNGR_SEM_HANDLE_MEM].i4_mem_size = (sizeof(void *) * num_threads);
181     ps_mem_tab[DEP_MNGR_SEM_HANDLE_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
182     ps_mem_tab[DEP_MNGR_SEM_HANDLE_MEM].i4_mem_alignment = 8;
183 
184     return (NUM_DEP_MNGR_MEM_RECS);
185 }
186 
187 /*!
188 ******************************************************************************
189 * \if Function name : ihevce_dmgr_map_get_mem_recs \endif
190 *
191 * \brief
192 *    Memory requirements are returned for Dependency manager.
193 *
194 * \param[in,out]  ps_mem_tab : pointer to memory descriptors table
195 * \param[in] num_units : Number of units in the map
196 * \param[in] num_threads : Number of threads among which sync will be established
197 * \param[in] i4_mem_space : memspace in which memory request should be done
198 *
199 * \return
200 *    None
201 *
202 * \author
203 *  Ittiam
204 *
205 *****************************************************************************
206 */
ihevce_dmgr_map_get_mem_recs(iv_mem_rec_t * ps_mem_tab,WORD32 num_units,WORD32 num_threads,WORD32 i4_mem_space)207 WORD32 ihevce_dmgr_map_get_mem_recs(
208     iv_mem_rec_t *ps_mem_tab, WORD32 num_units, WORD32 num_threads, WORD32 i4_mem_space)
209 {
210     /* Dependency manager state structure */
211     ps_mem_tab[DEP_MNGR_CTXT].i4_mem_size = sizeof(dep_mngr_state_t);
212     ps_mem_tab[DEP_MNGR_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
213     ps_mem_tab[DEP_MNGR_CTXT].i4_mem_alignment = 8;
214 
215     /**************** Get Processed status Memory Requirements *********************/
216     ps_mem_tab[DEP_MNGR_UNITS_PRCSD_MEM].i4_mem_size = (sizeof(WORD8) * num_units);
217     ps_mem_tab[DEP_MNGR_UNITS_PRCSD_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
218     ps_mem_tab[DEP_MNGR_UNITS_PRCSD_MEM].i4_mem_alignment = 8;
219 
220     /**************** Get Wait thread ids Memory Requirements *********************/
221     /* Map-mode: semaphore post is unconditionally done on all threads */
222     ps_mem_tab[DEP_MNGR_WAIT_THRD_ID_MEM].i4_mem_size = (sizeof(WORD32) * num_threads);
223     ps_mem_tab[DEP_MNGR_WAIT_THRD_ID_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
224     ps_mem_tab[DEP_MNGR_WAIT_THRD_ID_MEM].i4_mem_alignment = 8;
225 
226     /**************** Get Semaphore Requirements *********************/
227     ps_mem_tab[DEP_MNGR_SEM_HANDLE_MEM].i4_mem_size = (sizeof(void *) * num_threads);
228     ps_mem_tab[DEP_MNGR_SEM_HANDLE_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
229     ps_mem_tab[DEP_MNGR_SEM_HANDLE_MEM].i4_mem_alignment = 8;
230 
231     return (NUM_DEP_MNGR_MEM_RECS);
232 }
233 
234 /*!
235 ******************************************************************************
236 * \if Function name : ihevce_dmgr_rst_frm_frm_sync \endif
237 *
238 * \brief
239 *    Resets the values stored to init value
240 *
241 * \param[in,out]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
242 *
243 * \return
244 *    None
245 *
246 * \author
247 *  Ittiam
248 *
249 *****************************************************************************
250 */
ihevce_dmgr_rst_frm_frm_sync(void * pv_dep_mngr_state)251 void ihevce_dmgr_rst_frm_frm_sync(void *pv_dep_mngr_state)
252 {
253     dep_mngr_state_t *ps_dep_mngr_state;
254     WORD32 thrds;
255     ULWORD64 *pu8_num_units_proc_prev;
256     ULWORD64 *pu8_num_units_proc_curr;
257 
258     /* dep manager state structure */
259     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
260 
261     /* Reset the num units processed by each thread */
262     pu8_num_units_proc_curr = (ULWORD64 *)ps_dep_mngr_state->pv_units_prcsd_in_row;
263     pu8_num_units_proc_prev = pu8_num_units_proc_curr + ps_dep_mngr_state->i4_num_thrds;
264 
265     /* Reset the values thread ids waiting */
266     for(thrds = 0; thrds < ps_dep_mngr_state->i4_num_thrds; thrds++)
267     {
268         pu8_num_units_proc_prev[thrds] = 0;
269         pu8_num_units_proc_curr[thrds] = 0;
270         ps_dep_mngr_state->pi4_wait_thrd_id[thrds] = -1;
271     }
272 
273     return;
274 }
275 
276 /*!
277 ******************************************************************************
278 * \if Function name : ihevce_dmgr_rst_row_frm_sync \endif
279 *
280 * \brief
281 *    Resets the values stored to init value
282 *
283 * \param[in,out]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
284 *
285 * \return
286 *    None
287 *
288 * \author
289 *  Ittiam
290 *
291 *****************************************************************************
292 */
ihevce_dmgr_rst_row_frm_sync(void * pv_dep_mngr_state)293 void ihevce_dmgr_rst_row_frm_sync(void *pv_dep_mngr_state)
294 {
295     dep_mngr_state_t *ps_dep_mngr_state;
296     WORD32 ctr, thrds;
297 
298     /* dep manager state structure */
299     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
300 
301     /* Reset the values of number of units processed in a row */
302     for(ctr = 0; ctr < ps_dep_mngr_state->i4_num_vert_units; ctr++)
303     {
304         ((WORD32 *)ps_dep_mngr_state->pv_units_prcsd_in_row)[ctr] = 0;
305     }
306 
307     /* Reset the values thread ids waiting on each row  */
308     for(ctr = 0; ctr < ps_dep_mngr_state->i4_num_vert_units; ctr++)
309     {
310         for(thrds = 0; thrds < ps_dep_mngr_state->i4_num_thrds; thrds++)
311         {
312             ps_dep_mngr_state->pi4_wait_thrd_id[thrds + (ps_dep_mngr_state->i4_num_thrds * ctr)] =
313                 -1;
314         }
315     }
316 
317     return;
318 }
319 
320 /*!
321 ******************************************************************************
322 * \if Function name : ihevce_dmgr_map_rst_sync \endif
323 *
324 * \brief
325 *    Resets the values stored to init value
326 *
327 * \param[in,out]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
328 *
329 * \return
330 *    None
331 *
332 * \author
333 *  Ittiam
334 *
335 *****************************************************************************
336 */
ihevce_dmgr_map_rst_sync(void * pv_dep_mngr_state)337 void ihevce_dmgr_map_rst_sync(void *pv_dep_mngr_state)
338 {
339     dep_mngr_state_t *ps_dep_mngr_state;
340     WORD8 *pi1_ptr;
341 
342     /* dep manager state structure */
343     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
344 
345     pi1_ptr = (WORD8 *)ps_dep_mngr_state->pv_units_prcsd_in_row -
346               ps_dep_mngr_state->ai4_tile_xtra_ctb[0] * ps_dep_mngr_state->i4_num_horz_units -
347               ps_dep_mngr_state->ai4_tile_xtra_ctb[1];
348 
349     memset(
350         pi1_ptr,
351         MAP_CTB_INIT,
352         ps_dep_mngr_state->i4_num_vert_units * ps_dep_mngr_state->i4_num_horz_units *
353             sizeof(WORD8));
354 
355     //ps_dep_mngr_state->i4_frame_map_complete = 0;
356 
357     return;
358 }
359 
360 /*!
361 ******************************************************************************
362 * \if Function name : ihevce_dmgr_rst_row_row_sync \endif
363 *
364 * \brief
365 *    Resets the values stored to init value
366 *
367 * \param[in,out]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
368 *
369 * \return
370 *    None
371 *
372 * \author
373 *  Ittiam
374 *
375 *****************************************************************************
376 */
ihevce_dmgr_rst_row_row_sync(void * pv_dep_mngr_state)377 void ihevce_dmgr_rst_row_row_sync(void *pv_dep_mngr_state)
378 {
379     dep_mngr_state_t *ps_dep_mngr_state;
380     WORD32 ctr;
381 
382     /* dep manager state structure */
383     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
384 
385     /* Reset the values of number of units processed in a row */
386     for(ctr = 0; ctr < (ps_dep_mngr_state->i4_num_vert_units * ps_dep_mngr_state->i4_num_tile_cols);
387         ctr++)
388     {
389         ((WORD32 *)ps_dep_mngr_state->pv_units_prcsd_in_row)[ctr] = 0;
390     }
391 
392     /* Reset the values thread ids waiting on each row  */
393     for(ctr = 0; ctr < ps_dep_mngr_state->i4_num_vert_units; ctr++)
394     {
395         ps_dep_mngr_state->pi4_wait_thrd_id[ctr] = -1;
396     }
397 
398     return;
399 }
400 
401 /*!
402 ******************************************************************************
403 * \if Function name : ihevce_dmgr_init \endif
404 *
405 * \brief
406 *    Intialization for Dependency manager state structure .
407 *
408 * \param[in] ps_mem_tab : pointer to memory descriptors table
409 * \param[in] pv_osal_handle : osal handle
410 * \param[in] dep_mngr_mode : Mode of operation of dependency manager
411 * \param[in] max_num_vert_units : Maximum nunber of units to be processed (Frame Data)
412 * \param[in] max_num_horz_units : Maximun Number of Horizontal units to be processed (Frame Data)
413 * \param[in] num_tile_cols : Number of column tiles for which encoder is working
414 * \param[in] sem_enable : Whether you want to enable semaphore or not
415              1 : Sem. Enabled, 0 : Spin lock enabled (do-while)
416 * \param[in] num_threads : Number of threads among which sync will be established
417 * \param[in] i4_mem_space : memspace in which memory request should be do
418 *
419 * \return
420 *    Handle to context
421 *
422 * \author
423 *  Ittiam
424 *
425 *****************************************************************************
426 */
ihevce_dmgr_init(iv_mem_rec_t * ps_mem_tab,void * pv_osal_handle,WORD32 dep_mngr_mode,WORD32 max_num_vert_units,WORD32 max_num_horz_units,WORD32 num_tile_cols,WORD32 num_threads,WORD32 sem_enable)427 void *ihevce_dmgr_init(
428     iv_mem_rec_t *ps_mem_tab,
429     void *pv_osal_handle,
430     WORD32 dep_mngr_mode,
431     WORD32 max_num_vert_units,
432     WORD32 max_num_horz_units,
433     WORD32 num_tile_cols,
434     WORD32 num_threads,
435     WORD32 sem_enable)
436 {
437     dep_mngr_state_t *ps_dep_mngr_state;
438 
439     (void)pv_osal_handle;
440     /* dep manager state structure */
441     ps_dep_mngr_state = (dep_mngr_state_t *)ps_mem_tab[DEP_MNGR_CTXT].pv_base;
442 
443     /* dep manager memory init */
444     ps_dep_mngr_state->ppv_thrd_sem_handles = (void **)ps_mem_tab[DEP_MNGR_SEM_HANDLE_MEM].pv_base;
445     ps_dep_mngr_state->pi4_wait_thrd_id = (WORD32 *)ps_mem_tab[DEP_MNGR_WAIT_THRD_ID_MEM].pv_base;
446     ps_dep_mngr_state->pv_units_prcsd_in_row = ps_mem_tab[DEP_MNGR_UNITS_PRCSD_MEM].pv_base;
447 
448     /* SANITY CHECK */
449     ASSERT(NULL != pv_osal_handle);
450     ASSERT(
451         (DEP_MNGR_FRM_FRM_SYNC == dep_mngr_mode) || (DEP_MNGR_ROW_FRM_SYNC == dep_mngr_mode) ||
452         (DEP_MNGR_ROW_ROW_SYNC == dep_mngr_mode));
453 
454     /* Default value */
455     if(num_tile_cols < 1)
456     {
457         num_tile_cols = 1;
458     }
459 
460     /* reset the state structure variables */
461     ps_dep_mngr_state->i4_num_horz_units = max_num_horz_units;
462     ps_dep_mngr_state->i4_num_vert_units = max_num_vert_units;
463     ps_dep_mngr_state->i1_sem_enable = sem_enable;
464     ps_dep_mngr_state->i4_dep_mngr_mode = dep_mngr_mode;
465     ps_dep_mngr_state->i4_num_thrds = num_threads;
466     ps_dep_mngr_state->i4_num_tile_cols = num_tile_cols;
467 
468     /* call the reset function baed on mode */
469     if(DEP_MNGR_FRM_FRM_SYNC == dep_mngr_mode)
470     {
471         ihevce_dmgr_rst_frm_frm_sync((void *)ps_dep_mngr_state);
472     }
473     else if(DEP_MNGR_ROW_ROW_SYNC == dep_mngr_mode)
474     {
475         ihevce_dmgr_rst_row_row_sync((void *)ps_dep_mngr_state);
476     }
477     else
478     {
479         ihevce_dmgr_rst_row_frm_sync((void *)ps_dep_mngr_state);
480     }
481 
482     return ((void *)ps_dep_mngr_state);
483 }
484 
485 /*!
486 ******************************************************************************
487 * \if Function name : ihevce_dmgr_map_init \endif
488 *
489 * \brief
490 *    Intialization for Dependency manager state structure .
491 *
492 * \param[in] ps_mem_tab : pointer to memory descriptors table
493 * \param[in] max_num_vert_units : Maximum nunber of units to be processed
494 * \param[in] max_num_horz_units : Maximun Number of Horizontal units to be processed
495 * \param[in] sem_enable : Whether you want to enable semaphore or not
496              1 : Sem. Enabled, 0 : Spin lock enabled (do-while)
497 * \param[in] num_threads : Number of threads among which sync will be established
498 * \param[in] ai4_tile_xtra_ctb : Array containing the number of CTBs which are
499 *            are present in the Search Range outside the tile in dist-client mode.
500 *            In standalone mode this array should be zero.
501 *
502 * \return
503 *    Handle to context
504 *
505 * \author
506 *  Ittiam
507 *
508 *****************************************************************************
509 */
ihevce_dmgr_map_init(iv_mem_rec_t * ps_mem_tab,WORD32 max_num_vert_units,WORD32 max_num_horz_units,WORD32 sem_enable,WORD32 num_threads,WORD32 ai4_tile_xtra_ctb[4])510 void *ihevce_dmgr_map_init(
511     iv_mem_rec_t *ps_mem_tab,
512     WORD32 max_num_vert_units,
513     WORD32 max_num_horz_units,
514     WORD32 sem_enable,
515     WORD32 num_threads,
516     WORD32 ai4_tile_xtra_ctb[4])
517 {
518     WORD32 ctr;
519     dep_mngr_state_t *ps_dep_mngr_state;
520 
521     /* dep manager state structure */
522     ps_dep_mngr_state = (dep_mngr_state_t *)ps_mem_tab[DEP_MNGR_CTXT].pv_base;
523 
524     ps_dep_mngr_state->ai4_tile_xtra_ctb[0] = ai4_tile_xtra_ctb[0];
525     ps_dep_mngr_state->ai4_tile_xtra_ctb[1] = ai4_tile_xtra_ctb[1];
526     ps_dep_mngr_state->ai4_tile_xtra_ctb[2] = ai4_tile_xtra_ctb[2];
527     ps_dep_mngr_state->ai4_tile_xtra_ctb[3] = ai4_tile_xtra_ctb[3];
528 
529     /* dep manager memory init */
530     ps_dep_mngr_state->pv_units_prcsd_in_row = ps_mem_tab[DEP_MNGR_UNITS_PRCSD_MEM].pv_base;
531     ps_dep_mngr_state->pi4_wait_thrd_id = (WORD32 *)ps_mem_tab[DEP_MNGR_WAIT_THRD_ID_MEM].pv_base;
532     ps_dep_mngr_state->ppv_thrd_sem_handles = (void **)ps_mem_tab[DEP_MNGR_SEM_HANDLE_MEM].pv_base;
533 
534     /* Pointing to first CTB of tile */
535     ps_dep_mngr_state->pv_units_prcsd_in_row =
536         (void*)((WORD8*)ps_dep_mngr_state->pv_units_prcsd_in_row +
537         ps_dep_mngr_state->ai4_tile_xtra_ctb[1] +
538         max_num_horz_units * ps_dep_mngr_state->ai4_tile_xtra_ctb[0]);
539 
540     /* Map-mode: semaphore post is unconditionally done on all threads. Hence
541     store these one time IDs. The use of pi4_wait_thrd_id itself can be removed
542     altogether for map-mode, but keeping it for the sake of laziness  */
543     for(ctr = 0; ctr < num_threads; ctr++)
544     {
545         ps_dep_mngr_state->pi4_wait_thrd_id[ctr] = ctr;
546     }
547 
548     /* reset the state structure variables */
549     ps_dep_mngr_state->i4_num_horz_units = max_num_horz_units;
550     ps_dep_mngr_state->i4_num_vert_units = max_num_vert_units;
551     ps_dep_mngr_state->i1_sem_enable = sem_enable;
552     ps_dep_mngr_state->i4_dep_mngr_mode = DEP_MNGR_MAP_SYNC;
553     ps_dep_mngr_state->i4_num_thrds = num_threads;
554 
555     /* call the reset function baed on mode */
556     ihevce_dmgr_map_rst_sync((void *)ps_dep_mngr_state);
557 
558     return ((void *)ps_dep_mngr_state);
559 }
560 
561 /*!
562 ******************************************************************************
563 * \if Function name : ihevce_dmgr_del \endif
564 *
565 * \brief
566 *    Delete the Dependency manager state structure.
567 * Note : Destroys the mutex only. System has to free the allocated memory
568 *
569 * \param[in,out]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
570 *
571 * \return
572 *    None
573 *
574 * \author
575 *  Ittiam
576 *
577 *****************************************************************************
578 */
ihevce_dmgr_del(void * pv_dep_mngr_state)579 void ihevce_dmgr_del(void *pv_dep_mngr_state)
580 {
581     dep_mngr_state_t *ps_dep_mngr_state;
582 
583     /* dep manager state structure */
584     (void)ps_dep_mngr_state;
585     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
586 }
587 
588 /*!
589 ******************************************************************************
590 * \if Function name : ihevce_dmgr_register_sem_hdls \endif
591 *
592 * \brief
593 *    Register sem handles of threads wihci are part of dependency group
594 *
595 * \param[in,out]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
596 * \param[in] ppv_thread_sem_hdl : arry of pointer to all the sem handles
597 * \param[in] num_threads : Number of threads part of this dependency group
598 *
599 * \return
600 *    None
601 *
602 * \author
603 *  Ittiam
604 *
605 *****************************************************************************
606 */
ihevce_dmgr_reg_sem_hdls(void * pv_dep_mngr_state,void ** ppv_thread_sem_hdl,WORD32 num_threads)607 void ihevce_dmgr_reg_sem_hdls(void *pv_dep_mngr_state, void **ppv_thread_sem_hdl, WORD32 num_threads)
608 {
609     dep_mngr_state_t *ps_dep_mngr_state;
610     WORD32 ctr;
611 
612     /* dep manager state structure */
613     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
614 
615     ASSERT(num_threads <= ps_dep_mngr_state->i4_num_thrds);
616 
617     for(ctr = 0; ctr < num_threads; ctr++)
618     {
619         ps_dep_mngr_state->ppv_thrd_sem_handles[ctr] = ppv_thread_sem_hdl[ctr];
620     }
621 
622     return;
623 }
624 
625 /*!
626 ******************************************************************************
627 * \if Function name : ihevce_dmgr_set_prev_done_frm_frm_sync \endif
628 *
629 * \brief
630 *    Set the values to dependency not resolved state
631 *
632 * \param[in,out]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
633 *
634 * \return
635 *    None
636 *
637 * \author
638 *  Ittiam
639 *
640 *****************************************************************************
641 */
ihevce_dmgr_set_prev_done_frm_frm_sync(void * pv_dep_mngr_state)642 void ihevce_dmgr_set_prev_done_frm_frm_sync(void *pv_dep_mngr_state)
643 {
644     dep_mngr_state_t *ps_dep_mngr_state;
645     WORD32 thrds;
646     ULWORD64 *pu8_num_units_proc_curr;
647     ULWORD64 *pu8_num_units_proc_prev;
648 
649     /* dep manager state structure */
650     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
651 
652     /* Reset the values num threads entering processing state  */
653     pu8_num_units_proc_curr = (ULWORD64 *)ps_dep_mngr_state->pv_units_prcsd_in_row;
654     pu8_num_units_proc_prev =
655         (ULWORD64 *)(pu8_num_units_proc_curr + ps_dep_mngr_state->i4_num_thrds);
656 
657     /* Reset the values thread ids waiting */
658     for(thrds = 0; thrds < ps_dep_mngr_state->i4_num_thrds; thrds++)
659     {
660         pu8_num_units_proc_prev[thrds] = 1;
661         ps_dep_mngr_state->pi4_wait_thrd_id[thrds] = -1;
662     }
663 
664     return;
665 }
666 
667 /*!
668 ******************************************************************************
669 * \if Function name : ihevce_dmgr_set_done_frm_frm_sync \endif
670 *
671 * \brief
672 *    Set the values to dependency met state
673 *
674 * \param[in,out]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
675 *
676 * \return
677 *    None
678 *
679 * \author
680 *  Ittiam
681 *
682 *****************************************************************************
683 */
ihevce_dmgr_set_done_frm_frm_sync(void * pv_dep_mngr_state)684 void ihevce_dmgr_set_done_frm_frm_sync(void *pv_dep_mngr_state)
685 {
686     dep_mngr_state_t *ps_dep_mngr_state;
687     WORD32 thrds;
688     ULWORD64 *pu8_num_units_proc_curr;
689 
690     /* dep manager state structure */
691     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
692 
693     /* Reset the values num threads entering processing state  */
694     pu8_num_units_proc_curr = (ULWORD64 *)ps_dep_mngr_state->pv_units_prcsd_in_row;
695 
696     /* Reset the values thread ids waiting */
697     for(thrds = 0; thrds < ps_dep_mngr_state->i4_num_thrds; thrds++)
698     {
699         pu8_num_units_proc_curr[thrds] = 1;
700         ps_dep_mngr_state->pi4_wait_thrd_id[thrds] = -1;
701     }
702 
703     return;
704 }
705 
706 /*!
707 **************************************************************************
708 * \if Function name : ihevce_dmgr_chk_row_row_sync \endif
709 *
710 * \brief
711 *    This function checks whether the dependency is met to proceed with
712 *    processing. If condition is not met, it should go to a sem_wait state,
713 *    else start processing.
714 *
715 * \param[in]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
716 * \param[in]  cur_offset    : Current offset of the dep. variable
717 * \param[in]  dep_offset    : Offset from the current value to meet the dep.
718 * \param[in]  dep_row       : The position of the Ref.
719 * \param[in]  cur_tile_col  : The current column tile number (not tile id)
720 *   Assuming the dependency is within the tile only (Acroos tiles won't work now)
721 * \param[in]  thrd_id       : Thread id of the current thread checking for dependency
722 *
723 * \return
724 *    0 on Success and -1 on error
725 *
726 * \author
727 *  Ittiam
728 *
729 **************************************************************************
730 */
ihevce_dmgr_chk_row_row_sync(void * pv_dep_mngr_state,WORD32 cur_offset,WORD32 dep_offset,WORD32 dep_row,WORD32 cur_tile_col,WORD32 thrd_id)731 WORD32 ihevce_dmgr_chk_row_row_sync(
732     void *pv_dep_mngr_state,
733     WORD32 cur_offset,
734     WORD32 dep_offset,
735     WORD32 dep_row,
736     WORD32 cur_tile_col,
737     WORD32 thrd_id)
738 {
739     dep_mngr_state_t *ps_dep_mngr_state;
740     volatile WORD32 *pi4_ref_value;
741     WORD32 ref_value;
742 
743     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
744 
745     /* Sanity Check */
746     ASSERT(dep_row >= 0);
747     ASSERT(dep_row < ps_dep_mngr_state->i4_num_vert_units);
748     ASSERT(cur_tile_col >= 0);
749     ASSERT(cur_tile_col < ps_dep_mngr_state->i4_num_tile_cols);
750 
751     pi4_ref_value = ((volatile WORD32 *)(ps_dep_mngr_state->pv_units_prcsd_in_row)) +
752                     (cur_tile_col * ps_dep_mngr_state->i4_num_vert_units) + dep_row;
753 
754     /* Sanity Check */
755     ASSERT((cur_offset + dep_offset) <= ps_dep_mngr_state->i4_num_horz_units);
756 
757     /* Check whether Dep. is met */
758     while(1)
759     {
760         ref_value = *pi4_ref_value;
761 
762         if(ref_value >= (cur_offset + dep_offset))
763             break;
764 
765         if(1 == ps_dep_mngr_state->i1_sem_enable)
766         {
767             void *pv_sem_handle;
768             WORD32 ret_val;
769 
770             (void)ret_val;
771             pv_sem_handle = ps_dep_mngr_state->ppv_thrd_sem_handles[thrd_id];
772 
773             /* register the thread id before going to pend state */
774             ps_dep_mngr_state->pi4_wait_thrd_id[dep_row] = thrd_id;
775 
776             /* go to the pend state */
777             ret_val = osal_sem_wait(pv_sem_handle);
778             //ASSERT(0 == ret_val);
779         }
780     }
781 
782     return 0;
783 }
784 
785 /*!
786 **************************************************************************
787 * \if Function name : ihevce_dmgr_set_row_row_sync \endif
788 *
789 * \brief
790 *    This function sets the dependency and wakes up the proper semaphores
791 *    to start processing.
792 *
793 * \param[in]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
794 * \param[in]  cur_offset     : Current offset processed
795 * \param[in]  cur_row       : The cur. vertical position
796 * \param[in]  cur_tile_col  : The current column tile number (not tile id)
797 *   Assuming the dependency is within the tile only (Acroos tiles won't work now)
798 *
799 * \return
800 *    0 on Success and -1 on error
801 *
802 * \author
803 *  Ittiam
804 *
805 **************************************************************************
806 */
ihevce_dmgr_set_row_row_sync(void * pv_dep_mngr_state,WORD32 cur_offset,WORD32 cur_row,WORD32 cur_tile_col)807 WORD32 ihevce_dmgr_set_row_row_sync(
808     void *pv_dep_mngr_state, WORD32 cur_offset, WORD32 cur_row, WORD32 cur_tile_col)
809 {
810     dep_mngr_state_t *ps_dep_mngr_state;
811     WORD32 *pi4_units_prcsd;
812     void *pv_sem_handle;
813     WORD32 ret_val;
814 
815     (void)ret_val;
816     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
817 
818     /* Sanity Check */
819     ASSERT(cur_offset >= 0);
820     ASSERT(cur_offset <= ps_dep_mngr_state->i4_num_horz_units);
821     ASSERT(cur_row <= ps_dep_mngr_state->i4_num_vert_units);
822     ASSERT(cur_tile_col >= 0);
823     ASSERT(cur_tile_col < ps_dep_mngr_state->i4_num_tile_cols);
824 
825     DATA_SYNC();
826 
827     pi4_units_prcsd = ((WORD32 *)(ps_dep_mngr_state->pv_units_prcsd_in_row)) +
828                       (cur_tile_col * ps_dep_mngr_state->i4_num_vert_units) + cur_row;
829 
830     /* Update the number of units processed */
831     *pi4_units_prcsd = cur_offset;
832 
833     if(1 == ps_dep_mngr_state->i1_sem_enable)
834     {
835         WORD32 wait_thrd_id;
836 
837         wait_thrd_id = ps_dep_mngr_state->pi4_wait_thrd_id[cur_row];
838 
839         /* Post on threads waiting on the current row */
840         if(-1 != wait_thrd_id)
841         {
842             pv_sem_handle = ps_dep_mngr_state->ppv_thrd_sem_handles[wait_thrd_id];
843             /* Post on the semaphore */
844             ret_val = osal_sem_post(pv_sem_handle);
845             //ASSERT(0 == ret_val);
846 
847             ps_dep_mngr_state->pi4_wait_thrd_id[cur_row] = -1;
848         }
849 
850         /* towards end of row all threads are posted (to avoid any corner cases) */
851         if(cur_offset == ps_dep_mngr_state->i4_num_horz_units)
852         {
853             WORD32 ctr;
854 
855             for(ctr = 0; ctr < ps_dep_mngr_state->i4_num_thrds; ctr++)
856             {
857                 ret_val = osal_sem_post(ps_dep_mngr_state->ppv_thrd_sem_handles[ctr]);
858                 //ASSERT(0 == ret_val);
859             }
860         }
861     }
862 
863     return 0;
864 }
865 
866 /*!
867 **************************************************************************
868 * \if Function name : ihevce_dmgr_chk_frm_frm_sync \endif
869 *
870 * \brief
871 *    This function checks whether the dependency is met to proceed with
872 *    processing. If condition is not met, it should go to a sem_wait state,
873 *    else start processing.
874 *    For Barrier case, the thread will wait till all threads have completed
875 *    the processing on the previosu instance of same stage
876 * \param[in]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
877 * \param[in]  thrd_id       : Thread id checking for dependency
878 *
879 * \return
880 *    0 on Success and -1 on error
881 *
882 * \author
883 *  Ittiam
884 *
885 **************************************************************************
886 */
ihevce_dmgr_chk_frm_frm_sync(void * pv_dep_mngr_state,WORD32 thrd_id)887 WORD32 ihevce_dmgr_chk_frm_frm_sync(void *pv_dep_mngr_state, WORD32 thrd_id)
888 {
889     dep_mngr_state_t *ps_dep_mngr_state;
890     void *pv_sem_handle;
891     volatile ULWORD64 *pu8_num_units_proc_prev;
892     volatile ULWORD64 *pu8_num_units_proc_curr;
893     ULWORD64 prev_value;
894     ULWORD64 curr_value;
895 
896     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
897     pv_sem_handle = ps_dep_mngr_state->ppv_thrd_sem_handles[thrd_id];
898 
899     pu8_num_units_proc_curr = (volatile ULWORD64 *)ps_dep_mngr_state->pv_units_prcsd_in_row;
900     pu8_num_units_proc_prev =
901         (volatile ULWORD64 *)(pu8_num_units_proc_curr + ps_dep_mngr_state->i4_num_thrds);
902 
903     /* Check whether Dep. is met */
904     while(1)
905     {
906         WORD32 ret_val;
907 
908         (void)ret_val;
909         curr_value = pu8_num_units_proc_curr[thrd_id];
910         prev_value = pu8_num_units_proc_prev[thrd_id];
911 
912         if(curr_value == (prev_value + 1))
913         {
914             break;
915         }
916         else
917         {
918             /* register the thread id before going to pend state */
919             ps_dep_mngr_state->pi4_wait_thrd_id[thrd_id] = thrd_id;
920 
921             /* go to the pend state */
922             ret_val = osal_sem_wait(pv_sem_handle);
923             //ASSERT(0 == ret_val);
924         }
925     }
926 
927     /* store curr value to prev for next iteration */
928     pu8_num_units_proc_prev[thrd_id] = pu8_num_units_proc_curr[thrd_id];
929 
930     return 0;
931 }
932 
933 /*!
934 **************************************************************************
935 * \if Function name : ihevce_dmgr_update_frm_frm_sync \endif
936 *
937 * \brief
938 *    This function sets the dependency and wakes up the proper semaphores
939 *    to start processing.
940 *    For barrier case, if the dep. is met, all waiting threads should be waked up
941 *
942 * \param[in]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
943 *
944 * \return
945 *    0 on Success and -1 on error
946 *
947 * \author
948 *  Ittiam
949 *
950 **************************************************************************
951 */
ihevce_dmgr_update_frm_frm_sync(void * pv_dep_mngr_state)952 WORD32 ihevce_dmgr_update_frm_frm_sync(void *pv_dep_mngr_state)
953 {
954     dep_mngr_state_t *ps_dep_mngr_state;
955     void *pv_sem_handle;
956     volatile ULWORD64 *pu8_num_units_proc_curr;
957     WORD32 ctr;
958 
959     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
960 
961     pu8_num_units_proc_curr = (volatile ULWORD64 *)ps_dep_mngr_state->pv_units_prcsd_in_row;
962 
963     /* Post on All vertical waiting threads semaphores & update the cur unit proc */
964     for(ctr = 0; ctr < ps_dep_mngr_state->i4_num_thrds; ctr++)
965     {
966         WORD32 ret_val;
967         WORD32 wait_thrd_id;
968 
969         (void)ret_val;
970         /* increment the curr unit counter for all threads */
971         pu8_num_units_proc_curr[ctr] = pu8_num_units_proc_curr[ctr] + 1;
972 
973         wait_thrd_id = ctr;
974         //wait_thrd_id    = ps_dep_mngr_state->pi4_wait_thrd_id[ctr];
975 
976         if(-1 != wait_thrd_id)
977         {
978             pv_sem_handle = ps_dep_mngr_state->ppv_thrd_sem_handles[wait_thrd_id];
979             /* Post on the semaphore */
980             ret_val = osal_sem_post(pv_sem_handle);
981             //ASSERT(0 == ret_val);
982 
983             ps_dep_mngr_state->pi4_wait_thrd_id[ctr] = -1;
984         }
985     }
986 
987     return 0;
988 }
989 
990 /*!
991 **************************************************************************
992 * \if Function name : ihevce_dmgr_map_chk \endif
993 *
994 * \brief
995 *   This function checks whether all entries in the dependency map are set
996 *
997 * \param[in]  pu1_start    : Pointer to the start of the search area
998 * \param[in]  i4_num_ctb_x : Size   of search area
999 * \param[in]  i4_num_ctb_y : Size   of search area
1000 * \param[in]  i4_stride    : Stride of search area
1001 *
1002 * \return
1003 *    1 on Success otherwise 0
1004 *
1005 * \author
1006 *  Ittiam
1007 *
1008 **************************************************************************
1009 */
1010 WORD32
ihevce_dmgr_map_chk(WORD8 * pu1_start,WORD32 i4_num_ctb_x,WORD32 i4_num_ctb_y,WORD32 i4_stride)1011     ihevce_dmgr_map_chk(WORD8 *pu1_start, WORD32 i4_num_ctb_x, WORD32 i4_num_ctb_y, WORD32 i4_stride)
1012 {
1013     WORD8 *pi1_ctb = pu1_start;
1014     WORD32 row, col;
1015     WORD32 map_ready_flag = MAP_CTB_COMPLETE;
1016 
1017     for(row = 0; row < i4_num_ctb_y; row++)
1018     {
1019         for(col = 0; col < i4_num_ctb_x; col++)
1020         {
1021             map_ready_flag &= pi1_ctb[col];
1022         }
1023         pi1_ctb += i4_stride;
1024     }
1025 
1026     /* NOTE: early exit in the above loop can taken if map_ready_flag
1027     is found to be zero somewhere at the start itself */
1028     return (map_ready_flag == MAP_CTB_COMPLETE);
1029 }
1030 
1031 /*!
1032 **************************************************************************
1033 * \if Function name : ihevce_dmgr_map_chk_sync \endif
1034 *
1035 * \brief
1036 *   This function checks whether the dependency is met by searching in a
1037 *   rectangular area. If condition is not met, it should go to a sem_wait state,
1038 *    else start processing.
1039 *
1040 * \param[in]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
1041 * \param[in]  thrd_id     : Thread id of the current thread checking for dependency
1042 * \param[in]  offset_x    : Offset of current CTB in Tile in ctb-unit
1043 * \param[in]  offset_y    : Offset of current CTB in Tile in ctb-unit
1044 * \param[in]  i4_sr_ctb_x : Search Range in ctb-unit
1045 * \param[in]  i4_sr_ctb_y : Search Range in ctb-unit
1046 *
1047 * \return
1048 *    0 on Success and -1 on error
1049 *
1050 * \author
1051 *  Ittiam
1052 *
1053 **************************************************************************
1054 */
ihevce_dmgr_map_chk_sync(void * pv_dep_mngr_state,WORD32 thrd_id,WORD32 offset_x,WORD32 offset_y,WORD32 i4_sr_ctb_x,WORD32 i4_sr_ctb_y)1055 WORD32 ihevce_dmgr_map_chk_sync(
1056     void *pv_dep_mngr_state,
1057     WORD32 thrd_id,
1058     WORD32 offset_x,
1059     WORD32 offset_y,
1060     WORD32 i4_sr_ctb_x,
1061     WORD32 i4_sr_ctb_y)
1062 {
1063     dep_mngr_state_t *ps_dep_mngr_state;
1064     volatile WORD8 *pi1_ctb;
1065     WORD8 *pi1_tile_start;
1066     WORD32 i4_avail_left, i4_avail_right, i4_avail_top, i4_avail_bot;
1067     WORD32 i4_num_ctb_x, i4_num_ctb_y;
1068     WORD32 i4_stride;
1069     WORD32 i4_tile_wd, i4_tile_ht;  //in ctb units
1070 
1071     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
1072 
1073     i4_tile_wd = ps_dep_mngr_state->i4_num_horz_units - ps_dep_mngr_state->ai4_tile_xtra_ctb[1] -
1074                  ps_dep_mngr_state->ai4_tile_xtra_ctb[2];
1075 
1076     i4_tile_ht = ps_dep_mngr_state->i4_num_vert_units - ps_dep_mngr_state->ai4_tile_xtra_ctb[0] -
1077                  ps_dep_mngr_state->ai4_tile_xtra_ctb[3];
1078 
1079     i4_stride = ps_dep_mngr_state->i4_num_horz_units;
1080 
1081     /* Sanity Checks, confirm if ctb offsets are within tiles */
1082     ASSERT(offset_x >= 0);
1083     ASSERT(offset_y >= 0);
1084     ASSERT(offset_x < i4_tile_wd);
1085     ASSERT(offset_y < i4_tile_ht);
1086 
1087     pi1_tile_start = (WORD8 *)ps_dep_mngr_state->pv_units_prcsd_in_row;
1088     pi1_ctb = (volatile WORD8 *)pi1_tile_start;
1089 
1090     if(ps_dep_mngr_state->ai4_tile_xtra_ctb[0])
1091     {
1092         i4_avail_top = i4_sr_ctb_y;
1093     }
1094     else
1095     {
1096         i4_avail_top = MIN(i4_sr_ctb_y, offset_y);
1097     }
1098 
1099     if(ps_dep_mngr_state->ai4_tile_xtra_ctb[1])
1100     {
1101         i4_avail_left = i4_sr_ctb_x;
1102     }
1103     else
1104     {
1105         i4_avail_left = MIN(i4_sr_ctb_x, offset_x);
1106     }
1107 
1108     if(ps_dep_mngr_state->ai4_tile_xtra_ctb[2])
1109     {
1110         i4_avail_right = i4_sr_ctb_x;
1111     }
1112     else
1113     {
1114         i4_avail_right = MIN(i4_sr_ctb_x, (i4_tile_wd - offset_x - 1));
1115     }
1116 
1117     if(ps_dep_mngr_state->ai4_tile_xtra_ctb[3])
1118     {
1119         i4_avail_bot = i4_sr_ctb_y;
1120     }
1121     else
1122     {
1123         i4_avail_bot = MIN(i4_sr_ctb_y, (i4_tile_ht - offset_y - 1));
1124     }
1125 
1126     i4_num_ctb_x = (i4_avail_left + 1 + i4_avail_right);
1127     i4_num_ctb_y = (i4_avail_top + 1 + i4_avail_bot);
1128 
1129     /* Point to the start of the search-area */
1130     pi1_ctb += ((offset_y - i4_avail_top) * i4_stride + (offset_x - i4_avail_left));
1131 
1132     /* Check whether Dep. is met */
1133     while(1)
1134     {
1135         if(1 == ihevce_dmgr_map_chk((WORD8 *)pi1_ctb, i4_num_ctb_x, i4_num_ctb_y, i4_stride))
1136         {
1137             break;
1138         }
1139         else
1140         {
1141             if(1 == ps_dep_mngr_state->i1_sem_enable)
1142             {
1143                 osal_sem_wait(ps_dep_mngr_state->ppv_thrd_sem_handles[thrd_id]);
1144             }
1145         }
1146     }
1147 
1148     return 0;
1149 }
1150 
1151 /*!
1152 **************************************************************************
1153 * \if Function name : ihevce_dmgr_map_set_sync \endif
1154 *
1155 * \brief
1156 *    This function sets the dependency and wakes up the proper semaphores
1157 *    to start processing.
1158 *
1159 * \param[in]  pv_dep_mngr_state  : Pointer to Sync Manager handle.
1160 * \param[in]  offset_x           : Offset of current CTB in Tile(ctb unit)
1161 * \param[in]  offset_y           : Offset of current CTB in Tile(ctb unit)
1162 *
1163 * \return
1164 *    0 on Success and -1 on error
1165 *
1166 * \author
1167 *  Ittiam
1168 *
1169 **************************************************************************
1170 */
ihevce_dmgr_map_set_sync(void * pv_dep_mngr_state,WORD32 offset_x,WORD32 offset_y,WORD32 i4_map_value)1171 WORD32 ihevce_dmgr_map_set_sync(
1172     void *pv_dep_mngr_state, WORD32 offset_x, WORD32 offset_y, WORD32 i4_map_value)
1173 {
1174     dep_mngr_state_t *ps_dep_mngr_state;
1175     WORD8 *pi1_tile_start;
1176     WORD32 map_stride;
1177 
1178     ps_dep_mngr_state = (dep_mngr_state_t *)pv_dep_mngr_state;
1179 
1180     /* Sanity Checks */
1181     ASSERT(offset_x >= (-ps_dep_mngr_state->ai4_tile_xtra_ctb[1]));
1182     ASSERT(offset_y >= (-ps_dep_mngr_state->ai4_tile_xtra_ctb[0]));
1183 
1184     ASSERT(
1185         offset_x <
1186         (ps_dep_mngr_state->i4_num_horz_units - ps_dep_mngr_state->ai4_tile_xtra_ctb[1]));
1187 
1188     ASSERT(
1189         offset_y <
1190         (ps_dep_mngr_state->i4_num_vert_units - ps_dep_mngr_state->ai4_tile_xtra_ctb[0]));
1191 
1192     DATA_SYNC();
1193 
1194     map_stride = ps_dep_mngr_state->i4_num_horz_units;
1195 
1196     pi1_tile_start = (WORD8 *)ps_dep_mngr_state->pv_units_prcsd_in_row;
1197 
1198     /* Set the flag to indicate that this CTB has been processed */
1199     *(pi1_tile_start + offset_y * map_stride + offset_x) = (WORD8)i4_map_value;
1200 
1201     if(1 == ps_dep_mngr_state->i1_sem_enable)
1202     {
1203         WORD32 wait_thrd_id;
1204 
1205         /* Post on threads waiting on the current row */
1206         for(wait_thrd_id = 0; wait_thrd_id < ps_dep_mngr_state->i4_num_thrds; wait_thrd_id++)
1207         {
1208             /* Post on the semaphore */
1209             /* Map-mode: semaphore post is unconditionally done on all threads */
1210             osal_sem_post(ps_dep_mngr_state->ppv_thrd_sem_handles[wait_thrd_id]);
1211         }
1212     }
1213 
1214     return 0;
1215 }
1216