sci_abstract_list.c revision 231136
1173362Sbenjsc/*-
2173362Sbenjsc * This file is provided under a dual BSD/GPLv2 license.  When using or
3173362Sbenjsc * redistributing this file, you may do so under either license.
4173362Sbenjsc *
5173362Sbenjsc * GPL LICENSE SUMMARY
6173362Sbenjsc *
7173362Sbenjsc * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8173362Sbenjsc *
9173362Sbenjsc * This program is free software; you can redistribute it and/or modify
10173362Sbenjsc * it under the terms of version 2 of the GNU General Public License as
11173362Sbenjsc * published by the Free Software Foundation.
12173362Sbenjsc *
13173362Sbenjsc * This program is distributed in the hope that it will be useful, but
14173362Sbenjsc * WITHOUT ANY WARRANTY; without even the implied warranty of
15173362Sbenjsc * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16173362Sbenjsc * General Public License for more details.
17173362Sbenjsc *
18173362Sbenjsc * You should have received a copy of the GNU General Public License
19173362Sbenjsc * along with this program; if not, write to the Free Software
20173362Sbenjsc * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21173362Sbenjsc * The full GNU General Public License is included in this distribution
22173362Sbenjsc * in the file called LICENSE.GPL.
23173362Sbenjsc *
24173362Sbenjsc * BSD LICENSE
25173362Sbenjsc *
26173362Sbenjsc * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27173362Sbenjsc * All rights reserved.
28173362Sbenjsc *
29173362Sbenjsc * Redistribution and use in source and binary forms, with or without
30173362Sbenjsc * modification, are permitted provided that the following conditions
31173362Sbenjsc * are met:
32173362Sbenjsc *
33173362Sbenjsc *   * Redistributions of source code must retain the above copyright
34173362Sbenjsc *     notice, this list of conditions and the following disclaimer.
35173362Sbenjsc *   * Redistributions in binary form must reproduce the above copyright
36173362Sbenjsc *     notice, this list of conditions and the following disclaimer in
37173362Sbenjsc *     the documentation and/or other materials provided with the
38173362Sbenjsc *     distribution.
39173362Sbenjsc *
40173362Sbenjsc * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41173362Sbenjsc * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42173362Sbenjsc * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43173362Sbenjsc * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44173362Sbenjsc * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45173362Sbenjsc * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46173362Sbenjsc * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47177043Sthompsa * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48173362Sbenjsc * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49173362Sbenjsc * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50173362Sbenjsc * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51173362Sbenjsc */
52173362Sbenjsc
53173362Sbenjsc#include <sys/cdefs.h>
54173362Sbenjsc__FBSDID("$FreeBSD: head/sys/dev/isci/scil/sci_abstract_list.c 231136 2012-02-07 17:43:58Z jimharris $");
55173362Sbenjsc
56173362Sbenjsc/**
57173362Sbenjsc * @file
58173362Sbenjsc *
59173362Sbenjsc * @brief This file contains the implementation of an abstract list class.
60173362Sbenjsc *        This class will allow for the same item to occur multiple times in
61173362Sbenjsc *        the list.  It will provide an interface that is similar to the
62173362Sbenjsc *        C++ standard template list interface.
63173362Sbenjsc */
64173362Sbenjsc
65173362Sbenjsc//******************************************************************************
66173362Sbenjsc//*
67173362Sbenjsc//*     I N C L U D E S
68173362Sbenjsc//*
69173362Sbenjsc//******************************************************************************
70173362Sbenjsc
71173362Sbenjsc#include <dev/isci/scil/sci_abstract_list.h>
72173362Sbenjsc
73173362Sbenjsc
74173362Sbenjsc//******************************************************************************
75173362Sbenjsc//*
76173362Sbenjsc//*     P R I V A T E   M E M B E R S
77173362Sbenjsc//*
78173362Sbenjsc//******************************************************************************
79173362Sbenjsc
80173362Sbenjsc//******************************************************************************
81173362Sbenjsc//*
82173362Sbenjsc//*     P R O T E C T E D   M E T H O D S
83173362Sbenjsc//*
84173362Sbenjsc//******************************************************************************
85173362Sbenjsc
86173362Sbenjsc/**
87173362Sbenjsc * @brief Initialize the abstract list
88173362Sbenjsc *
89173362Sbenjsc * @pre The supplied free pool should be constructed prior to utilization
90173362Sbenjsc *      of this abstract list.  It isn't mandatory for the free pool to be
91173362Sbenjsc *      constructed before invoking this method, but suggested.
92173362Sbenjsc *
93173362Sbenjsc * @param[in] list This parameter specifies the abstract list to be
94173362Sbenjsc *            constructed.
95173362Sbenjsc * @param[in] free_pool This parameter specifies the free pool to be
96173362Sbenjsc *            utilized as the repository of free elements for list usage.
97173362Sbenjsc *
98173362Sbenjsc * @return none
99173362Sbenjsc */
100173362Sbenjscvoid sci_abstract_list_construct(
101173362Sbenjsc   SCI_ABSTRACT_LIST_T         * list,
102173362Sbenjsc   SCI_ABSTRACT_ELEMENT_POOL_T * free_pool
103173362Sbenjsc)
104173362Sbenjsc{
105173362Sbenjsc   memset(list, 0, sizeof(SCI_ABSTRACT_LIST_T));
106173362Sbenjsc   list->free_pool = free_pool;
107173362Sbenjsc}
108173362Sbenjsc
109173362Sbenjsc/**
110173362Sbenjsc * Initialize the abstract list with its free pool
111173362Sbenjsc *
112173362Sbenjsc * @param[in] pool
113173362Sbenjsc *    the free pool from which the elements will be extracted
114173362Sbenjsc * @param[in] list_elements
115173362Sbenjsc *    the array of list elements to be added to the free list
116173362Sbenjsc * @param[in] element_count
117173362Sbenjsc *    the count of the elements to be added to the free list these should be
118173362Sbenjsc *    the same as the array size of list elements
119173362Sbenjsc *
120173362Sbenjsc * @return none
121173362Sbenjsc */
122173362Sbenjscvoid sci_abstract_element_pool_construct(
123173362Sbenjsc   SCI_ABSTRACT_ELEMENT_POOL_T * pool,
124173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T      * list_elements,
125173362Sbenjsc   int                           element_count
126173362Sbenjsc)
127173362Sbenjsc{
128173362Sbenjsc   int index;
129173362Sbenjsc
130173362Sbenjsc   memset(pool, 0, sizeof(SCI_ABSTRACT_ELEMENT_POOL_T));
131173362Sbenjsc   memset(list_elements, 0, sizeof(SCI_ABSTRACT_ELEMENT_T) * element_count);
132173362Sbenjsc
133173362Sbenjsc   pool->elements     = list_elements;
134173362Sbenjsc   pool->max_elements = element_count;
135173362Sbenjsc
136173362Sbenjsc   // Loop through all of the elements in the array and push them onto the
137173362Sbenjsc   // pool's free list.
138173362Sbenjsc   for (index = element_count - 1; index >= 0; index--)
139173362Sbenjsc   {
140173362Sbenjsc      private_pool_free(pool, &(list_elements[index]));
141173362Sbenjsc   }
142173362Sbenjsc}
143173362Sbenjsc
144173362Sbenjsc
145173362Sbenjsc#ifdef USE_ABSTRACT_LIST_FUNCTIONS
146261455Seadler
147173362Sbenjsc//******************************************************************************
148173362Sbenjsc//*
149173362Sbenjsc//*     P U B L I C   M E T H O D S
150173362Sbenjsc//*
151173362Sbenjsc//******************************************************************************
152173362Sbenjsc
153173362Sbenjsc/**
154261455Seadler * Simply return the front element pointer of the list.  This returns an element
155173362Sbenjsc * element as opposed to what the element is pointing to.
156173362Sbenjsc */
157173362SbenjscSCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_front(
158173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
159173362Sbenjsc)
160173362Sbenjsc{
161173362Sbenjsc   return (list_p)->elements.front_p;
162173362Sbenjsc}
163173362Sbenjsc
164173362Sbenjsc/**
165173362Sbenjsc * This method simply returns the object pointed to by the head (front) of
166173362Sbenjsc * the list.
167173362Sbenjsc */
168173362Sbenjscvoid * sci_abstract_list_front(
169173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
170173362Sbenjsc)
171173362Sbenjsc{
172173362Sbenjsc   return
173173362Sbenjsc      ( ( (list_p)->elements.front_p ) ? ((list_p)->elements.front_p->object_p) : NULL );
174173362Sbenjsc}
175173362Sbenjsc
176173362Sbenjsc/**
177173362Sbenjsc * This method simply returns the object pointed to by the tail (back) of
178173362Sbenjsc * the list.
179173362Sbenjsc */
180173362Sbenjscvoid * sci_abstract_list_back(
181173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
182173362Sbenjsc)
183173362Sbenjsc{
184173362Sbenjsc   return
185173362Sbenjsc      ( ( (list_p)->elements.back_p ) ? ((list_p)->elements.back_p->object_p) : NULL );
186173362Sbenjsc}
187173362Sbenjsc
188173362Sbenjsc/**
189173362Sbenjsc * This method will return FALSE if the list is not empty.
190173362Sbenjsc */
191173362SbenjscBOOL sci_abstract_list_is_empty(
192173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
193173362Sbenjsc)
194173362Sbenjsc{
195173362Sbenjsc   return ( (list_p)->elements.front_p == NULL );
196173362Sbenjsc}
197173362Sbenjsc
198173362Sbenjsc
199173362Sbenjsc/**
200173362Sbenjsc * This method will return the number of elements queued in the list.
201173362Sbenjsc */
202173362SbenjscU32 sci_abstract_list_size(
203173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
204173362Sbenjsc)
205177043Sthompsa{
206173362Sbenjsc   return ( (list_p)->elements.size );
207173362Sbenjsc}
208173976Sbenjsc
209173362Sbenjsc
210173362Sbenjsc/**
211173362Sbenjsc * This method simply returns the next list element in the list.
212173362Sbenjsc */
213173362SbenjscSCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_next(
214173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p
215173362Sbenjsc)
216173362Sbenjsc{
217173362Sbenjsc   return ( (alElement_p)->next_p );
218173362Sbenjsc}
219173362Sbenjsc
220173362Sbenjsc
221173362Sbenjsc#if defined(SCI_LOGGING)
222173362Sbenjsc/**
223173362Sbenjsc * This method simply prints the contents of the list.
224173362Sbenjsc */
225173362Sbenjscvoid  sci_abstract_list_print(
226173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
227173362Sbenjsc)
228173362Sbenjsc{
229173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p = list_p->elements.front_p;
230173362Sbenjsc
231173362Sbenjsc   while (alElement_p != NULL)
232173362Sbenjsc   {
233173362Sbenjsc#ifdef UNIT_TEST_DEBUG
234173362Sbenjsc      /* Check to see if we found the object for which we are searching. */
235173362Sbenjsc      printf("ITEM next_p 0x%x prev_p 0x%x obj_p 0x%x, 0x%x\n",
236173362Sbenjsc             alElement_p->next_p,
237173362Sbenjsc             alElement_p->previous_p,
238173362Sbenjsc             (U32*) (alElement_p->object_p));
239173362Sbenjsc#endif
240173362Sbenjsc      alElement_p = alElement_p->next_p;
241173362Sbenjsc   }
242173362Sbenjsc}
243173362Sbenjsc#endif // defined(SCI_LOGGING)
244173362Sbenjsc
245173362Sbenjsc
246173362Sbenjsc/**
247173362Sbenjsc * This method will simply search the supplied list for the desired object.
248173362Sbenjsc * It will return a pointer to the object, if it is found.  Otherwise
249173362Sbenjsc * it will return NULL.
250173362Sbenjsc */
251173362Sbenjscvoid * sci_abstract_list_find(
252173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p,
253173362Sbenjsc   void * obj_p
254173362Sbenjsc)
255173362Sbenjsc{
256173362Sbenjsc   return
257173362Sbenjsc      sci_abstract_list_get_object(private_find(&(list_p)->elements, (obj_p)));
258173362Sbenjsc}
259173362Sbenjsc
260173362Sbenjsc
261173362Sbenjsc/**
262173362Sbenjsc * This method will simply remove the element at the back (tail) of the list.
263173362Sbenjsc * It will return a pointer to the object that was removed or NULL if not
264173362Sbenjsc * found.
265173362Sbenjsc */
266173362Sbenjscvoid * sci_abstract_list_popback(
267173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
268173362Sbenjsc)
269173362Sbenjsc{
270173362Sbenjsc   SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;
271173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T      * alElement_p = elem_list->back_p;
272173362Sbenjsc   void * obj_p = NULL;
273173362Sbenjsc
274173362Sbenjsc   if (alElement_p != NULL)
275173362Sbenjsc   {
276173362Sbenjsc      obj_p = alElement_p->object_p;
277173362Sbenjsc      if (elem_list->back_p == elem_list->front_p)
278173362Sbenjsc      {
279173362Sbenjsc         elem_list->back_p = elem_list->front_p = NULL;
280173362Sbenjsc      }
281173362Sbenjsc      else
282173362Sbenjsc      {
283173362Sbenjsc         elem_list->back_p = elem_list->back_p->previous_p;
284173362Sbenjsc         elem_list->back_p->next_p = NULL;
285173362Sbenjsc      }
286173362Sbenjsc
287173362Sbenjsc      elem_list->size--;
288173362Sbenjsc      private_pool_free((list_p)->free_pool, alElement_p);
289173362Sbenjsc   }
290173362Sbenjsc
291173362Sbenjsc   return obj_p;
292173362Sbenjsc}
293173362Sbenjsc
294173362Sbenjsc/**
295173362Sbenjsc * This method simply removes the list element at the head of the list
296173362Sbenjsc * and returns the pointer to the object that was removed.
297173362Sbenjsc */
298173362Sbenjscvoid * sci_abstract_list_popfront(
299173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
300173362Sbenjsc)
301173362Sbenjsc{
302173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p =
303173362Sbenjsc                              private_pop_front(&(list_p)->elements);
304173362Sbenjsc   void * obj_p = NULL;
305173362Sbenjsc
306173362Sbenjsc   if (alElement_p != NULL)
307173362Sbenjsc   {
308173362Sbenjsc      obj_p = alElement_p->object_p;
309173362Sbenjsc      private_pool_free((list_p)->free_pool, alElement_p);
310173362Sbenjsc   }
311173362Sbenjsc
312173362Sbenjsc   return obj_p;
313173362Sbenjsc}
314173362Sbenjsc
315173362Sbenjsc
316173362Sbenjsc
317173362Sbenjsc/**
318173362Sbenjsc * This method will erase (remove) all instances of the supplied object from
319173362Sbenjsc * anywhere in the list.
320173362Sbenjsc */
321173362Sbenjscvoid sci_abstract_list_erase(
322173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p,
323173362Sbenjsc   void * obj_p
324173362Sbenjsc)
325173362Sbenjsc{
326173362Sbenjsc   SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;
327173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T      * alElement_p;
328173362Sbenjsc
329173362Sbenjsc   while ((alElement_p = private_find(elem_list, (obj_p))) != NULL)
330173362Sbenjsc   {
331173362Sbenjsc      if (alElement_p == elem_list->front_p)
332173362Sbenjsc      {
333173362Sbenjsc         sci_abstract_list_popfront(list_p);
334173362Sbenjsc      }
335173362Sbenjsc      else if (alElement_p == elem_list->back_p)
336173362Sbenjsc      {
337173362Sbenjsc         sci_abstract_list_popback(list_p);
338173362Sbenjsc      }
339173362Sbenjsc      else
340173362Sbenjsc      {
341173362Sbenjsc         alElement_p->previous_p->next_p = alElement_p->next_p;
342173362Sbenjsc         alElement_p->next_p->previous_p = alElement_p->previous_p;
343173362Sbenjsc         elem_list->size--;
344173362Sbenjsc         private_pool_free((list_p)->free_pool, alElement_p);
345173362Sbenjsc      }
346173362Sbenjsc   }
347173362Sbenjsc   return;
348173362Sbenjsc}
349173362Sbenjsc
350173362Sbenjsc/**
351173362Sbenjsc * This method simply adds a LIST_ELEMENT for the supplied object to the back
352173362Sbenjsc * (tail) of the supplied list.
353173362Sbenjsc */
354173362Sbenjscvoid sci_abstract_list_pushback(
355173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p,
356173362Sbenjsc   void * obj_p
357173362Sbenjsc)
358173362Sbenjsc{
359173362Sbenjsc   SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;
360173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T      * alElement_p
361173362Sbenjsc      = private_pool_allocate((list_p)->free_pool);
362173362Sbenjsc//   assert(alElement_p != NULL);
363173362Sbenjsc
364173362Sbenjsc   alElement_p->object_p = (obj_p);
365173362Sbenjsc
366173362Sbenjsc   if (elem_list->front_p == NULL)
367173362Sbenjsc   {
368173362Sbenjsc      elem_list->front_p = elem_list->back_p = alElement_p;
369173362Sbenjsc   }
370173362Sbenjsc   else
371173362Sbenjsc   {
372173362Sbenjsc      elem_list->back_p->next_p = alElement_p;
373173362Sbenjsc      alElement_p->previous_p   = elem_list->back_p;
374173362Sbenjsc      elem_list->back_p         = alElement_p;
375173362Sbenjsc   }
376173362Sbenjsc
377173362Sbenjsc   elem_list->size++;
378173362Sbenjsc}
379173362Sbenjsc
380173362Sbenjsc
381173362Sbenjsc
382173362Sbenjsc/**
383173362Sbenjsc * This method simply adds a LIST_ELEMENT for the supplied object to the front
384173362Sbenjsc * (head) of the supplied list.
385173362Sbenjsc */
386173362Sbenjscvoid sci_abstract_list_pushfront(
387173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p,
388173362Sbenjsc   void * obj_p
389173362Sbenjsc)
390173362Sbenjsc{
391173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p =
392173362Sbenjsc         private_pool_allocate((list_p)->free_pool);
393173362Sbenjsc   alElement_p->object_p = (obj_p);
394173362Sbenjsc   private_push_front(&(list_p)->elements, alElement_p);
395173362Sbenjsc}
396173362Sbenjsc
397173362Sbenjsc
398173362Sbenjsc/**
399173362Sbenjsc * This method will add the objToAdd_p object to the list before the obj_p.
400173362Sbenjsc *
401173362Sbenjsc */
402173362Sbenjscvoid sci_abstract_list_insert(
403173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p,
404173362Sbenjsc   void * obj_p,
405173362Sbenjsc   void * objToAdd_p
406173362Sbenjsc)
407173362Sbenjsc{
408173362Sbenjsc   SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;
409173362Sbenjsc
410173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * obj_element = private_find(elem_list, obj_p);
411173362Sbenjsc
412173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * objToAdd_element =
413173362Sbenjsc      private_pool_allocate((list_p)->free_pool);
414173362Sbenjsc
415173362Sbenjsc   objToAdd_element->object_p = objToAdd_p;
416173362Sbenjsc
417173362Sbenjsc   ASSERT(obj_element != NULL);
418173362Sbenjsc   ASSERT(objToAdd_element != NULL);
419173362Sbenjsc
420173362Sbenjsc   if (obj_element == elem_list->front_p)
421173362Sbenjsc   {
422173362Sbenjsc      objToAdd_element->object_p = (objToAdd_p);
423173362Sbenjsc      private_push_front(&(list_p)->elements, objToAdd_element);
424173976Sbenjsc   }
425173976Sbenjsc   else
426173976Sbenjsc   {
427173976Sbenjsc      obj_element->previous_p->next_p = objToAdd_element;
428173976Sbenjsc      objToAdd_element->previous_p = obj_element->previous_p;
429173976Sbenjsc
430173976Sbenjsc      obj_element->previous_p = objToAdd_element;
431173976Sbenjsc      objToAdd_element->next_p = obj_element;
432173976Sbenjsc
433173362Sbenjsc      elem_list->size++;
434173362Sbenjsc   }
435173362Sbenjsc}
436173362Sbenjsc
437173362Sbenjsc/**
438173362Sbenjsc * This method simply frees all the items from the list.
439173362Sbenjsc */
440173362Sbenjscvoid sci_abstract_list_clear(
441173362Sbenjsc   SCI_ABSTRACT_LIST_T * list_p
442173362Sbenjsc)
443173362Sbenjsc{
444173362Sbenjsc   while ((list_p)->elements.size > 0)
445173362Sbenjsc      sci_abstract_list_popfront((list_p));
446173362Sbenjsc}
447173362Sbenjsc
448173362Sbenjsc/**
449173362Sbenjsc * This method simply returns the object being pointed to by the list element
450173362Sbenjsc * (The item being listed).
451173362Sbenjsc */
452173362Sbenjscvoid * sci_abstract_list_get_object(
453173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p
454173362Sbenjsc)
455173362Sbenjsc{
456173362Sbenjsc   void * obj_p = NULL;
457173362Sbenjsc   if ((alElement_p) != NULL)
458173362Sbenjsc      obj_p = (alElement_p)->object_p;
459173362Sbenjsc
460173362Sbenjsc   return obj_p;
461173362Sbenjsc}
462173362Sbenjsc
463173362Sbenjsc
464173362Sbenjsc/**
465173362Sbenjsc * This method is simply a wrapper to provide the number of elements in
466173362Sbenjsc * the free list.
467173362Sbenjsc */
468173362SbenjscU32 sci_abstract_list_freeList_size(
469173362Sbenjsc   SCI_ABSTRACT_LIST_T * freeList
470173362Sbenjsc)
471173362Sbenjsc{
472173362Sbenjsc   return (sci_abstract_list_size(freeList));
473173362Sbenjsc}
474173362Sbenjsc
475173362Sbenjsc//******************************************************************************
476173362Sbenjsc//*
477173362Sbenjsc//*     P R I V A T E   M E T H O D S
478173362Sbenjsc//*
479173362Sbenjsc//******************************************************************************
480173362Sbenjsc
481173362Sbenjsc/**
482173362Sbenjsc * This method simply performs the common portion of pushing a list element
483173362Sbenjsc * onto a list.
484173362Sbenjsc *
485173362Sbenjsc * WARNING: This is a private helper method that should not be called directly
486173362Sbenjsc *          by any users.
487173362Sbenjsc */
488173362Sbenjscvoid private_push_front(
489173362Sbenjsc   SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p,
490173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p
491173362Sbenjsc)
492173362Sbenjsc{
493173362Sbenjsc   if ((privateList_p)->front_p == NULL)
494173362Sbenjsc   {
495173362Sbenjsc      (privateList_p)->front_p = (privateList_p)->back_p = (alElement_p);
496173362Sbenjsc      (alElement_p)->next_p = (alElement_p)->previous_p = NULL;
497173362Sbenjsc   }
498173362Sbenjsc   else
499173362Sbenjsc   {
500173362Sbenjsc      (alElement_p)->next_p                = (privateList_p)->front_p;
501173362Sbenjsc      (alElement_p)->previous_p            = NULL;
502173362Sbenjsc      (privateList_p)->front_p->previous_p = (alElement_p);
503173362Sbenjsc      (privateList_p)->front_p             = (alElement_p);
504173362Sbenjsc   }
505173362Sbenjsc
506173362Sbenjsc   (privateList_p)->size++;
507173362Sbenjsc}
508173362Sbenjsc
509173362Sbenjsc/**
510173362Sbenjsc * This method simply performs the common portion of popping a list element
511173362Sbenjsc * from a list.
512173362Sbenjsc *
513173362Sbenjsc * WARNING: This is a private helper method that should not be called directly
514173362Sbenjsc *          by any users.
515173362Sbenjsc */
516173362SbenjscSCI_ABSTRACT_ELEMENT_T * private_pop_front(
517173362Sbenjsc   SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p
518173362Sbenjsc)
519173362Sbenjsc{
520173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p = (privateList_p)->front_p;
521173362Sbenjsc
522173362Sbenjsc   if (alElement_p != NULL)
523173362Sbenjsc   {
524173362Sbenjsc      if ((privateList_p)->front_p == (privateList_p)->back_p)
525173362Sbenjsc      {
526173362Sbenjsc         (privateList_p)->front_p = (privateList_p)->back_p = NULL;
527173362Sbenjsc      }
528173362Sbenjsc      else
529173362Sbenjsc      {
530173362Sbenjsc         (privateList_p)->front_p = (privateList_p)->front_p->next_p;
531173362Sbenjsc         (privateList_p)->front_p->previous_p = NULL;
532173362Sbenjsc      }
533173362Sbenjsc
534173362Sbenjsc      (privateList_p)->size--;
535173362Sbenjsc   }
536173362Sbenjsc
537173362Sbenjsc   return alElement_p;
538173362Sbenjsc}
539173362Sbenjsc
540173362Sbenjsc/**
541173362Sbenjsc * This method will simply search the supplied list for the desired object.
542173362Sbenjsc * It will return a pointer to the abstract_list_element if found, otherwise
543173362Sbenjsc * it will return NULL.
544173362Sbenjsc */
545173362SbenjscSCI_ABSTRACT_ELEMENT_T * private_find(
546173362Sbenjsc   SCI_ABSTRACT_ELEMENT_LIST_T * list_p,
547173362Sbenjsc   void * obj_p
548173362Sbenjsc)
549173362Sbenjsc{
550173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p = (list_p)->front_p;
551173362Sbenjsc
552173362Sbenjsc   while (alElement_p != NULL)
553173362Sbenjsc   {
554173362Sbenjsc      /* Check to see if we found the object for which we are searching. */
555173362Sbenjsc      if (alElement_p->object_p == (void*) (obj_p))
556173362Sbenjsc      {
557173362Sbenjsc         break;
558173362Sbenjsc      }
559173362Sbenjsc
560173362Sbenjsc      alElement_p = alElement_p->next_p;
561173362Sbenjsc   }
562173362Sbenjsc
563173362Sbenjsc   return alElement_p;
564173362Sbenjsc}
565173362Sbenjsc
566173362Sbenjsc/**
567173362Sbenjsc * This private method will free the supplied list element back to the pool
568173362Sbenjsc * of free list elements.
569173362Sbenjsc */
570173362Sbenjscvoid private_pool_free(
571173362Sbenjsc   SCI_ABSTRACT_ELEMENT_POOL_T * free_pool,
572173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p
573173362Sbenjsc)
574173362Sbenjsc{
575173362Sbenjsc   /* Push the list element back to the head to get better locality of */
576173362Sbenjsc   /* reference with the cache.                                        */
577173362Sbenjsc   private_push_front(&(free_pool)->free_list, (alElement_p));
578173362Sbenjsc}
579173362Sbenjsc
580173362Sbenjsc/**
581173362Sbenjsc * This private method will allocate a list element from the pool of free
582173362Sbenjsc * list elements.
583173362Sbenjsc */
584173362SbenjscSCI_ABSTRACT_ELEMENT_T * private_pool_allocate(
585173362Sbenjsc   SCI_ABSTRACT_ELEMENT_POOL_T * free_pool
586173362Sbenjsc)
587173362Sbenjsc{
588173362Sbenjsc   SCI_ABSTRACT_ELEMENT_T * alElement_p;
589173362Sbenjsc
590173362Sbenjsc   alElement_p = private_pop_front(&(free_pool)->free_list);
591173362Sbenjsc
592173362Sbenjsc   alElement_p->next_p     = NULL;
593173362Sbenjsc   alElement_p->previous_p = NULL;
594173362Sbenjsc   alElement_p->object_p   = NULL;
595173362Sbenjsc
596173362Sbenjsc   return alElement_p;
597173362Sbenjsc}
598173362Sbenjsc
599173362Sbenjsc#endif // USE_ABSTRACT_LIST_FUNCTIONS
600173362Sbenjsc