1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
6 *
7 * GPL LICENSE SUMMARY
8 *
9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23 * The full GNU General Public License is included in this distribution
24 * in the file called LICENSE.GPL.
25 *
26 * BSD LICENSE
27 *
28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29 * All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 *
35 * * Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * * Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in
39 * the documentation and/or other materials provided with the
40 * distribution.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 *
54 * $FreeBSD$
55 */
56 /**
57 * @file
58 *
59 * @brief This file contains the interface to the abstract list class.
60 * This class will allow for the same item to occur multiple times in
61 * a list or multiple lists. It will provide an interface that is
62 * similar to the C++ standard template list interface.
63 * Methods Provided:
64 * - sci_abstract_list_front()
65 * - sci_abstract_list_back()
66 * - sci_abstract_list_is_empty()
67 * - sci_abstract_list_size()
68 * - sci_abstract_list_print()
69 * - sci_abstract_list_find()
70 * - sci_abstract_list_popback()
71 * - sci_abstract_list_popfront()
72 * - sci_abstract_list_erase()
73 * - sci_abstract_list_pushback()
74 * - sci_abstract_list_pushfront()
75 * - sci_abstract_list_get_object()
76 * - sci_abstract_list_get_next()
77 * - sci_abstract_list_insert() UNIMPLEMENTED
78 * - sci_abstract_list_clear()
79 */
80
81 #ifndef _SCI_ABSTRACT_LIST_H_
82 #define _SCI_ABSTRACT_LIST_H_
83
84 //******************************************************************************
85 //*
86 //* I N C L U D E S
87 //*
88 //******************************************************************************
89
90 #include <dev/isci/scil/sci_types.h>
91
92 //******************************************************************************
93 //*
94 //* C O N S T A N T S
95 //*
96 //******************************************************************************
97
98 //******************************************************************************
99 //*
100 //* T Y P E S
101 //*
102 //******************************************************************************
103
104 /**
105 * @struct SCI_ABSTRACT_ELEMENT
106 *
107 * @brief This object represents an element of a abstract list.
108 * NOTE: This structure does not evenly align on a cache line
109 * boundary. If SSP specific code ends up using this list,
110 * then it may be a good idea to force the alignment. Now
111 * it is more important to save the space.
112 */
113 typedef struct SCI_ABSTRACT_ELEMENT
114 {
115 /**
116 * This field points to the next item in the abstract_list.
117 */
118 struct SCI_ABSTRACT_ELEMENT * next_p;
119
120 /**
121 * This field points to the previous item in the abstract_list.
122 */
123 struct SCI_ABSTRACT_ELEMENT * previous_p;
124
125 /**
126 * This field points to the object the list is managing (i.e. the thing
127 * being listed).
128 */
129 void * object_p;
130
131 } SCI_ABSTRACT_ELEMENT_T;
132
133 /**
134 * @struct SCI_ABSTRACT_ELEMENT_LIST
135 *
136 * @brief This object represents an element list object. It can have
137 * elements added and removed from it.
138 */
139 typedef struct SCI_ABSTRACT_ELEMENT_LIST
140 {
141 /**
142 * Pointer to the front (head) of the list.
143 */
144 SCI_ABSTRACT_ELEMENT_T * front_p;
145
146 /**
147 * Pointer to the back (tail) of the list.
148 */
149 SCI_ABSTRACT_ELEMENT_T * back_p;
150
151 /**
152 * This field depicts the number of elements in this list.
153 * NOTE: It is possible to remove this field and replace it with a
154 * linear walking of the list to determine the size, but since
155 * there aren't many lists in the system we don't utilize much
156 * space.
157 */
158 U32 size;
159
160 } SCI_ABSTRACT_ELEMENT_LIST_T;
161
162 /**
163 * @struct SCI_ABSTRACT_ELEMENT_POOL
164 *
165 * @brief This structure provides the pool of free abstract elements to be
166 * utilized by an SCI_ABSTRACT_LIST.
167 */
168 typedef struct SCI_ABSTRACT_ELEMENT_POOL
169 {
170 /**
171 * Pointer to an array of elements to be managed by this pool. This
172 * array acts as the memory store for the elements in the free pool or
173 * allocated out of the pool into an SCI_ABSTRACT_LIST.
174 */
175 SCI_ABSTRACT_ELEMENT_T * elements;
176
177 /**
178 * This field contains the maximum number of free elements for the pool.
179 * It is set at creation of the pool and should not be changed afterward.
180 */
181 U32 max_elements;
182
183 /**
184 * Pointer to the list of free elements that can be allocated from
185 * the pool.
186 */
187 struct SCI_ABSTRACT_ELEMENT_LIST free_list;
188
189 } SCI_ABSTRACT_ELEMENT_POOL_T;
190
191 /**
192 * @struct SCI_ABSTRACT_LIST
193 *
194 * @brief This object provides the ability to queue any type of object or
195 * even the same object multiple times. The object must be provided
196 * an element pool from which to draw free elements.
197 */
198 typedef struct SCI_ABSTRACT_LIST
199 {
200 /**
201 * This represents the elements currently managed by the list.
202 */
203 SCI_ABSTRACT_ELEMENT_LIST_T elements;
204
205 /**
206 * This field contains elements that are currently available for
207 * allocation into the list of elements;
208 */
209 SCI_ABSTRACT_ELEMENT_POOL_T * free_pool;
210
211 } SCI_ABSTRACT_LIST_T;
212
213 //******************************************************************************
214 //*
215 //* P R O T E C T E D M E T H O D S
216 //*
217 //******************************************************************************
218
219 void sci_abstract_element_pool_construct(
220 SCI_ABSTRACT_ELEMENT_POOL_T * pool,
221 SCI_ABSTRACT_ELEMENT_T * list_elements,
222 int element_count
223 );
224
225 void sci_abstract_list_construct(
226 SCI_ABSTRACT_LIST_T * list,
227 SCI_ABSTRACT_ELEMENT_POOL_T * free_pool
228 );
229
230
231
232 #ifdef USE_ABSTRACT_LIST_FUNCTIONS
233 //******************************************************************************
234 //*
235 //* P U B L I C M E T H O D S
236 //*
237 //******************************************************************************
238
239 /**
240 * Simply return the front element pointer of the list. This returns an element
241 * element as opposed to what the element is pointing to.
242 */
243 SCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_front(
244 SCI_ABSTRACT_LIST_T * list_p
245 );
246
247
248 /**
249 * This method simply returns the object pointed to by the head (front) of
250 * the list.
251 */
252 void * sci_abstract_list_front(
253 SCI_ABSTRACT_LIST_T * list_p
254 );
255
256
257 /**
258 * This method simply returns the object pointed to by the tail (back) of
259 * the list.
260 */
261 void * sci_abstract_list_back(
262 SCI_ABSTRACT_LIST_T * list_p
263 );
264
265
266 /**
267 * This method will return FALSE if the list is not empty.
268 */
269 BOOL sci_abstract_list_is_empty(
270 SCI_ABSTRACT_LIST_T * list_p
271 );
272
273
274 /**
275 * This method will return the number of elements queued in the list.
276 */
277 U32 sci_abstract_list_size(
278 SCI_ABSTRACT_LIST_T * list_p
279 );
280
281
282 /**
283 * This method simply returns the next list element in the list.
284 */
285 SCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_next(
286 SCI_ABSTRACT_ELEMENT_T * alElement_p
287 );
288
289
290 /**
291 * This method simply prints the contents of the list.
292 */
293 void sci_abstract_list_print(
294 SCI_ABSTRACT_LIST_T * list_p
295 );
296
297
298 /**
299 * This method will simply search the supplied list for the desired object.
300 * It will return a pointer to the object, if it is found. Otherwise
301 * it will return NULL.
302 */
303 void * sci_abstract_list_find(
304 SCI_ABSTRACT_LIST_T * list_p,
305 void * obj_p
306 );
307
308
309 /**
310 * This method will simply remove the element at the back (tail) of the list.
311 * It will return a pointer to the object that was removed or NULL if not
312 * found.
313 */
314 void * sci_abstract_list_popback(
315 SCI_ABSTRACT_LIST_T * list_p
316 );
317
318
319 /**
320 * This method simply removes the list element at the head of the list
321 * and returns the pointer to the object that was removed.
322 */
323 void * sci_abstract_list_popfront(
324 SCI_ABSTRACT_LIST_T * list_p
325 );
326
327
328
329 /**
330 * This method will erase (remove) all instances of the supplied object from
331 * anywhere in the list.
332 */
333 void sci_abstract_list_erase(
334 SCI_ABSTRACT_LIST_T * list_p,
335 void * obj_p
336 );
337
338
339 /**
340 * This method simply adds a LIST_ELEMENT for the supplied object to the back
341 * (tail) of the supplied list.
342 */
343 void sci_abstract_list_pushback(
344 SCI_ABSTRACT_LIST_T * list_p,
345 void * obj_p
346 );
347
348
349
350 /**
351 * This method simply adds a LIST_ELEMENT for the supplied object to the front
352 * (head) of the supplied list.
353 */
354 void sci_abstract_list_pushfront(
355 SCI_ABSTRACT_LIST_T * list_p,
356 void * obj_p
357 );
358
359
360 /**
361 * This method will add the objToAdd_p object to the list before the obj_p.
362 * NOTE: UNIMPLEMENTED
363 */
364 void sci_abstract_list_insert(
365 SCI_ABSTRACT_LIST_T * list_p,
366 void * obj_p,
367 void * objToAdd_p
368 );
369
370
371 /**
372 * This method simply frees all the items from the list.
373 */
374 void sci_abstract_list_clear(
375 SCI_ABSTRACT_LIST_T * list_p
376 );
377
378
379 /**
380 * This method simply returns the object being pointed to by the list element
381 * (The item being listed).
382 */
383 void * sci_abstract_list_get_object(
384 SCI_ABSTRACT_ELEMENT_T * alElement_p
385 );
386
387
388 /**
389 * This method is simply a wrapper to provide the number of elements in
390 * the free list.
391 */
392 U32 sci_abstract_list_freeList_size(
393 SCI_ABSTRACT_LIST_T * freeList
394 );
395
396
397 //******************************************************************************
398 //*
399 //* P R I V A T E M E T H O D S
400 //*
401 //******************************************************************************
402
403 /**
404 * This method simply performs the common portion of pushing a list element
405 * onto a list.
406 *
407 * WARNING: This is a private helper method that should not be called directly
408 * by any users.
409 */
410 void private_push_front(
411 SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p,
412 SCI_ABSTRACT_ELEMENT_T * alElement_p
413 );
414
415
416 /**
417 * This method simply performs the common portion of popping a list element
418 * from a list.
419 *
420 * WARNING: This is a private helper method that should not be called directly
421 * by any users.
422 */
423 SCI_ABSTRACT_ELEMENT_T * private_pop_front(
424 SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p
425 );
426
427
428 /**
429 * This method will simply search the supplied list for the desired object.
430 * It will return a pointer to the abstract_list_element if found, otherwise
431 * it will return NULL.
432 */
433 SCI_ABSTRACT_ELEMENT_T * private_find(
434 SCI_ABSTRACT_ELEMENT_LIST_T * list_p,
435 void * obj_p
436 );
437
438
439 /**
440 * This private method will free the supplied list element back to the pool
441 * of free list elements.
442 */
443 void private_pool_free(
444 SCI_ABSTRACT_ELEMENT_POOL_T * free_pool,
445 SCI_ABSTRACT_ELEMENT_T * alElement_p
446 );
447
448
449 /**
450 * This private method will allocate a list element from the pool of free
451 * list elements.
452 */
453 SCI_ABSTRACT_ELEMENT_T * private_pool_allocate(
454 SCI_ABSTRACT_ELEMENT_POOL_T * free_pool
455 );
456
457
458 #else
459
460 //******************************************************************************
461 //*
462 //* P U B L I C M E T H O D S
463 //*
464 //******************************************************************************
465
466 /**
467 * Simply return the front element pointer of the list. This returns an element
468 * element as opposed to what the element is pointing to.
469 */
470 #define sci_abstract_list_get_front( \
471 list_p \
472 ) \
473 ((list_p)->elements.front_p)
474
475 /**
476 * This method simply returns the object pointed to by the head (front) of
477 * the list.
478 */
479 #define sci_abstract_list_front( \
480 list_p \
481 ) \
482 ( ( (list_p)->elements.front_p ) ? ((list_p)->elements.front_p->object_p) : NULL )
483
484 /**
485 * This method simply returns the object pointed to by the tail (back) of
486 * the list.
487 */
488 #define sci_abstract_list_back( \
489 list_p \
490 ) \
491 ( ( (list_p)->elements.back_p ) ? ((list_p)->elements.back_p->object_p) : NULL )
492
493 /**
494 * This method will return FALSE if the list is not empty.
495 */
496 #define sci_abstract_list_is_empty( \
497 list_p \
498 ) \
499 ( (list_p)->elements.front_p == NULL )
500
501 /**
502 * This method will return the number of elements queued in the list.
503 */
504 #define sci_abstract_list_size( \
505 list_p \
506 ) \
507 ( (list_p)->elements.size )
508
509 /**
510 * This method simply returns the next list element in the list.
511 */
512 #define sci_abstract_list_get_next( \
513 alElement_p \
514 ) \
515 ( (alElement_p)->next_p )
516
517 /**
518 * This method simply prints the contents of the list.
519 */
520 #define sci_abstract_list_print( \
521 list_p \
522 ) \
523 { \
524 SCI_ABSTRACT_ELEMENT_T * alElement_p = list_p->elements.front_p; \
525 \
526 while (alElement_p != NULL) \
527 { \
528 /* Check to see if we found the object for which we are searching. */ \
529 printf("ITEM next_p 0x%x prev_p 0x%x obj_p 0x%x, 0x%x\n", \
530 alElement_p->next_p, \
531 alElement_p->previous_p, \
532 (U32*) (alElement_p->object_p)); \
533 \
534 alElement_p = alElement_p->next_p; \
535 } \
536 }
537
538 /**
539 * This method will simply search the supplied list for the desired object.
540 * It will return a pointer to the object, if it is found. Otherwise
541 * it will return NULL.
542 */
543 #define sci_abstract_list_find( \
544 list_p, \
545 obj_p \
546 ) \
547 ({ \
548 sci_abstract_list_get_object(private_find(&(list_p)->elements, (obj_p))); \
549 })
550
551 /**
552 * This method will simply remove the element at the back (tail) of the list.
553 * It will return a pointer to the object that was removed or NULL if not
554 * found.
555 */
556 #define sci_abstract_list_popback( \
557 list_p \
558 ) \
559 ({ \
560 SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements; \
561 SCI_ABSTRACT_ELEMENT_T * alElement_p = elem_list->back_p; \
562 void * obj_p = NULL; \
563 \
564 if (alElement_p != NULL) \
565 { \
566 obj_p = alElement_p->object_p; \
567 if (elem_list->back_p == elem_list->front_p) \
568 { \
569 elem_list->back_p = elem_list->front_p = NULL; \
570 } \
571 else \
572 { \
573 elem_list->back_p = elem_list->back_p->previous_p; \
574 elem_list->back_p->next_p = NULL; \
575 } \
576 \
577 elem_list->size--; \
578 private_pool_free((list_p)->free_pool, alElement_p); \
579 } \
580 \
581 obj_p; \
582 })
583
584 /**
585 * This method simply removes the list element at the head of the list
586 * and returns the pointer to the object that was removed.
587 */
588 #define sci_abstract_list_popfront( \
589 list_p \
590 ) \
591 ({ \
592 SCI_ABSTRACT_ELEMENT_T * alElement_p = \
593 private_pop_front(&(list_p)->elements); \
594 void * obj_p = NULL; \
595 \
596 if (alElement_p != NULL) \
597 { \
598 obj_p = alElement_p->object_p; \
599 private_pool_free((list_p)->free_pool, alElement_p); \
600 } \
601 \
602 obj_p; \
603 })
604
605 /**
606 * This method will erase (remove) all instances of the supplied object from
607 * anywhere in the list.
608 */
609 #define sci_abstract_list_erase( \
610 list_p, \
611 obj_p \
612 ) \
613 { \
614 SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements; \
615 SCI_ABSTRACT_ELEMENT_T * alElement_p; \
616 \
617 while ((alElement_p = private_find(elem_list, (obj_p))) != NULL) \
618 { \
619 if (alElement_p == elem_list->front_p) \
620 { \
621 sci_abstract_list_popfront(list_p); \
622 } \
623 else if (alElement_p == elem_list->back_p) \
624 { \
625 sci_abstract_list_popback(list_p); \
626 } \
627 else \
628 { \
629 alElement_p->previous_p->next_p = alElement_p->next_p; \
630 alElement_p->next_p->previous_p = alElement_p->previous_p; \
631 elem_list->size--; \
632 private_pool_free((list_p)->free_pool, alElement_p); \
633 } \
634 } \
635 }
636
637 /**
638 * This method simply adds a LIST_ELEMENT for the supplied object to the back
639 * (tail) of the supplied list.
640 */
641 #define sci_abstract_list_pushback( \
642 list_p, \
643 obj_p \
644 ) \
645 { \
646 SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements; \
647 SCI_ABSTRACT_ELEMENT_T * alElement_p \
648 = private_pool_allocate((list_p)->free_pool); \
649 assert(alElement_p != NULL); \
650 \
651 alElement_p->object_p = (obj_p); \
652 \
653 if (elem_list->front_p == NULL) \
654 { \
655 elem_list->front_p = elem_list->back_p = alElement_p; \
656 } \
657 else \
658 { \
659 elem_list->back_p->next_p = alElement_p; \
660 alElement_p->previous_p = elem_list->back_p; \
661 elem_list->back_p = alElement_p; \
662 } \
663 \
664 elem_list->size++; \
665 }
666
667 /**
668 * This method simply adds a LIST_ELEMENT for the supplied object to the front
669 * (head) of the supplied list.
670 */
671 #define sci_abstract_list_pushfront( \
672 list_p, \
673 obj_p \
674 ) \
675 { \
676 SCI_ABSTRACT_ELEMENT_T * alElement_p = \
677 private_pool_allocate((list_p)->free_pool); \
678 alElement_p->object_p = (obj_p); \
679 private_push_front(&(list_p)->elements, alElement_p); \
680 }
681
682 /**
683 * This method will add the objToAdd_p object to the list before the obj_p.
684 * NOTE: UNIMPLEMENTED
685 */
686 #define sci_abstract_list_insert( \
687 list_p, \
688 obj_p, \
689 objToAdd_p \
690 ) \
691 { \
692 SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements; \
693 \
694 SCI_ABSTRACT_ELEMENT_T * obj_element = private_find(elem_list, obj_p); \
695 \
696 SCI_ABSTRACT_ELEMENT_T * objToAdd_element = \
697 private_pool_allocate((list_p)->free_pool); \
698 \
699 objToAdd_element->object_p = objToAdd_p; \
700 \
701 ASSERT(obj_element != NULL); \
702 ASSERT(objToAdd_element != NULL); \
703 \
704 if (obj_element == elem_list->front_p) \
705 { \
706 objToAdd_element->object_p = (objToAdd_p); \
707 private_push_front(&(list_p)->elements, objToAdd_element); \
708 } \
709 else \
710 { \
711 obj_element->previous_p->next_p = objToAdd_element; \
712 objToAdd_element->previous_p = obj_element->previous_p; \
713 \
714 obj_element->previous_p = objToAdd_element; \
715 objToAdd_element->next_p = obj_element; \
716 \
717 elem_list->size++; \
718 } \
719 }
720
721 /**
722 * This method simply frees all the items from the list.
723 */
724 #define sci_abstract_list_clear( \
725 list_p \
726 ) \
727 { \
728 while ((list_p)->elements.size > 0) \
729 sci_abstract_list_popfront((list_p)); \
730 }
731
732 /**
733 * This method simply returns the object being pointed to by the list element
734 * (The item being listed).
735 */
736 #define sci_abstract_list_get_object( \
737 alElement_p \
738 ) \
739 ({ \
740 void * obj_p = NULL; \
741 if ((alElement_p) != NULL) \
742 obj_p = (alElement_p)->object_p; \
743 \
744 obj_p; \
745 })
746
747 /**
748 * This method is simply a wrapper to provide the number of elements in
749 * the free list.
750 */
751 #define sci_abstract_list_freeList_size(freeList) (sci_abstract_list_size(freeList))
752
753 //******************************************************************************
754 //*
755 //* P R I V A T E M E T H O D S
756 //*
757 //******************************************************************************
758
759 /**
760 * This method simply performs the common portion of pushing a list element
761 * onto a list.
762 *
763 * WARNING: This is a private helper method that should not be called directly
764 * by any users.
765 */
766 #define private_push_front( \
767 privateList_p, \
768 alElement_p \
769 ) \
770 { \
771 if ((privateList_p)->front_p == NULL) \
772 { \
773 (privateList_p)->front_p = (privateList_p)->back_p = (alElement_p); \
774 (alElement_p)->next_p = (alElement_p)->previous_p = NULL; \
775 } \
776 else \
777 { \
778 (alElement_p)->next_p = (privateList_p)->front_p; \
779 (alElement_p)->previous_p = NULL; \
780 (privateList_p)->front_p->previous_p = (alElement_p); \
781 (privateList_p)->front_p = (alElement_p); \
782 } \
783 \
784 (privateList_p)->size++; \
785 }
786
787 /**
788 * This method simply performs the common portion of popping a list element
789 * from a list.
790 *
791 * WARNING: This is a private helper method that should not be called directly
792 * by any users.
793 */
794 #define private_pop_front( \
795 privateList_p \
796 ) \
797 ({ \
798 SCI_ABSTRACT_ELEMENT_T * alElement_p = (privateList_p)->front_p; \
799 \
800 if (alElement_p != NULL) \
801 { \
802 if ((privateList_p)->front_p == (privateList_p)->back_p) \
803 { \
804 (privateList_p)->front_p = (privateList_p)->back_p = NULL; \
805 } \
806 else \
807 { \
808 (privateList_p)->front_p = (privateList_p)->front_p->next_p; \
809 (privateList_p)->front_p->previous_p = NULL; \
810 } \
811 \
812 (privateList_p)->size--; \
813 } \
814 \
815 alElement_p; \
816 })
817
818 /**
819 * This method will simply search the supplied list for the desired object.
820 * It will return a pointer to the abstract_list_element if found, otherwise
821 * it will return NULL.
822 */
823 #define private_find( \
824 list_p, \
825 obj_p \
826 ) \
827 ({ \
828 SCI_ABSTRACT_ELEMENT_T * alElement_p = (list_p)->front_p; \
829 \
830 while (alElement_p != NULL) \
831 { \
832 /* Check to see if we found the object for which we are searching. */ \
833 if (alElement_p->object_p == (void*) (obj_p)) \
834 { \
835 break; \
836 } \
837 \
838 alElement_p = alElement_p->next_p; \
839 } \
840 \
841 alElement_p; \
842 })
843
844 /**
845 * This private method will free the supplied list element back to the pool
846 * of free list elements.
847 */
848 #define private_pool_free( \
849 free_pool, \
850 alElement_p \
851 ) \
852 { \
853 /* Push the list element back to the head to get better locality of */ \
854 /* reference with the cache. */ \
855 private_push_front(&(free_pool)->free_list, (alElement_p)); \
856 }
857
858 /**
859 * This private method will allocate a list element from the pool of free
860 * list elements.
861 */
862 #define private_pool_allocate(free_pool) \
863 ({ \
864 SCI_ABSTRACT_ELEMENT_T * alElement_p; \
865 \
866 alElement_p = private_pop_front(&(free_pool)->free_list); \
867 \
868 memset(alElement_p, 0, sizeof(SCI_ABSTRACT_ELEMENT_T)); \
869 alElement_p; \
870 })
871
872 #endif
873 #endif // _ABSTRACT_LIST_H_
Cache object: 54e046f01d208080f1dbbc1d428857a8
|