1230557Sjimharris/*-
2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license.  When using or
3230557Sjimharris * redistributing this file, you may do so under either license.
4230557Sjimharris *
5230557Sjimharris * GPL LICENSE SUMMARY
6230557Sjimharris *
7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8230557Sjimharris *
9230557Sjimharris * This program is free software; you can redistribute it and/or modify
10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as
11230557Sjimharris * published by the Free Software Foundation.
12230557Sjimharris *
13230557Sjimharris * This program is distributed in the hope that it will be useful, but
14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of
15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16230557Sjimharris * General Public License for more details.
17230557Sjimharris *
18230557Sjimharris * You should have received a copy of the GNU General Public License
19230557Sjimharris * along with this program; if not, write to the Free Software
20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21230557Sjimharris * The full GNU General Public License is included in this distribution
22230557Sjimharris * in the file called LICENSE.GPL.
23230557Sjimharris *
24230557Sjimharris * BSD LICENSE
25230557Sjimharris *
26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27230557Sjimharris * All rights reserved.
28230557Sjimharris *
29230557Sjimharris * Redistribution and use in source and binary forms, with or without
30230557Sjimharris * modification, are permitted provided that the following conditions
31230557Sjimharris * are met:
32230557Sjimharris *
33230557Sjimharris *   * Redistributions of source code must retain the above copyright
34230557Sjimharris *     notice, this list of conditions and the following disclaimer.
35230557Sjimharris *   * Redistributions in binary form must reproduce the above copyright
36230557Sjimharris *     notice, this list of conditions and the following disclaimer in
37230557Sjimharris *     the documentation and/or other materials provided with the
38230557Sjimharris *     distribution.
39230557Sjimharris *
40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51230557Sjimharris */
52230557Sjimharris
53230557Sjimharris#include <sys/cdefs.h>
54230557Sjimharris__FBSDID("$FreeBSD$");
55230557Sjimharris
56230557Sjimharris/**
57230557Sjimharris * @file
58230557Sjimharris *
59230557Sjimharris * @brief This file contains the implementation of an abstract list class.
60230557Sjimharris *        This class will allow for the same item to occur multiple times in
61230557Sjimharris *        the list.  It will provide an interface that is similar to the
62230557Sjimharris *        C++ standard template list interface.
63230557Sjimharris */
64230557Sjimharris
65230557Sjimharris//******************************************************************************
66230557Sjimharris//*
67230557Sjimharris//*     I N C L U D E S
68230557Sjimharris//*
69230557Sjimharris//******************************************************************************
70230557Sjimharris
71230557Sjimharris#include <dev/isci/scil/sci_abstract_list.h>
72230557Sjimharris
73230557Sjimharris
74230557Sjimharris//******************************************************************************
75230557Sjimharris//*
76230557Sjimharris//*     P R I V A T E   M E M B E R S
77230557Sjimharris//*
78230557Sjimharris//******************************************************************************
79230557Sjimharris
80230557Sjimharris//******************************************************************************
81230557Sjimharris//*
82230557Sjimharris//*     P R O T E C T E D   M E T H O D S
83230557Sjimharris//*
84230557Sjimharris//******************************************************************************
85230557Sjimharris
86230557Sjimharris/**
87230557Sjimharris * @brief Initialize the abstract list
88230557Sjimharris *
89230557Sjimharris * @pre The supplied free pool should be constructed prior to utilization
90230557Sjimharris *      of this abstract list.  It isn't mandatory for the free pool to be
91230557Sjimharris *      constructed before invoking this method, but suggested.
92230557Sjimharris *
93230557Sjimharris * @param[in] list This parameter specifies the abstract list to be
94230557Sjimharris *            constructed.
95230557Sjimharris * @param[in] free_pool This parameter specifies the free pool to be
96230557Sjimharris *            utilized as the repository of free elements for list usage.
97230557Sjimharris *
98230557Sjimharris * @return none
99230557Sjimharris */
100230557Sjimharrisvoid sci_abstract_list_construct(
101230557Sjimharris   SCI_ABSTRACT_LIST_T         * list,
102230557Sjimharris   SCI_ABSTRACT_ELEMENT_POOL_T * free_pool
103230557Sjimharris)
104230557Sjimharris{
105230557Sjimharris   memset(list, 0, sizeof(SCI_ABSTRACT_LIST_T));
106230557Sjimharris   list->free_pool = free_pool;
107230557Sjimharris}
108230557Sjimharris
109230557Sjimharris/**
110230557Sjimharris * Initialize the abstract list with its free pool
111230557Sjimharris *
112230557Sjimharris * @param[in] pool
113230557Sjimharris *    the free pool from which the elements will be extracted
114230557Sjimharris * @param[in] list_elements
115230557Sjimharris *    the array of list elements to be added to the free list
116230557Sjimharris * @param[in] element_count
117230557Sjimharris *    the count of the elements to be added to the free list these should be
118230557Sjimharris *    the same as the array size of list elements
119230557Sjimharris *
120230557Sjimharris * @return none
121230557Sjimharris */
122230557Sjimharrisvoid sci_abstract_element_pool_construct(
123230557Sjimharris   SCI_ABSTRACT_ELEMENT_POOL_T * pool,
124230557Sjimharris   SCI_ABSTRACT_ELEMENT_T      * list_elements,
125230557Sjimharris   int                           element_count
126230557Sjimharris)
127230557Sjimharris{
128230557Sjimharris   int index;
129230557Sjimharris
130230557Sjimharris   memset(pool, 0, sizeof(SCI_ABSTRACT_ELEMENT_POOL_T));
131230557Sjimharris   memset(list_elements, 0, sizeof(SCI_ABSTRACT_ELEMENT_T) * element_count);
132230557Sjimharris
133230557Sjimharris   pool->elements     = list_elements;
134230557Sjimharris   pool->max_elements = element_count;
135230557Sjimharris
136230557Sjimharris   // Loop through all of the elements in the array and push them onto the
137230557Sjimharris   // pool's free list.
138230557Sjimharris   for (index = element_count - 1; index >= 0; index--)
139230557Sjimharris   {
140230557Sjimharris      private_pool_free(pool, &(list_elements[index]));
141230557Sjimharris   }
142230557Sjimharris}
143230557Sjimharris
144230557Sjimharris
145230557Sjimharris#ifdef USE_ABSTRACT_LIST_FUNCTIONS
146230557Sjimharris
147230557Sjimharris//******************************************************************************
148230557Sjimharris//*
149230557Sjimharris//*     P U B L I C   M E T H O D S
150230557Sjimharris//*
151230557Sjimharris//******************************************************************************
152230557Sjimharris
153230557Sjimharris/**
154230557Sjimharris * Simply return the front element pointer of the list.  This returns an element
155230557Sjimharris * element as opposed to what the element is pointing to.
156230557Sjimharris */
157230557SjimharrisSCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_front(
158230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
159230557Sjimharris)
160230557Sjimharris{
161230557Sjimharris   return (list_p)->elements.front_p;
162230557Sjimharris}
163230557Sjimharris
164230557Sjimharris/**
165230557Sjimharris * This method simply returns the object pointed to by the head (front) of
166230557Sjimharris * the list.
167230557Sjimharris */
168230557Sjimharrisvoid * sci_abstract_list_front(
169230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
170230557Sjimharris)
171230557Sjimharris{
172230557Sjimharris   return
173230557Sjimharris      ( ( (list_p)->elements.front_p ) ? ((list_p)->elements.front_p->object_p) : NULL );
174230557Sjimharris}
175230557Sjimharris
176230557Sjimharris/**
177230557Sjimharris * This method simply returns the object pointed to by the tail (back) of
178230557Sjimharris * the list.
179230557Sjimharris */
180230557Sjimharrisvoid * sci_abstract_list_back(
181230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
182230557Sjimharris)
183230557Sjimharris{
184230557Sjimharris   return
185230557Sjimharris      ( ( (list_p)->elements.back_p ) ? ((list_p)->elements.back_p->object_p) : NULL );
186230557Sjimharris}
187230557Sjimharris
188230557Sjimharris/**
189230557Sjimharris * This method will return FALSE if the list is not empty.
190230557Sjimharris */
191230557SjimharrisBOOL sci_abstract_list_is_empty(
192230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
193230557Sjimharris)
194230557Sjimharris{
195230557Sjimharris   return ( (list_p)->elements.front_p == NULL );
196230557Sjimharris}
197230557Sjimharris
198230557Sjimharris
199230557Sjimharris/**
200230557Sjimharris * This method will return the number of elements queued in the list.
201230557Sjimharris */
202230557SjimharrisU32 sci_abstract_list_size(
203230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
204230557Sjimharris)
205230557Sjimharris{
206230557Sjimharris   return ( (list_p)->elements.size );
207230557Sjimharris}
208230557Sjimharris
209230557Sjimharris
210230557Sjimharris/**
211230557Sjimharris * This method simply returns the next list element in the list.
212230557Sjimharris */
213230557SjimharrisSCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_next(
214230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p
215230557Sjimharris)
216230557Sjimharris{
217230557Sjimharris   return ( (alElement_p)->next_p );
218230557Sjimharris}
219230557Sjimharris
220230557Sjimharris
221230557Sjimharris#if defined(SCI_LOGGING)
222230557Sjimharris/**
223230557Sjimharris * This method simply prints the contents of the list.
224230557Sjimharris */
225230557Sjimharrisvoid  sci_abstract_list_print(
226230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
227230557Sjimharris)
228230557Sjimharris{
229230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p = list_p->elements.front_p;
230230557Sjimharris
231230557Sjimharris   while (alElement_p != NULL)
232230557Sjimharris   {
233230557Sjimharris#ifdef UNIT_TEST_DEBUG
234230557Sjimharris      /* Check to see if we found the object for which we are searching. */
235230557Sjimharris      printf("ITEM next_p 0x%x prev_p 0x%x obj_p 0x%x, 0x%x\n",
236230557Sjimharris             alElement_p->next_p,
237230557Sjimharris             alElement_p->previous_p,
238230557Sjimharris             (U32*) (alElement_p->object_p));
239230557Sjimharris#endif
240230557Sjimharris      alElement_p = alElement_p->next_p;
241230557Sjimharris   }
242230557Sjimharris}
243230557Sjimharris#endif // defined(SCI_LOGGING)
244230557Sjimharris
245230557Sjimharris
246230557Sjimharris/**
247230557Sjimharris * This method will simply search the supplied list for the desired object.
248230557Sjimharris * It will return a pointer to the object, if it is found.  Otherwise
249230557Sjimharris * it will return NULL.
250230557Sjimharris */
251230557Sjimharrisvoid * sci_abstract_list_find(
252230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p,
253230557Sjimharris   void * obj_p
254230557Sjimharris)
255230557Sjimharris{
256230557Sjimharris   return
257230557Sjimharris      sci_abstract_list_get_object(private_find(&(list_p)->elements, (obj_p)));
258230557Sjimharris}
259230557Sjimharris
260230557Sjimharris
261230557Sjimharris/**
262230557Sjimharris * This method will simply remove the element at the back (tail) of the list.
263230557Sjimharris * It will return a pointer to the object that was removed or NULL if not
264230557Sjimharris * found.
265230557Sjimharris */
266230557Sjimharrisvoid * sci_abstract_list_popback(
267230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
268230557Sjimharris)
269230557Sjimharris{
270230557Sjimharris   SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;
271230557Sjimharris   SCI_ABSTRACT_ELEMENT_T      * alElement_p = elem_list->back_p;
272230557Sjimharris   void * obj_p = NULL;
273230557Sjimharris
274230557Sjimharris   if (alElement_p != NULL)
275230557Sjimharris   {
276230557Sjimharris      obj_p = alElement_p->object_p;
277230557Sjimharris      if (elem_list->back_p == elem_list->front_p)
278230557Sjimharris      {
279230557Sjimharris         elem_list->back_p = elem_list->front_p = NULL;
280230557Sjimharris      }
281230557Sjimharris      else
282230557Sjimharris      {
283230557Sjimharris         elem_list->back_p = elem_list->back_p->previous_p;
284230557Sjimharris         elem_list->back_p->next_p = NULL;
285230557Sjimharris      }
286230557Sjimharris
287230557Sjimharris      elem_list->size--;
288230557Sjimharris      private_pool_free((list_p)->free_pool, alElement_p);
289230557Sjimharris   }
290230557Sjimharris
291230557Sjimharris   return obj_p;
292230557Sjimharris}
293230557Sjimharris
294230557Sjimharris/**
295230557Sjimharris * This method simply removes the list element at the head of the list
296230557Sjimharris * and returns the pointer to the object that was removed.
297230557Sjimharris */
298230557Sjimharrisvoid * sci_abstract_list_popfront(
299230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
300230557Sjimharris)
301230557Sjimharris{
302230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p =
303230557Sjimharris                              private_pop_front(&(list_p)->elements);
304230557Sjimharris   void * obj_p = NULL;
305230557Sjimharris
306230557Sjimharris   if (alElement_p != NULL)
307230557Sjimharris   {
308230557Sjimharris      obj_p = alElement_p->object_p;
309230557Sjimharris      private_pool_free((list_p)->free_pool, alElement_p);
310230557Sjimharris   }
311230557Sjimharris
312230557Sjimharris   return obj_p;
313230557Sjimharris}
314230557Sjimharris
315230557Sjimharris
316230557Sjimharris
317230557Sjimharris/**
318230557Sjimharris * This method will erase (remove) all instances of the supplied object from
319230557Sjimharris * anywhere in the list.
320230557Sjimharris */
321230557Sjimharrisvoid sci_abstract_list_erase(
322230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p,
323230557Sjimharris   void * obj_p
324230557Sjimharris)
325230557Sjimharris{
326230557Sjimharris   SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;
327230557Sjimharris   SCI_ABSTRACT_ELEMENT_T      * alElement_p;
328230557Sjimharris
329230557Sjimharris   while ((alElement_p = private_find(elem_list, (obj_p))) != NULL)
330230557Sjimharris   {
331230557Sjimharris      if (alElement_p == elem_list->front_p)
332230557Sjimharris      {
333230557Sjimharris         sci_abstract_list_popfront(list_p);
334230557Sjimharris      }
335230557Sjimharris      else if (alElement_p == elem_list->back_p)
336230557Sjimharris      {
337230557Sjimharris         sci_abstract_list_popback(list_p);
338230557Sjimharris      }
339230557Sjimharris      else
340230557Sjimharris      {
341230557Sjimharris         alElement_p->previous_p->next_p = alElement_p->next_p;
342230557Sjimharris         alElement_p->next_p->previous_p = alElement_p->previous_p;
343230557Sjimharris         elem_list->size--;
344230557Sjimharris         private_pool_free((list_p)->free_pool, alElement_p);
345230557Sjimharris      }
346230557Sjimharris   }
347230557Sjimharris   return;
348230557Sjimharris}
349230557Sjimharris
350230557Sjimharris/**
351230557Sjimharris * This method simply adds a LIST_ELEMENT for the supplied object to the back
352230557Sjimharris * (tail) of the supplied list.
353230557Sjimharris */
354230557Sjimharrisvoid sci_abstract_list_pushback(
355230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p,
356230557Sjimharris   void * obj_p
357230557Sjimharris)
358230557Sjimharris{
359230557Sjimharris   SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;
360230557Sjimharris   SCI_ABSTRACT_ELEMENT_T      * alElement_p
361230557Sjimharris      = private_pool_allocate((list_p)->free_pool);
362230557Sjimharris//   assert(alElement_p != NULL);
363230557Sjimharris
364230557Sjimharris   alElement_p->object_p = (obj_p);
365230557Sjimharris
366230557Sjimharris   if (elem_list->front_p == NULL)
367230557Sjimharris   {
368230557Sjimharris      elem_list->front_p = elem_list->back_p = alElement_p;
369230557Sjimharris   }
370230557Sjimharris   else
371230557Sjimharris   {
372230557Sjimharris      elem_list->back_p->next_p = alElement_p;
373230557Sjimharris      alElement_p->previous_p   = elem_list->back_p;
374230557Sjimharris      elem_list->back_p         = alElement_p;
375230557Sjimharris   }
376230557Sjimharris
377230557Sjimharris   elem_list->size++;
378230557Sjimharris}
379230557Sjimharris
380230557Sjimharris
381230557Sjimharris
382230557Sjimharris/**
383230557Sjimharris * This method simply adds a LIST_ELEMENT for the supplied object to the front
384230557Sjimharris * (head) of the supplied list.
385230557Sjimharris */
386230557Sjimharrisvoid sci_abstract_list_pushfront(
387230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p,
388230557Sjimharris   void * obj_p
389230557Sjimharris)
390230557Sjimharris{
391230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p =
392230557Sjimharris         private_pool_allocate((list_p)->free_pool);
393230557Sjimharris   alElement_p->object_p = (obj_p);
394230557Sjimharris   private_push_front(&(list_p)->elements, alElement_p);
395230557Sjimharris}
396230557Sjimharris
397230557Sjimharris
398230557Sjimharris/**
399230557Sjimharris * This method will add the objToAdd_p object to the list before the obj_p.
400230557Sjimharris *
401230557Sjimharris */
402230557Sjimharrisvoid sci_abstract_list_insert(
403230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p,
404230557Sjimharris   void * obj_p,
405230557Sjimharris   void * objToAdd_p
406230557Sjimharris)
407230557Sjimharris{
408230557Sjimharris   SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;
409230557Sjimharris
410230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * obj_element = private_find(elem_list, obj_p);
411230557Sjimharris
412230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * objToAdd_element =
413230557Sjimharris      private_pool_allocate((list_p)->free_pool);
414230557Sjimharris
415230557Sjimharris   objToAdd_element->object_p = objToAdd_p;
416230557Sjimharris
417230557Sjimharris   ASSERT(obj_element != NULL);
418230557Sjimharris   ASSERT(objToAdd_element != NULL);
419230557Sjimharris
420230557Sjimharris   if (obj_element == elem_list->front_p)
421230557Sjimharris   {
422230557Sjimharris      objToAdd_element->object_p = (objToAdd_p);
423230557Sjimharris      private_push_front(&(list_p)->elements, objToAdd_element);
424230557Sjimharris   }
425230557Sjimharris   else
426230557Sjimharris   {
427230557Sjimharris      obj_element->previous_p->next_p = objToAdd_element;
428230557Sjimharris      objToAdd_element->previous_p = obj_element->previous_p;
429230557Sjimharris
430230557Sjimharris      obj_element->previous_p = objToAdd_element;
431230557Sjimharris      objToAdd_element->next_p = obj_element;
432230557Sjimharris
433230557Sjimharris      elem_list->size++;
434230557Sjimharris   }
435230557Sjimharris}
436230557Sjimharris
437230557Sjimharris/**
438230557Sjimharris * This method simply frees all the items from the list.
439230557Sjimharris */
440230557Sjimharrisvoid sci_abstract_list_clear(
441230557Sjimharris   SCI_ABSTRACT_LIST_T * list_p
442230557Sjimharris)
443230557Sjimharris{
444230557Sjimharris   while ((list_p)->elements.size > 0)
445230557Sjimharris      sci_abstract_list_popfront((list_p));
446230557Sjimharris}
447230557Sjimharris
448230557Sjimharris/**
449230557Sjimharris * This method simply returns the object being pointed to by the list element
450230557Sjimharris * (The item being listed).
451230557Sjimharris */
452230557Sjimharrisvoid * sci_abstract_list_get_object(
453230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p
454230557Sjimharris)
455230557Sjimharris{
456230557Sjimharris   void * obj_p = NULL;
457230557Sjimharris   if ((alElement_p) != NULL)
458230557Sjimharris      obj_p = (alElement_p)->object_p;
459230557Sjimharris
460230557Sjimharris   return obj_p;
461230557Sjimharris}
462230557Sjimharris
463230557Sjimharris
464230557Sjimharris/**
465230557Sjimharris * This method is simply a wrapper to provide the number of elements in
466230557Sjimharris * the free list.
467230557Sjimharris */
468230557SjimharrisU32 sci_abstract_list_freeList_size(
469230557Sjimharris   SCI_ABSTRACT_LIST_T * freeList
470230557Sjimharris)
471230557Sjimharris{
472230557Sjimharris   return (sci_abstract_list_size(freeList));
473230557Sjimharris}
474230557Sjimharris
475230557Sjimharris//******************************************************************************
476230557Sjimharris//*
477230557Sjimharris//*     P R I V A T E   M E T H O D S
478230557Sjimharris//*
479230557Sjimharris//******************************************************************************
480230557Sjimharris
481230557Sjimharris/**
482230557Sjimharris * This method simply performs the common portion of pushing a list element
483230557Sjimharris * onto a list.
484230557Sjimharris *
485230557Sjimharris * WARNING: This is a private helper method that should not be called directly
486230557Sjimharris *          by any users.
487230557Sjimharris */
488230557Sjimharrisvoid private_push_front(
489230557Sjimharris   SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p,
490230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p
491230557Sjimharris)
492230557Sjimharris{
493230557Sjimharris   if ((privateList_p)->front_p == NULL)
494230557Sjimharris   {
495230557Sjimharris      (privateList_p)->front_p = (privateList_p)->back_p = (alElement_p);
496230557Sjimharris      (alElement_p)->next_p = (alElement_p)->previous_p = NULL;
497230557Sjimharris   }
498230557Sjimharris   else
499230557Sjimharris   {
500230557Sjimharris      (alElement_p)->next_p                = (privateList_p)->front_p;
501230557Sjimharris      (alElement_p)->previous_p            = NULL;
502230557Sjimharris      (privateList_p)->front_p->previous_p = (alElement_p);
503230557Sjimharris      (privateList_p)->front_p             = (alElement_p);
504230557Sjimharris   }
505230557Sjimharris
506230557Sjimharris   (privateList_p)->size++;
507230557Sjimharris}
508230557Sjimharris
509230557Sjimharris/**
510230557Sjimharris * This method simply performs the common portion of popping a list element
511230557Sjimharris * from a list.
512230557Sjimharris *
513230557Sjimharris * WARNING: This is a private helper method that should not be called directly
514230557Sjimharris *          by any users.
515230557Sjimharris */
516230557SjimharrisSCI_ABSTRACT_ELEMENT_T * private_pop_front(
517230557Sjimharris   SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p
518230557Sjimharris)
519230557Sjimharris{
520230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p = (privateList_p)->front_p;
521230557Sjimharris
522230557Sjimharris   if (alElement_p != NULL)
523230557Sjimharris   {
524230557Sjimharris      if ((privateList_p)->front_p == (privateList_p)->back_p)
525230557Sjimharris      {
526230557Sjimharris         (privateList_p)->front_p = (privateList_p)->back_p = NULL;
527230557Sjimharris      }
528230557Sjimharris      else
529230557Sjimharris      {
530230557Sjimharris         (privateList_p)->front_p = (privateList_p)->front_p->next_p;
531230557Sjimharris         (privateList_p)->front_p->previous_p = NULL;
532230557Sjimharris      }
533230557Sjimharris
534230557Sjimharris      (privateList_p)->size--;
535230557Sjimharris   }
536230557Sjimharris
537230557Sjimharris   return alElement_p;
538230557Sjimharris}
539230557Sjimharris
540230557Sjimharris/**
541230557Sjimharris * This method will simply search the supplied list for the desired object.
542230557Sjimharris * It will return a pointer to the abstract_list_element if found, otherwise
543230557Sjimharris * it will return NULL.
544230557Sjimharris */
545230557SjimharrisSCI_ABSTRACT_ELEMENT_T * private_find(
546230557Sjimharris   SCI_ABSTRACT_ELEMENT_LIST_T * list_p,
547230557Sjimharris   void * obj_p
548230557Sjimharris)
549230557Sjimharris{
550230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p = (list_p)->front_p;
551230557Sjimharris
552230557Sjimharris   while (alElement_p != NULL)
553230557Sjimharris   {
554230557Sjimharris      /* Check to see if we found the object for which we are searching. */
555230557Sjimharris      if (alElement_p->object_p == (void*) (obj_p))
556230557Sjimharris      {
557230557Sjimharris         break;
558230557Sjimharris      }
559230557Sjimharris
560230557Sjimharris      alElement_p = alElement_p->next_p;
561230557Sjimharris   }
562230557Sjimharris
563230557Sjimharris   return alElement_p;
564230557Sjimharris}
565230557Sjimharris
566230557Sjimharris/**
567230557Sjimharris * This private method will free the supplied list element back to the pool
568230557Sjimharris * of free list elements.
569230557Sjimharris */
570230557Sjimharrisvoid private_pool_free(
571230557Sjimharris   SCI_ABSTRACT_ELEMENT_POOL_T * free_pool,
572230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p
573230557Sjimharris)
574230557Sjimharris{
575230557Sjimharris   /* Push the list element back to the head to get better locality of */
576230557Sjimharris   /* reference with the cache.                                        */
577230557Sjimharris   private_push_front(&(free_pool)->free_list, (alElement_p));
578230557Sjimharris}
579230557Sjimharris
580230557Sjimharris/**
581230557Sjimharris * This private method will allocate a list element from the pool of free
582230557Sjimharris * list elements.
583230557Sjimharris */
584230557SjimharrisSCI_ABSTRACT_ELEMENT_T * private_pool_allocate(
585230557Sjimharris   SCI_ABSTRACT_ELEMENT_POOL_T * free_pool
586230557Sjimharris)
587230557Sjimharris{
588230557Sjimharris   SCI_ABSTRACT_ELEMENT_T * alElement_p;
589230557Sjimharris
590230557Sjimharris   alElement_p = private_pop_front(&(free_pool)->free_list);
591230557Sjimharris
592230557Sjimharris   alElement_p->next_p     = NULL;
593230557Sjimharris   alElement_p->previous_p = NULL;
594230557Sjimharris   alElement_p->object_p   = NULL;
595230557Sjimharris
596230557Sjimharris   return alElement_p;
597230557Sjimharris}
598230557Sjimharris
599230557Sjimharris#endif // USE_ABSTRACT_LIST_FUNCTIONS
600