Line data Source code
1 : /*
2 : * Copyright(c) 2019 Intel Corporation
3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 : */
5 :
6 : #include <stdlib.h>
7 :
8 : #include "EbSystemResourceManager.h"
9 :
10 384 : void EbFifoDctor(EbPtr p)
11 : {
12 384 : EbFifo *obj = (EbFifo*)p;
13 384 : EB_DESTROY_SEMAPHORE(obj->counting_semaphore);
14 384 : EB_DESTROY_MUTEX(obj->lockout_mutex);
15 384 : }
16 : /**************************************
17 : * EbFifoCtor
18 : **************************************/
19 384 : static EbErrorType EbFifoCtor(
20 : EbFifo *fifoPtr,
21 : uint32_t initial_count,
22 : uint32_t max_count,
23 : EbObjectWrapper *firstWrapperPtr,
24 : EbObjectWrapper *lastWrapperPtr,
25 : EbMuxingQueue *queue_ptr)
26 : {
27 384 : fifoPtr->dctor = EbFifoDctor;
28 : // Create Counting Semaphore
29 384 : EB_CREATE_SEMAPHORE(fifoPtr->counting_semaphore, initial_count, max_count);
30 :
31 : // Create Buffer Pool Mutex
32 384 : EB_CREATE_MUTEX(fifoPtr->lockout_mutex);
33 :
34 : // Initialize Fifo First & Last ptrs
35 384 : fifoPtr->first_ptr = firstWrapperPtr;
36 384 : fifoPtr->last_ptr = lastWrapperPtr;
37 :
38 : // Copy the Muxing Queue ptr this Fifo belongs to
39 384 : fifoPtr->queue_ptr = queue_ptr;
40 :
41 384 : return EB_ErrorNone;
42 : }
43 :
44 : /**************************************
45 : * EbFifoPushBack
46 : **************************************/
47 52252 : static EbErrorType EbFifoPushBack(
48 : EbFifo *fifoPtr,
49 : EbObjectWrapper *wrapper_ptr)
50 : {
51 52252 : EbErrorType return_error = EB_ErrorNone;
52 :
53 : // If FIFO is empty
54 52252 : if (fifoPtr->first_ptr == (EbObjectWrapper*)EB_NULL) {
55 52252 : fifoPtr->first_ptr = wrapper_ptr;
56 52252 : fifoPtr->last_ptr = wrapper_ptr;
57 : }
58 : else {
59 0 : fifoPtr->last_ptr->next_ptr = wrapper_ptr;
60 0 : fifoPtr->last_ptr = wrapper_ptr;
61 : }
62 :
63 52252 : fifoPtr->last_ptr->next_ptr = (EbObjectWrapper*)EB_NULL;
64 :
65 52252 : return return_error;
66 : }
67 :
68 : /**************************************
69 : * EbFifoPopFront
70 : **************************************/
71 52180 : static EbErrorType EbFifoPopFront(
72 : EbFifo *fifoPtr,
73 : EbObjectWrapper **wrapper_ptr)
74 : {
75 52180 : EbErrorType return_error = EB_ErrorNone;
76 :
77 : // Set wrapper_ptr to head of BufferPool
78 52180 : *wrapper_ptr = fifoPtr->first_ptr;
79 :
80 : // Update tail of BufferPool if the BufferPool is now empty
81 52180 : fifoPtr->last_ptr = (fifoPtr->first_ptr == fifoPtr->last_ptr) ? (EbObjectWrapper*)EB_NULL : fifoPtr->last_ptr;
82 :
83 : // Update head of BufferPool
84 52180 : fifoPtr->first_ptr = fifoPtr->first_ptr->next_ptr;
85 :
86 52180 : return return_error;
87 : }
88 :
89 148 : void EbCircularBufferDctor(EbPtr p)
90 : {
91 148 : EbCircularBuffer* obj = (EbCircularBuffer*)p;
92 148 : EB_FREE(obj->array_ptr);
93 148 : }
94 :
95 : /**************************************
96 : * EbCircularBufferCtor
97 : **************************************/
98 148 : static EbErrorType EbCircularBufferCtor(
99 : EbCircularBuffer *bufferPtr,
100 : uint32_t buffer_total_count)
101 : {
102 148 : bufferPtr->dctor = EbCircularBufferDctor;
103 :
104 148 : bufferPtr->buffer_total_count = buffer_total_count;
105 :
106 148 : EB_CALLOC(bufferPtr->array_ptr, bufferPtr->buffer_total_count, sizeof(EbPtr));
107 :
108 148 : return EB_ErrorNone;
109 : }
110 :
111 : /**************************************
112 : * EbCircularBufferEmptyCheck
113 : **************************************/
114 294832 : static EbBool EbCircularBufferEmptyCheck(
115 : EbCircularBuffer *bufferPtr)
116 : {
117 294832 : return ((bufferPtr->head_index == bufferPtr->tail_index) && (bufferPtr->array_ptr[bufferPtr->head_index] == EB_NULL)) ? EB_TRUE : EB_FALSE;
118 : }
119 :
120 : /**************************************
121 : * EbCircularBufferPopFront
122 : **************************************/
123 104389 : static EbErrorType EbCircularBufferPopFront(
124 : EbCircularBuffer *bufferPtr,
125 : EbPtr *object_ptr)
126 : {
127 104389 : EbErrorType return_error = EB_ErrorNone;
128 :
129 : // Copy the head of the buffer into the object_ptr
130 104389 : *object_ptr = bufferPtr->array_ptr[bufferPtr->head_index];
131 104389 : bufferPtr->array_ptr[bufferPtr->head_index] = EB_NULL;
132 :
133 : // Increment the head & check for rollover
134 104389 : bufferPtr->head_index = (bufferPtr->head_index == bufferPtr->buffer_total_count - 1) ? 0 : bufferPtr->head_index + 1;
135 :
136 : // Decrement the Current Count
137 104389 : --bufferPtr->current_count;
138 :
139 104389 : return return_error;
140 : }
141 :
142 : /**************************************
143 : * EbCircularBufferPushBack
144 : **************************************/
145 34971 : static EbErrorType EbCircularBufferPushBack(
146 : EbCircularBuffer *bufferPtr,
147 : EbPtr object_ptr)
148 : {
149 34971 : EbErrorType return_error = EB_ErrorNone;
150 :
151 : // Copy the pointer into the array
152 34971 : bufferPtr->array_ptr[bufferPtr->tail_index] = object_ptr;
153 :
154 : // Increment the tail & check for rollover
155 34971 : bufferPtr->tail_index = (bufferPtr->tail_index == bufferPtr->buffer_total_count - 1) ? 0 : bufferPtr->tail_index + 1;
156 :
157 : // Increment the Current Count
158 34971 : ++bufferPtr->current_count;
159 :
160 34971 : return return_error;
161 : }
162 :
163 : /**************************************
164 : * EbCircularBufferPushFront
165 : **************************************/
166 78716 : static EbErrorType EbCircularBufferPushFront(
167 : EbCircularBuffer *bufferPtr,
168 : EbPtr object_ptr)
169 : {
170 78716 : EbErrorType return_error = EB_ErrorNone;
171 :
172 : // Decrement the head_index
173 78716 : bufferPtr->head_index = (bufferPtr->head_index == 0) ? bufferPtr->buffer_total_count - 1 : bufferPtr->head_index - 1;
174 :
175 : // Copy the pointer into the array
176 78716 : bufferPtr->array_ptr[bufferPtr->head_index] = object_ptr;
177 :
178 : // Increment the Current Count
179 78716 : ++bufferPtr->current_count;
180 :
181 78716 : return return_error;
182 : }
183 :
184 74 : void EbMuxingQueueDctor(EbPtr p)
185 : {
186 74 : EbMuxingQueue* obj = (EbMuxingQueue*)p;
187 458 : EB_DELETE_PTR_ARRAY(obj->process_fifo_ptr_array, obj->process_total_count);
188 74 : EB_DELETE(obj->object_queue);
189 74 : EB_DELETE(obj->process_queue);
190 74 : EB_DESTROY_MUTEX(obj->lockout_mutex);
191 74 : }
192 :
193 : /**************************************
194 : * EbMuxingQueueCtor
195 : **************************************/
196 74 : static EbErrorType EbMuxingQueueCtor(
197 : EbMuxingQueue *queue_ptr,
198 : uint32_t object_total_count,
199 : uint32_t process_total_count,
200 : EbFifo ***processFifoPtrArrayPtr)
201 : {
202 : uint32_t processIndex;
203 74 : EbErrorType return_error = EB_ErrorNone;
204 :
205 74 : queue_ptr->dctor = EbMuxingQueueDctor;
206 74 : queue_ptr->process_total_count = process_total_count;
207 :
208 : // Lockout Mutex
209 74 : EB_CREATE_MUTEX(queue_ptr->lockout_mutex);
210 :
211 : // Construct Object Circular Buffer
212 74 : EB_NEW(
213 : queue_ptr->object_queue,
214 : EbCircularBufferCtor,
215 : object_total_count);
216 : // Construct Process Circular Buffer
217 74 : EB_NEW(
218 : queue_ptr->process_queue,
219 : EbCircularBufferCtor,
220 : queue_ptr->process_total_count);
221 : // Construct the Process Fifos
222 74 : EB_ALLOC_PTR_ARRAY(queue_ptr->process_fifo_ptr_array, queue_ptr->process_total_count);
223 :
224 458 : for (processIndex = 0; processIndex < queue_ptr->process_total_count; ++processIndex) {
225 384 : EB_NEW(
226 : queue_ptr->process_fifo_ptr_array[processIndex],
227 : EbFifoCtor,
228 : 0,
229 : object_total_count,
230 : (EbObjectWrapper *)EB_NULL,
231 : (EbObjectWrapper *)EB_NULL,
232 : queue_ptr);
233 : }
234 :
235 74 : *processFifoPtrArrayPtr = queue_ptr->process_fifo_ptr_array;
236 :
237 74 : return return_error;
238 : }
239 :
240 : /**************************************
241 : * EbMuxingQueueAssignation
242 : **************************************/
243 113576 : static EbErrorType EbMuxingQueueAssignation(
244 : EbMuxingQueue *queue_ptr)
245 : {
246 113576 : EbErrorType return_error = EB_ErrorNone;
247 : EbFifo *processFifoPtr;
248 : EbObjectWrapper *wrapper_ptr;
249 :
250 : // while loop
251 295207 : while ((EbCircularBufferEmptyCheck(queue_ptr->object_queue) == EB_FALSE) &&
252 129399 : (EbCircularBufferEmptyCheck(queue_ptr->process_queue) == EB_FALSE)) {
253 : // Get the next process
254 52055 : EbCircularBufferPopFront(
255 : queue_ptr->process_queue,
256 : (void **)&processFifoPtr);
257 :
258 : // Get the next object
259 52211 : EbCircularBufferPopFront(
260 : queue_ptr->object_queue,
261 : (void **)&wrapper_ptr);
262 :
263 : // Block on the Process Fifo's Mutex
264 52203 : eb_block_on_mutex(processFifoPtr->lockout_mutex);
265 :
266 : // Put the object on the fifo
267 52251 : EbFifoPushBack(
268 : processFifoPtr,
269 : wrapper_ptr);
270 :
271 : // Release the Process Fifo's Mutex
272 52245 : eb_release_mutex(processFifoPtr->lockout_mutex);
273 :
274 : // Post the semaphore
275 52253 : eb_post_semaphore(processFifoPtr->counting_semaphore);
276 : }
277 :
278 113618 : return return_error;
279 : }
280 :
281 : /**************************************
282 : * EbMuxingQueueObjectPushBack
283 : **************************************/
284 34972 : static EbErrorType EbMuxingQueueObjectPushBack(
285 : EbMuxingQueue *queue_ptr,
286 : EbObjectWrapper *object_ptr)
287 : {
288 34972 : EbErrorType return_error = EB_ErrorNone;
289 :
290 34972 : EbCircularBufferPushBack(
291 : queue_ptr->object_queue,
292 : object_ptr);
293 :
294 34972 : EbMuxingQueueAssignation(queue_ptr);
295 :
296 34964 : return return_error;
297 : }
298 :
299 : /**************************************
300 : * EbMuxingQueueObjectPushFront
301 : **************************************/
302 26353 : static EbErrorType EbMuxingQueueObjectPushFront(
303 : EbMuxingQueue *queue_ptr,
304 : EbObjectWrapper *object_ptr)
305 : {
306 26353 : EbErrorType return_error = EB_ErrorNone;
307 :
308 26353 : EbCircularBufferPushFront(
309 : queue_ptr->object_queue,
310 : object_ptr);
311 :
312 26348 : EbMuxingQueueAssignation(queue_ptr);
313 :
314 26344 : return return_error;
315 : }
316 :
317 : /*********************************************************************
318 : * eb_object_release_enable
319 : * Enables the release_enable member of EbObjectWrapper. Used by
320 : * certain objects (e.g. SequenceControlSet) to control whether
321 : * EbObjectWrappers are allowed to be released or not.
322 : *
323 : * resource_ptr
324 : * pointer to the SystemResource that manages the EbObjectWrapper.
325 : * The emptyFifo's lockout_mutex is used to write protect the
326 : * modification of the EbObjectWrapper.
327 : *
328 : * wrapper_ptr
329 : * pointer to the EbObjectWrapper to be modified.
330 : *********************************************************************/
331 0 : EbErrorType eb_object_release_enable(
332 : EbObjectWrapper *wrapper_ptr)
333 : {
334 0 : EbErrorType return_error = EB_ErrorNone;
335 :
336 0 : eb_block_on_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
337 :
338 0 : wrapper_ptr->release_enable = EB_TRUE;
339 :
340 0 : eb_release_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
341 :
342 0 : return return_error;
343 : }
344 :
345 : /*********************************************************************
346 : * eb_object_release_disable
347 : * Disables the release_enable member of EbObjectWrapper. Used by
348 : * certain objects (e.g. SequenceControlSet) to control whether
349 : * EbObjectWrappers are allowed to be released or not.
350 : *
351 : * resource_ptr
352 : * pointer to the SystemResource that manages the EbObjectWrapper.
353 : * The emptyFifo's lockout_mutex is used to write protect the
354 : * modification of the EbObjectWrapper.
355 : *
356 : * wrapper_ptr
357 : * pointer to the EbObjectWrapper to be modified.
358 : *********************************************************************/
359 2 : EbErrorType eb_object_release_disable(
360 : EbObjectWrapper *wrapper_ptr)
361 : {
362 2 : EbErrorType return_error = EB_ErrorNone;
363 :
364 2 : eb_block_on_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
365 :
366 2 : wrapper_ptr->release_enable = EB_FALSE;
367 :
368 2 : eb_release_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
369 :
370 2 : return return_error;
371 : }
372 :
373 : /*********************************************************************
374 : * eb_object_inc_live_count
375 : * Increments the live_count member of EbObjectWrapper. Used by
376 : * certain objects (e.g. SequenceControlSet) to count the number of active
377 : * pointers of a EbObjectWrapper in pipeline at any point in time.
378 : *
379 : * resource_ptr
380 : * pointer to the SystemResource that manages the EbObjectWrapper.
381 : * The emptyFifo's lockout_mutex is used to write protect the
382 : * modification of the EbObjectWrapper.
383 : *
384 : * wrapper_ptr
385 : * pointer to the EbObjectWrapper to be modified.
386 : *********************************************************************/
387 1464 : EbErrorType eb_object_inc_live_count(
388 : EbObjectWrapper *wrapper_ptr,
389 : uint32_t increment_number)
390 : {
391 1464 : EbErrorType return_error = EB_ErrorNone;
392 :
393 1464 : eb_block_on_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
394 :
395 1464 : wrapper_ptr->live_count += increment_number;
396 :
397 1464 : eb_release_mutex(wrapper_ptr->system_resource_ptr->empty_queue->lockout_mutex);
398 :
399 1464 : return return_error;
400 : }
401 :
402 : //ugly hack
403 : typedef struct DctorAble
404 : {
405 : EbDctor dctor;
406 : } DctorAble;
407 :
408 9082 : void eb_object_wrapper_dctor(EbPtr p)
409 : {
410 9082 : EbObjectWrapper* wrapper = (EbObjectWrapper*)p;
411 9082 : if (wrapper->object_destroyer) {
412 : //customized destoryer
413 296 : if (wrapper->object_ptr)
414 296 : wrapper->object_destroyer(wrapper->object_ptr);
415 : }
416 : else {
417 : //hack....
418 8786 : DctorAble* obj= (DctorAble*)wrapper->object_ptr;
419 8786 : EB_DELETE(obj);
420 : }
421 9082 : }
422 :
423 9082 : static EbErrorType eb_object_wrapper_ctor(EbObjectWrapper* wrapper,
424 : EbSystemResource *resource,
425 : EbCreator object_creator,
426 : EbPtr object_init_data_ptr,
427 : EbDctor object_destroyer)
428 : {
429 : EbErrorType ret;
430 :
431 9082 : wrapper->dctor = eb_object_wrapper_dctor;
432 9082 : ret = object_creator(&wrapper->object_ptr, object_init_data_ptr);
433 9082 : if (ret != EB_ErrorNone)
434 0 : return ret;
435 9082 : wrapper->release_enable = EB_TRUE;
436 9082 : wrapper->system_resource_ptr = resource;
437 9082 : wrapper->object_destroyer = object_destroyer;
438 9082 : return EB_ErrorNone;
439 : }
440 :
441 42 : static void eb_system_resource_dctor(EbPtr p)
442 : {
443 42 : EbSystemResource* obj = (EbSystemResource*)p;
444 42 : EB_DELETE(obj->full_queue);
445 42 : EB_DELETE(obj->empty_queue);
446 9124 : EB_DELETE_PTR_ARRAY(obj->wrapper_ptr_pool, obj->object_total_count);
447 42 : }
448 :
449 : /*********************************************************************
450 : * eb_system_resource_ctor
451 : * Constructor for EbSystemResource. Fully constructs all members
452 : * of EbSystemResource including the object with the passed
453 : * object_ctor function.
454 : *
455 : * resource_ptr
456 : * pointer that will contain the SystemResource to be constructed.
457 : *
458 : * object_total_count
459 : * Number of objects to be managed by the SystemResource.
460 : *
461 : * full_fifo_enabled
462 : * Bool that describes if the SystemResource is to have an output
463 : * fifo. An outputFifo is not used by certain objects (e.g.
464 : * SequenceControlSet).
465 : *
466 : * object_ctor
467 : * Function pointer to the constructor of the object managed by
468 : * SystemResource referenced by resource_ptr. No object level
469 : * construction is performed if object_ctor is NULL.
470 : *
471 : * object_init_data_ptr
472 :
473 : * pointer to data block to be used during the construction of
474 : * the object. object_init_data_ptr is passed to object_ctor when
475 : * object_ctor is called.
476 : * object_destroyer
477 : * object destroyer, will call dctor if this is null
478 : *********************************************************************/
479 42 : EbErrorType eb_system_resource_ctor(
480 : EbSystemResource *resource_ptr,
481 : uint32_t object_total_count,
482 : uint32_t producer_process_total_count,
483 : uint32_t consumer_process_total_count,
484 : EbFifo ***producer_fifo_ptr_array_ptr,
485 : EbFifo ***consumer_fifo_ptr_array_ptr,
486 : EbBool full_fifo_enabled,
487 : EbCreator object_creator,
488 : EbPtr object_init_data_ptr,
489 : EbDctor object_destroyer)
490 : {
491 : uint32_t wrapperIndex;
492 42 : EbErrorType return_error = EB_ErrorNone;
493 42 : resource_ptr->dctor = eb_system_resource_dctor;
494 :
495 42 : resource_ptr->object_total_count = object_total_count;
496 :
497 : // Allocate array for wrapper pointers
498 42 : EB_ALLOC_PTR_ARRAY(resource_ptr->wrapper_ptr_pool, resource_ptr->object_total_count);
499 :
500 : // Initialize each wrapper
501 9124 : for (wrapperIndex = 0; wrapperIndex < resource_ptr->object_total_count; ++wrapperIndex) {
502 9082 : EB_NEW(resource_ptr->wrapper_ptr_pool[wrapperIndex], eb_object_wrapper_ctor, resource_ptr,
503 : object_creator, object_init_data_ptr, object_destroyer);
504 : }
505 :
506 : // Initialize the Empty Queue
507 42 : EB_NEW(
508 : resource_ptr->empty_queue,
509 : EbMuxingQueueCtor,
510 : resource_ptr->object_total_count,
511 : producer_process_total_count,
512 : producer_fifo_ptr_array_ptr);
513 : // Fill the Empty Fifo with every ObjectWrapper
514 9124 : for (wrapperIndex = 0; wrapperIndex < resource_ptr->object_total_count; ++wrapperIndex) {
515 9082 : EbMuxingQueueObjectPushBack(
516 : resource_ptr->empty_queue,
517 9082 : resource_ptr->wrapper_ptr_pool[wrapperIndex]);
518 : }
519 :
520 : // Initialize the Full Queue
521 42 : if (full_fifo_enabled == EB_TRUE) {
522 32 : EB_NEW(
523 : resource_ptr->full_queue,
524 : EbMuxingQueueCtor,
525 : resource_ptr->object_total_count,
526 : consumer_process_total_count,
527 : consumer_fifo_ptr_array_ptr);
528 32 : if (return_error == EB_ErrorInsufficientResources)
529 0 : return EB_ErrorInsufficientResources;
530 : }
531 : else {
532 10 : resource_ptr->full_queue = (EbMuxingQueue *)EB_NULL;
533 10 : consumer_fifo_ptr_array_ptr = (EbFifo ***)EB_NULL;
534 : }
535 :
536 42 : return return_error;
537 : }
538 :
539 : /*********************************************************************
540 : * EbSystemResourceReleaseProcess
541 : *********************************************************************/
542 52454 : static EbErrorType EbReleaseProcess(
543 : EbFifo *processFifoPtr)
544 : {
545 52454 : EbErrorType return_error = EB_ErrorNone;
546 :
547 52454 : eb_block_on_mutex(processFifoPtr->queue_ptr->lockout_mutex);
548 :
549 52461 : EbCircularBufferPushFront(
550 52461 : processFifoPtr->queue_ptr->process_queue,
551 : processFifoPtr);
552 :
553 52445 : EbMuxingQueueAssignation(processFifoPtr->queue_ptr);
554 :
555 52476 : eb_release_mutex(processFifoPtr->queue_ptr->lockout_mutex);
556 :
557 52482 : return return_error;
558 : }
559 :
560 : /*********************************************************************
561 : * EbSystemResourcePostObject
562 : * Queues a full EbObjectWrapper to the SystemResource. This
563 : * function posts the SystemResource fullFifo counting_semaphore.
564 : * This function is write protected by the SystemResource fullFifo
565 : * lockout_mutex.
566 : *
567 : * resource_ptr
568 : * pointer to the SystemResource that the EbObjectWrapper is
569 : * posted to.
570 : *
571 : * wrapper_ptr
572 : * pointer to EbObjectWrapper to be posted.
573 : *********************************************************************/
574 25890 : EbErrorType eb_post_full_object(
575 : EbObjectWrapper *object_ptr)
576 : {
577 25890 : EbErrorType return_error = EB_ErrorNone;
578 :
579 25890 : eb_block_on_mutex(object_ptr->system_resource_ptr->full_queue->lockout_mutex);
580 :
581 25890 : EbMuxingQueueObjectPushBack(
582 25890 : object_ptr->system_resource_ptr->full_queue,
583 : object_ptr);
584 :
585 25882 : eb_release_mutex(object_ptr->system_resource_ptr->full_queue->lockout_mutex);
586 :
587 25890 : return return_error;
588 : }
589 :
590 : /*********************************************************************
591 : * EbSystemResourceReleaseObject
592 : * Queues an empty EbObjectWrapper to the SystemResource. This
593 : * function posts the SystemResource emptyFifo counting_semaphore.
594 : * This function is write protected by the SystemResource emptyFifo
595 : * lockout_mutex.
596 : *
597 : * object_ptr
598 : * pointer to EbObjectWrapper to be released.
599 : *********************************************************************/
600 27557 : EbErrorType eb_release_object(
601 : EbObjectWrapper *object_ptr)
602 : {
603 27557 : EbErrorType return_error = EB_ErrorNone;
604 :
605 27557 : eb_block_on_mutex(object_ptr->system_resource_ptr->empty_queue->lockout_mutex);
606 :
607 : // Decrement live_count
608 27569 : object_ptr->live_count = (object_ptr->live_count == 0) ? object_ptr->live_count : object_ptr->live_count - 1;
609 :
610 27569 : if ((object_ptr->release_enable == EB_TRUE) && (object_ptr->live_count == 0)) {
611 : // Set live_count to EB_ObjectWrapperReleasedValue
612 26354 : object_ptr->live_count = EB_ObjectWrapperReleasedValue;
613 :
614 26354 : EbMuxingQueueObjectPushFront(
615 26354 : object_ptr->system_resource_ptr->empty_queue,
616 : object_ptr);
617 : }
618 :
619 27559 : eb_release_mutex(object_ptr->system_resource_ptr->empty_queue->lockout_mutex);
620 :
621 27567 : return return_error;
622 : }
623 :
624 : /*********************************************************************
625 : * EbSystemResourceGetEmptyObject
626 : * Dequeues an empty EbObjectWrapper from the SystemResource. This
627 : * function blocks on the SystemResource emptyFifo counting_semaphore.
628 : * This function is write protected by the SystemResource emptyFifo
629 : * lockout_mutex.
630 : *
631 : * resource_ptr
632 : * pointer to the SystemResource that provides the empty
633 : * EbObjectWrapper.
634 : *
635 : * wrapper_dbl_ptr
636 : * Double pointer used to pass the pointer to the empty
637 : * EbObjectWrapper pointer.
638 : *********************************************************************/
639 26376 : EbErrorType eb_get_empty_object(
640 : EbFifo *empty_fifo_ptr,
641 : EbObjectWrapper **wrapper_dbl_ptr)
642 : {
643 26376 : EbErrorType return_error = EB_ErrorNone;
644 :
645 : // Queue the Fifo requesting the empty fifo
646 26376 : EbReleaseProcess(empty_fifo_ptr);
647 :
648 : // Block on the counting Semaphore until an empty buffer is available
649 26374 : eb_block_on_semaphore(empty_fifo_ptr->counting_semaphore);
650 :
651 : // Acquire lockout Mutex
652 26375 : eb_block_on_mutex(empty_fifo_ptr->lockout_mutex);
653 :
654 : // Get the empty object
655 26375 : EbFifoPopFront(
656 : empty_fifo_ptr,
657 : wrapper_dbl_ptr);
658 :
659 : // Reset the wrapper's live_count
660 26375 : (*wrapper_dbl_ptr)->live_count = 0;
661 :
662 : // Object release enable
663 26375 : (*wrapper_dbl_ptr)->release_enable = EB_TRUE;
664 :
665 : // Release Mutex
666 26375 : eb_release_mutex(empty_fifo_ptr->lockout_mutex);
667 :
668 26374 : return return_error;
669 : }
670 :
671 : /*********************************************************************
672 : * EbSystemResourceGetFullObject
673 : * Dequeues an full EbObjectWrapper from the SystemResource. This
674 : * function blocks on the SystemResource fullFifo counting_semaphore.
675 : * This function is write protected by the SystemResource fullFifo
676 : * lockout_mutex.
677 : *
678 : * resource_ptr
679 : * pointer to the SystemResource that provides the full
680 : * EbObjectWrapper.
681 : *
682 : * wrapper_dbl_ptr
683 : * Double pointer used to pass the pointer to the full
684 : * EbObjectWrapper pointer.
685 : *********************************************************************/
686 25999 : EbErrorType eb_get_full_object(
687 : EbFifo *full_fifo_ptr,
688 : EbObjectWrapper **wrapper_dbl_ptr)
689 : {
690 25999 : EbErrorType return_error = EB_ErrorNone;
691 :
692 : // Queue the Fifo requesting the full fifo
693 25999 : EbReleaseProcess(full_fifo_ptr);
694 :
695 : // Block on the counting Semaphore until an empty buffer is available
696 25998 : eb_block_on_semaphore(full_fifo_ptr->counting_semaphore);
697 :
698 : // Acquire lockout Mutex
699 25850 : eb_block_on_mutex(full_fifo_ptr->lockout_mutex);
700 :
701 25876 : EbFifoPopFront(
702 : full_fifo_ptr,
703 : wrapper_dbl_ptr);
704 :
705 : // Release Mutex
706 25869 : eb_release_mutex(full_fifo_ptr->lockout_mutex);
707 :
708 25877 : return return_error;
709 : }
710 :
711 : /**************************************
712 : * EbFifoPopFront
713 : **************************************/
714 118 : static EbBool EbFifoPeakFront(
715 : EbFifo *fifoPtr)
716 : {
717 : // Set wrapper_ptr to head of BufferPool
718 118 : if (fifoPtr->first_ptr == (EbObjectWrapper*)EB_NULL)
719 118 : return EB_TRUE;
720 : else
721 0 : return EB_FALSE;
722 : }
723 :
724 118 : EbErrorType eb_get_full_object_non_blocking(
725 : EbFifo *full_fifo_ptr,
726 : EbObjectWrapper **wrapper_dbl_ptr)
727 : {
728 118 : EbErrorType return_error = EB_ErrorNone;
729 : EbBool fifoEmpty;
730 : // Queue the Fifo requesting the full fifo
731 118 : EbReleaseProcess(full_fifo_ptr);
732 :
733 : // Acquire lockout Mutex
734 118 : eb_block_on_mutex(full_fifo_ptr->lockout_mutex);
735 :
736 118 : fifoEmpty = EbFifoPeakFront(
737 : full_fifo_ptr);
738 :
739 : // Release Mutex
740 118 : eb_release_mutex(full_fifo_ptr->lockout_mutex);
741 :
742 118 : if (fifoEmpty == EB_FALSE)
743 0 : eb_get_full_object(
744 : full_fifo_ptr,
745 : wrapper_dbl_ptr);
746 : else
747 118 : *wrapper_dbl_ptr = (EbObjectWrapper*)EB_NULL;
748 :
749 118 : return return_error;
750 : }
|