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