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 * $FreeBSD: releng/10.3/sys/dev/isci/scil/sci_abstract_list.h 231136 2012-02-07 17:43:58Z jimharris $ 53230557Sjimharris */ 54230557Sjimharris/** 55230557Sjimharris * @file 56230557Sjimharris * 57230557Sjimharris * @brief This file contains the interface to the abstract list class. 58230557Sjimharris * This class will allow for the same item to occur multiple times in 59230557Sjimharris * a list or multiple lists. It will provide an interface that is 60230557Sjimharris * similar to the C++ standard template list interface. 61230557Sjimharris * Methods Provided: 62230557Sjimharris * - sci_abstract_list_front() 63230557Sjimharris * - sci_abstract_list_back() 64230557Sjimharris * - sci_abstract_list_is_empty() 65230557Sjimharris * - sci_abstract_list_size() 66230557Sjimharris * - sci_abstract_list_print() 67230557Sjimharris * - sci_abstract_list_find() 68230557Sjimharris * - sci_abstract_list_popback() 69230557Sjimharris * - sci_abstract_list_popfront() 70230557Sjimharris * - sci_abstract_list_erase() 71230557Sjimharris * - sci_abstract_list_pushback() 72230557Sjimharris * - sci_abstract_list_pushfront() 73230557Sjimharris * - sci_abstract_list_get_object() 74230557Sjimharris * - sci_abstract_list_get_next() 75230557Sjimharris * - sci_abstract_list_insert() UNIMPLEMENTED 76230557Sjimharris * - sci_abstract_list_clear() 77230557Sjimharris */ 78230557Sjimharris 79230557Sjimharris#ifndef _SCI_ABSTRACT_LIST_H_ 80230557Sjimharris#define _SCI_ABSTRACT_LIST_H_ 81230557Sjimharris 82230557Sjimharris//****************************************************************************** 83230557Sjimharris//* 84230557Sjimharris//* I N C L U D E S 85230557Sjimharris//* 86230557Sjimharris//****************************************************************************** 87230557Sjimharris 88230557Sjimharris#include <dev/isci/scil/sci_types.h> 89230557Sjimharris 90230557Sjimharris//****************************************************************************** 91230557Sjimharris//* 92230557Sjimharris//* C O N S T A N T S 93230557Sjimharris//* 94230557Sjimharris//****************************************************************************** 95230557Sjimharris 96230557Sjimharris//****************************************************************************** 97230557Sjimharris//* 98230557Sjimharris//* T Y P E S 99230557Sjimharris//* 100230557Sjimharris//****************************************************************************** 101230557Sjimharris 102230557Sjimharris/** 103230557Sjimharris * @struct SCI_ABSTRACT_ELEMENT 104230557Sjimharris * 105230557Sjimharris * @brief This object represents an element of a abstract list. 106230557Sjimharris * NOTE: This structure does not evenly align on a cache line 107230557Sjimharris * boundary. If SSP specific code ends up using this list, 108230557Sjimharris * then it may be a good idea to force the alignment. Now 109230557Sjimharris * it is more important to save the space. 110230557Sjimharris */ 111230557Sjimharristypedef struct SCI_ABSTRACT_ELEMENT 112230557Sjimharris{ 113230557Sjimharris /** 114230557Sjimharris * This field points to the next item in the abstract_list. 115230557Sjimharris */ 116230557Sjimharris struct SCI_ABSTRACT_ELEMENT * next_p; 117230557Sjimharris 118230557Sjimharris /** 119230557Sjimharris * This field points to the previous item in the abstract_list. 120230557Sjimharris */ 121230557Sjimharris struct SCI_ABSTRACT_ELEMENT * previous_p; 122230557Sjimharris 123230557Sjimharris /** 124230557Sjimharris * This field points to the object the list is managing (i.e. the thing 125230557Sjimharris * being listed). 126230557Sjimharris */ 127230557Sjimharris void * object_p; 128230557Sjimharris 129230557Sjimharris} SCI_ABSTRACT_ELEMENT_T; 130230557Sjimharris 131230557Sjimharris/** 132230557Sjimharris * @struct SCI_ABSTRACT_ELEMENT_LIST 133230557Sjimharris * 134230557Sjimharris * @brief This object represents an element list object. It can have 135230557Sjimharris * elements added and removed from it. 136230557Sjimharris */ 137230557Sjimharristypedef struct SCI_ABSTRACT_ELEMENT_LIST 138230557Sjimharris{ 139230557Sjimharris /** 140230557Sjimharris * Pointer to the front (head) of the list. 141230557Sjimharris */ 142230557Sjimharris SCI_ABSTRACT_ELEMENT_T * front_p; 143230557Sjimharris 144230557Sjimharris /** 145230557Sjimharris * Pointer to the back (tail) of the list. 146230557Sjimharris */ 147230557Sjimharris SCI_ABSTRACT_ELEMENT_T * back_p; 148230557Sjimharris 149230557Sjimharris /** 150230557Sjimharris * This field depicts the number of elements in this list. 151230557Sjimharris * NOTE: It is possible to remove this field and replace it with a 152230557Sjimharris * linear walking of the list to determine the size, but since 153230557Sjimharris * there aren't many lists in the system we don't utilize much 154230557Sjimharris * space. 155230557Sjimharris */ 156230557Sjimharris U32 size; 157230557Sjimharris 158230557Sjimharris} SCI_ABSTRACT_ELEMENT_LIST_T; 159230557Sjimharris 160230557Sjimharris/** 161230557Sjimharris * @struct SCI_ABSTRACT_ELEMENT_POOL 162230557Sjimharris * 163230557Sjimharris * @brief This structure provides the pool of free abstract elements to be 164230557Sjimharris * utilized by an SCI_ABSTRACT_LIST. 165230557Sjimharris */ 166230557Sjimharristypedef struct SCI_ABSTRACT_ELEMENT_POOL 167230557Sjimharris{ 168230557Sjimharris /** 169230557Sjimharris * Pointer to an array of elements to be managed by this pool. This 170230557Sjimharris * array acts as the memory store for the elements in the free pool or 171230557Sjimharris * allocated out of the pool into an SCI_ABSTRACT_LIST. 172230557Sjimharris */ 173230557Sjimharris SCI_ABSTRACT_ELEMENT_T * elements; 174230557Sjimharris 175230557Sjimharris /** 176230557Sjimharris * This field contains the maximum number of free elements for the pool. 177230557Sjimharris * It is set at creation of the pool and should not be changed afterward. 178230557Sjimharris */ 179230557Sjimharris U32 max_elements; 180230557Sjimharris 181230557Sjimharris /** 182230557Sjimharris * Pointer to the list of free elements that can be allocated from 183230557Sjimharris * the pool. 184230557Sjimharris */ 185230557Sjimharris struct SCI_ABSTRACT_ELEMENT_LIST free_list; 186230557Sjimharris 187230557Sjimharris} SCI_ABSTRACT_ELEMENT_POOL_T; 188230557Sjimharris 189230557Sjimharris/** 190230557Sjimharris * @struct SCI_ABSTRACT_LIST 191230557Sjimharris * 192230557Sjimharris * @brief This object provides the ability to queue any type of object or 193230557Sjimharris * even the same object multiple times. The object must be provided 194230557Sjimharris * an element pool from which to draw free elements. 195230557Sjimharris */ 196230557Sjimharristypedef struct SCI_ABSTRACT_LIST 197230557Sjimharris{ 198230557Sjimharris /** 199230557Sjimharris * This represents the elements currently managed by the list. 200230557Sjimharris */ 201230557Sjimharris SCI_ABSTRACT_ELEMENT_LIST_T elements; 202230557Sjimharris 203230557Sjimharris /** 204230557Sjimharris * This field contains elements that are currently available for 205230557Sjimharris * allocation into the list of elements; 206230557Sjimharris */ 207230557Sjimharris SCI_ABSTRACT_ELEMENT_POOL_T * free_pool; 208230557Sjimharris 209230557Sjimharris} SCI_ABSTRACT_LIST_T; 210230557Sjimharris 211230557Sjimharris//****************************************************************************** 212230557Sjimharris//* 213230557Sjimharris//* P R O T E C T E D M E T H O D S 214230557Sjimharris//* 215230557Sjimharris//****************************************************************************** 216230557Sjimharris 217230557Sjimharrisvoid sci_abstract_element_pool_construct( 218230557Sjimharris SCI_ABSTRACT_ELEMENT_POOL_T * pool, 219230557Sjimharris SCI_ABSTRACT_ELEMENT_T * list_elements, 220230557Sjimharris int element_count 221230557Sjimharris); 222230557Sjimharris 223230557Sjimharrisvoid sci_abstract_list_construct( 224230557Sjimharris SCI_ABSTRACT_LIST_T * list, 225230557Sjimharris SCI_ABSTRACT_ELEMENT_POOL_T * free_pool 226230557Sjimharris); 227230557Sjimharris 228230557Sjimharris 229230557Sjimharris 230230557Sjimharris#ifdef USE_ABSTRACT_LIST_FUNCTIONS 231230557Sjimharris//****************************************************************************** 232230557Sjimharris//* 233230557Sjimharris//* P U B L I C M E T H O D S 234230557Sjimharris//* 235230557Sjimharris//****************************************************************************** 236230557Sjimharris 237230557Sjimharris/** 238230557Sjimharris * Simply return the front element pointer of the list. This returns an element 239230557Sjimharris * element as opposed to what the element is pointing to. 240230557Sjimharris */ 241230557SjimharrisSCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_front( 242230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 243230557Sjimharris); 244230557Sjimharris 245230557Sjimharris 246230557Sjimharris/** 247230557Sjimharris * This method simply returns the object pointed to by the head (front) of 248230557Sjimharris * the list. 249230557Sjimharris */ 250230557Sjimharrisvoid * sci_abstract_list_front( 251230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 252230557Sjimharris); 253230557Sjimharris 254230557Sjimharris 255230557Sjimharris/** 256230557Sjimharris * This method simply returns the object pointed to by the tail (back) of 257230557Sjimharris * the list. 258230557Sjimharris */ 259230557Sjimharrisvoid * sci_abstract_list_back( 260230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 261230557Sjimharris); 262230557Sjimharris 263230557Sjimharris 264230557Sjimharris/** 265230557Sjimharris * This method will return FALSE if the list is not empty. 266230557Sjimharris */ 267230557SjimharrisBOOL sci_abstract_list_is_empty( 268230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 269230557Sjimharris); 270230557Sjimharris 271230557Sjimharris 272230557Sjimharris/** 273230557Sjimharris * This method will return the number of elements queued in the list. 274230557Sjimharris */ 275230557SjimharrisU32 sci_abstract_list_size( 276230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 277230557Sjimharris); 278230557Sjimharris 279230557Sjimharris 280230557Sjimharris/** 281230557Sjimharris * This method simply returns the next list element in the list. 282230557Sjimharris */ 283230557SjimharrisSCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_next( 284230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p 285230557Sjimharris); 286230557Sjimharris 287230557Sjimharris 288230557Sjimharris/** 289230557Sjimharris * This method simply prints the contents of the list. 290230557Sjimharris */ 291230557Sjimharrisvoid sci_abstract_list_print( 292230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 293230557Sjimharris); 294230557Sjimharris 295230557Sjimharris 296230557Sjimharris/** 297230557Sjimharris * This method will simply search the supplied list for the desired object. 298230557Sjimharris * It will return a pointer to the object, if it is found. Otherwise 299230557Sjimharris * it will return NULL. 300230557Sjimharris */ 301230557Sjimharrisvoid * sci_abstract_list_find( 302230557Sjimharris SCI_ABSTRACT_LIST_T * list_p, 303230557Sjimharris void * obj_p 304230557Sjimharris); 305230557Sjimharris 306230557Sjimharris 307230557Sjimharris/** 308230557Sjimharris * This method will simply remove the element at the back (tail) of the list. 309230557Sjimharris * It will return a pointer to the object that was removed or NULL if not 310230557Sjimharris * found. 311230557Sjimharris */ 312230557Sjimharrisvoid * sci_abstract_list_popback( 313230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 314230557Sjimharris); 315230557Sjimharris 316230557Sjimharris 317230557Sjimharris/** 318230557Sjimharris * This method simply removes the list element at the head of the list 319230557Sjimharris * and returns the pointer to the object that was removed. 320230557Sjimharris */ 321230557Sjimharrisvoid * sci_abstract_list_popfront( 322230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 323230557Sjimharris); 324230557Sjimharris 325230557Sjimharris 326230557Sjimharris 327230557Sjimharris/** 328230557Sjimharris * This method will erase (remove) all instances of the supplied object from 329230557Sjimharris * anywhere in the list. 330230557Sjimharris */ 331230557Sjimharrisvoid sci_abstract_list_erase( 332230557Sjimharris SCI_ABSTRACT_LIST_T * list_p, 333230557Sjimharris void * obj_p 334230557Sjimharris); 335230557Sjimharris 336230557Sjimharris 337230557Sjimharris/** 338230557Sjimharris * This method simply adds a LIST_ELEMENT for the supplied object to the back 339230557Sjimharris * (tail) of the supplied list. 340230557Sjimharris */ 341230557Sjimharrisvoid sci_abstract_list_pushback( 342230557Sjimharris SCI_ABSTRACT_LIST_T * list_p, 343230557Sjimharris void * obj_p 344230557Sjimharris); 345230557Sjimharris 346230557Sjimharris 347230557Sjimharris 348230557Sjimharris/** 349230557Sjimharris * This method simply adds a LIST_ELEMENT for the supplied object to the front 350230557Sjimharris * (head) of the supplied list. 351230557Sjimharris */ 352230557Sjimharrisvoid sci_abstract_list_pushfront( 353230557Sjimharris SCI_ABSTRACT_LIST_T * list_p, 354230557Sjimharris void * obj_p 355230557Sjimharris); 356230557Sjimharris 357230557Sjimharris 358230557Sjimharris/** 359230557Sjimharris * This method will add the objToAdd_p object to the list before the obj_p. 360230557Sjimharris * NOTE: UNIMPLEMENTED 361230557Sjimharris */ 362230557Sjimharrisvoid sci_abstract_list_insert( 363230557Sjimharris SCI_ABSTRACT_LIST_T * list_p, 364230557Sjimharris void * obj_p, 365230557Sjimharris void * objToAdd_p 366230557Sjimharris); 367230557Sjimharris 368230557Sjimharris 369230557Sjimharris/** 370230557Sjimharris * This method simply frees all the items from the list. 371230557Sjimharris */ 372230557Sjimharrisvoid sci_abstract_list_clear( 373230557Sjimharris SCI_ABSTRACT_LIST_T * list_p 374230557Sjimharris); 375230557Sjimharris 376230557Sjimharris 377230557Sjimharris/** 378230557Sjimharris * This method simply returns the object being pointed to by the list element 379230557Sjimharris * (The item being listed). 380230557Sjimharris */ 381230557Sjimharrisvoid * sci_abstract_list_get_object( 382230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p 383230557Sjimharris); 384230557Sjimharris 385230557Sjimharris 386230557Sjimharris/** 387230557Sjimharris * This method is simply a wrapper to provide the number of elements in 388230557Sjimharris * the free list. 389230557Sjimharris */ 390230557SjimharrisU32 sci_abstract_list_freeList_size( 391230557Sjimharris SCI_ABSTRACT_LIST_T * freeList 392230557Sjimharris); 393230557Sjimharris 394230557Sjimharris 395230557Sjimharris//****************************************************************************** 396230557Sjimharris//* 397230557Sjimharris//* P R I V A T E M E T H O D S 398230557Sjimharris//* 399230557Sjimharris//****************************************************************************** 400230557Sjimharris 401230557Sjimharris/** 402230557Sjimharris * This method simply performs the common portion of pushing a list element 403230557Sjimharris * onto a list. 404230557Sjimharris * 405230557Sjimharris * WARNING: This is a private helper method that should not be called directly 406230557Sjimharris * by any users. 407230557Sjimharris */ 408230557Sjimharrisvoid private_push_front( 409230557Sjimharris SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p, 410230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p 411230557Sjimharris); 412230557Sjimharris 413230557Sjimharris 414230557Sjimharris/** 415230557Sjimharris * This method simply performs the common portion of popping a list element 416230557Sjimharris * from a list. 417230557Sjimharris * 418230557Sjimharris * WARNING: This is a private helper method that should not be called directly 419230557Sjimharris * by any users. 420230557Sjimharris */ 421230557SjimharrisSCI_ABSTRACT_ELEMENT_T * private_pop_front( 422230557Sjimharris SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p 423230557Sjimharris); 424230557Sjimharris 425230557Sjimharris 426230557Sjimharris/** 427230557Sjimharris * This method will simply search the supplied list for the desired object. 428230557Sjimharris * It will return a pointer to the abstract_list_element if found, otherwise 429230557Sjimharris * it will return NULL. 430230557Sjimharris */ 431230557SjimharrisSCI_ABSTRACT_ELEMENT_T * private_find( 432230557Sjimharris SCI_ABSTRACT_ELEMENT_LIST_T * list_p, 433230557Sjimharris void * obj_p 434230557Sjimharris); 435230557Sjimharris 436230557Sjimharris 437230557Sjimharris/** 438230557Sjimharris * This private method will free the supplied list element back to the pool 439230557Sjimharris * of free list elements. 440230557Sjimharris */ 441230557Sjimharrisvoid private_pool_free( 442230557Sjimharris SCI_ABSTRACT_ELEMENT_POOL_T * free_pool, 443230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p 444230557Sjimharris); 445230557Sjimharris 446230557Sjimharris 447230557Sjimharris/** 448230557Sjimharris * This private method will allocate a list element from the pool of free 449230557Sjimharris * list elements. 450230557Sjimharris */ 451230557SjimharrisSCI_ABSTRACT_ELEMENT_T * private_pool_allocate( 452230557Sjimharris SCI_ABSTRACT_ELEMENT_POOL_T * free_pool 453230557Sjimharris); 454230557Sjimharris 455230557Sjimharris 456230557Sjimharris#else 457230557Sjimharris 458230557Sjimharris//****************************************************************************** 459230557Sjimharris//* 460230557Sjimharris//* P U B L I C M E T H O D S 461230557Sjimharris//* 462230557Sjimharris//****************************************************************************** 463230557Sjimharris 464230557Sjimharris/** 465230557Sjimharris * Simply return the front element pointer of the list. This returns an element 466230557Sjimharris * element as opposed to what the element is pointing to. 467230557Sjimharris */ 468230557Sjimharris#define sci_abstract_list_get_front( \ 469230557Sjimharris list_p \ 470230557Sjimharris) \ 471230557Sjimharris((list_p)->elements.front_p) 472230557Sjimharris 473230557Sjimharris/** 474230557Sjimharris * This method simply returns the object pointed to by the head (front) of 475230557Sjimharris * the list. 476230557Sjimharris */ 477230557Sjimharris#define sci_abstract_list_front( \ 478230557Sjimharris list_p \ 479230557Sjimharris) \ 480230557Sjimharris( ( (list_p)->elements.front_p ) ? ((list_p)->elements.front_p->object_p) : NULL ) 481230557Sjimharris 482230557Sjimharris/** 483230557Sjimharris * This method simply returns the object pointed to by the tail (back) of 484230557Sjimharris * the list. 485230557Sjimharris */ 486230557Sjimharris#define sci_abstract_list_back( \ 487230557Sjimharris list_p \ 488230557Sjimharris) \ 489230557Sjimharris( ( (list_p)->elements.back_p ) ? ((list_p)->elements.back_p->object_p) : NULL ) 490230557Sjimharris 491230557Sjimharris/** 492230557Sjimharris * This method will return FALSE if the list is not empty. 493230557Sjimharris */ 494230557Sjimharris#define sci_abstract_list_is_empty( \ 495230557Sjimharris list_p \ 496230557Sjimharris) \ 497230557Sjimharris( (list_p)->elements.front_p == NULL ) 498230557Sjimharris 499230557Sjimharris/** 500230557Sjimharris * This method will return the number of elements queued in the list. 501230557Sjimharris */ 502230557Sjimharris#define sci_abstract_list_size( \ 503230557Sjimharris list_p \ 504230557Sjimharris) \ 505230557Sjimharris( (list_p)->elements.size ) 506230557Sjimharris 507230557Sjimharris/** 508230557Sjimharris * This method simply returns the next list element in the list. 509230557Sjimharris */ 510230557Sjimharris#define sci_abstract_list_get_next( \ 511230557Sjimharris alElement_p \ 512230557Sjimharris) \ 513230557Sjimharris( (alElement_p)->next_p ) 514230557Sjimharris 515230557Sjimharris/** 516230557Sjimharris * This method simply prints the contents of the list. 517230557Sjimharris */ 518230557Sjimharris#define sci_abstract_list_print( \ 519230557Sjimharris list_p \ 520230557Sjimharris) \ 521230557Sjimharris{ \ 522230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p = list_p->elements.front_p; \ 523230557Sjimharris \ 524230557Sjimharris while (alElement_p != NULL) \ 525230557Sjimharris { \ 526230557Sjimharris /* Check to see if we found the object for which we are searching. */ \ 527230557Sjimharris printf("ITEM next_p 0x%x prev_p 0x%x obj_p 0x%x, 0x%x\n", \ 528230557Sjimharris alElement_p->next_p, \ 529230557Sjimharris alElement_p->previous_p, \ 530230557Sjimharris (U32*) (alElement_p->object_p)); \ 531230557Sjimharris \ 532230557Sjimharris alElement_p = alElement_p->next_p; \ 533230557Sjimharris } \ 534230557Sjimharris} 535230557Sjimharris 536230557Sjimharris/** 537230557Sjimharris * This method will simply search the supplied list for the desired object. 538230557Sjimharris * It will return a pointer to the object, if it is found. Otherwise 539230557Sjimharris * it will return NULL. 540230557Sjimharris */ 541230557Sjimharris#define sci_abstract_list_find( \ 542230557Sjimharris list_p, \ 543230557Sjimharris obj_p \ 544230557Sjimharris) \ 545230557Sjimharris({ \ 546230557Sjimharris sci_abstract_list_get_object(private_find(&(list_p)->elements, (obj_p))); \ 547230557Sjimharris}) 548230557Sjimharris 549230557Sjimharris/** 550230557Sjimharris * This method will simply remove the element at the back (tail) of the list. 551230557Sjimharris * It will return a pointer to the object that was removed or NULL if not 552230557Sjimharris * found. 553230557Sjimharris */ 554230557Sjimharris#define sci_abstract_list_popback( \ 555230557Sjimharris list_p \ 556230557Sjimharris) \ 557230557Sjimharris({ \ 558230557Sjimharris SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements; \ 559230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p = elem_list->back_p; \ 560230557Sjimharris void * obj_p = NULL; \ 561230557Sjimharris \ 562230557Sjimharris if (alElement_p != NULL) \ 563230557Sjimharris { \ 564230557Sjimharris obj_p = alElement_p->object_p; \ 565230557Sjimharris if (elem_list->back_p == elem_list->front_p) \ 566230557Sjimharris { \ 567230557Sjimharris elem_list->back_p = elem_list->front_p = NULL; \ 568230557Sjimharris } \ 569230557Sjimharris else \ 570230557Sjimharris { \ 571230557Sjimharris elem_list->back_p = elem_list->back_p->previous_p; \ 572230557Sjimharris elem_list->back_p->next_p = NULL; \ 573230557Sjimharris } \ 574230557Sjimharris \ 575230557Sjimharris elem_list->size--; \ 576230557Sjimharris private_pool_free((list_p)->free_pool, alElement_p); \ 577230557Sjimharris } \ 578230557Sjimharris \ 579230557Sjimharris obj_p; \ 580230557Sjimharris}) 581230557Sjimharris 582230557Sjimharris/** 583230557Sjimharris * This method simply removes the list element at the head of the list 584230557Sjimharris * and returns the pointer to the object that was removed. 585230557Sjimharris */ 586230557Sjimharris#define sci_abstract_list_popfront( \ 587230557Sjimharris list_p \ 588230557Sjimharris) \ 589230557Sjimharris({ \ 590230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p = \ 591230557Sjimharris private_pop_front(&(list_p)->elements); \ 592230557Sjimharris void * obj_p = NULL; \ 593230557Sjimharris \ 594230557Sjimharris if (alElement_p != NULL) \ 595230557Sjimharris { \ 596230557Sjimharris obj_p = alElement_p->object_p; \ 597230557Sjimharris private_pool_free((list_p)->free_pool, alElement_p); \ 598230557Sjimharris } \ 599230557Sjimharris \ 600230557Sjimharris obj_p; \ 601230557Sjimharris}) 602230557Sjimharris 603230557Sjimharris/** 604230557Sjimharris * This method will erase (remove) all instances of the supplied object from 605230557Sjimharris * anywhere in the list. 606230557Sjimharris */ 607230557Sjimharris#define sci_abstract_list_erase( \ 608230557Sjimharris list_p, \ 609230557Sjimharris obj_p \ 610230557Sjimharris) \ 611230557Sjimharris{ \ 612230557Sjimharris SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements; \ 613230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p; \ 614230557Sjimharris \ 615230557Sjimharris while ((alElement_p = private_find(elem_list, (obj_p))) != NULL) \ 616230557Sjimharris { \ 617230557Sjimharris if (alElement_p == elem_list->front_p) \ 618230557Sjimharris { \ 619230557Sjimharris sci_abstract_list_popfront(list_p); \ 620230557Sjimharris } \ 621230557Sjimharris else if (alElement_p == elem_list->back_p) \ 622230557Sjimharris { \ 623230557Sjimharris sci_abstract_list_popback(list_p); \ 624230557Sjimharris } \ 625230557Sjimharris else \ 626230557Sjimharris { \ 627230557Sjimharris alElement_p->previous_p->next_p = alElement_p->next_p; \ 628230557Sjimharris alElement_p->next_p->previous_p = alElement_p->previous_p; \ 629230557Sjimharris elem_list->size--; \ 630230557Sjimharris private_pool_free((list_p)->free_pool, alElement_p); \ 631230557Sjimharris } \ 632230557Sjimharris } \ 633230557Sjimharris} 634230557Sjimharris 635230557Sjimharris/** 636230557Sjimharris * This method simply adds a LIST_ELEMENT for the supplied object to the back 637230557Sjimharris * (tail) of the supplied list. 638230557Sjimharris */ 639230557Sjimharris#define sci_abstract_list_pushback( \ 640230557Sjimharris list_p, \ 641230557Sjimharris obj_p \ 642230557Sjimharris) \ 643230557Sjimharris{ \ 644230557Sjimharris SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements; \ 645230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p \ 646230557Sjimharris = private_pool_allocate((list_p)->free_pool); \ 647230557Sjimharris assert(alElement_p != NULL); \ 648230557Sjimharris \ 649230557Sjimharris alElement_p->object_p = (obj_p); \ 650230557Sjimharris \ 651230557Sjimharris if (elem_list->front_p == NULL) \ 652230557Sjimharris { \ 653230557Sjimharris elem_list->front_p = elem_list->back_p = alElement_p; \ 654230557Sjimharris } \ 655230557Sjimharris else \ 656230557Sjimharris { \ 657230557Sjimharris elem_list->back_p->next_p = alElement_p; \ 658230557Sjimharris alElement_p->previous_p = elem_list->back_p; \ 659230557Sjimharris elem_list->back_p = alElement_p; \ 660230557Sjimharris } \ 661230557Sjimharris \ 662230557Sjimharris elem_list->size++; \ 663230557Sjimharris} 664230557Sjimharris 665230557Sjimharris/** 666230557Sjimharris * This method simply adds a LIST_ELEMENT for the supplied object to the front 667230557Sjimharris * (head) of the supplied list. 668230557Sjimharris */ 669230557Sjimharris#define sci_abstract_list_pushfront( \ 670230557Sjimharris list_p, \ 671230557Sjimharris obj_p \ 672230557Sjimharris) \ 673230557Sjimharris{ \ 674230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p = \ 675230557Sjimharris private_pool_allocate((list_p)->free_pool); \ 676230557Sjimharris alElement_p->object_p = (obj_p); \ 677230557Sjimharris private_push_front(&(list_p)->elements, alElement_p); \ 678230557Sjimharris} 679230557Sjimharris 680230557Sjimharris/** 681230557Sjimharris * This method will add the objToAdd_p object to the list before the obj_p. 682230557Sjimharris * NOTE: UNIMPLEMENTED 683230557Sjimharris */ 684230557Sjimharris#define sci_abstract_list_insert( \ 685230557Sjimharris list_p, \ 686230557Sjimharris obj_p, \ 687230557Sjimharris objToAdd_p \ 688230557Sjimharris) \ 689230557Sjimharris{ \ 690230557Sjimharris SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements; \ 691230557Sjimharris \ 692230557Sjimharris SCI_ABSTRACT_ELEMENT_T * obj_element = private_find(elem_list, obj_p); \ 693230557Sjimharris \ 694230557Sjimharris SCI_ABSTRACT_ELEMENT_T * objToAdd_element = \ 695230557Sjimharris private_pool_allocate((list_p)->free_pool); \ 696230557Sjimharris \ 697230557Sjimharris objToAdd_element->object_p = objToAdd_p; \ 698230557Sjimharris \ 699230557Sjimharris ASSERT(obj_element != NULL); \ 700230557Sjimharris ASSERT(objToAdd_element != NULL); \ 701230557Sjimharris \ 702230557Sjimharris if (obj_element == elem_list->front_p) \ 703230557Sjimharris { \ 704230557Sjimharris objToAdd_element->object_p = (objToAdd_p); \ 705230557Sjimharris private_push_front(&(list_p)->elements, objToAdd_element); \ 706230557Sjimharris } \ 707230557Sjimharris else \ 708230557Sjimharris { \ 709230557Sjimharris obj_element->previous_p->next_p = objToAdd_element; \ 710230557Sjimharris objToAdd_element->previous_p = obj_element->previous_p; \ 711230557Sjimharris \ 712230557Sjimharris obj_element->previous_p = objToAdd_element; \ 713230557Sjimharris objToAdd_element->next_p = obj_element; \ 714230557Sjimharris \ 715230557Sjimharris elem_list->size++; \ 716230557Sjimharris } \ 717230557Sjimharris} 718230557Sjimharris 719230557Sjimharris/** 720230557Sjimharris * This method simply frees all the items from the list. 721230557Sjimharris */ 722230557Sjimharris#define sci_abstract_list_clear( \ 723230557Sjimharris list_p \ 724230557Sjimharris) \ 725230557Sjimharris{ \ 726230557Sjimharris while ((list_p)->elements.size > 0) \ 727230557Sjimharris sci_abstract_list_popfront((list_p)); \ 728230557Sjimharris} 729230557Sjimharris 730230557Sjimharris/** 731230557Sjimharris * This method simply returns the object being pointed to by the list element 732230557Sjimharris * (The item being listed). 733230557Sjimharris */ 734230557Sjimharris#define sci_abstract_list_get_object( \ 735230557Sjimharris alElement_p \ 736230557Sjimharris) \ 737230557Sjimharris({ \ 738230557Sjimharris void * obj_p = NULL; \ 739230557Sjimharris if ((alElement_p) != NULL) \ 740230557Sjimharris obj_p = (alElement_p)->object_p; \ 741230557Sjimharris \ 742230557Sjimharris obj_p; \ 743230557Sjimharris}) 744230557Sjimharris 745230557Sjimharris/** 746230557Sjimharris * This method is simply a wrapper to provide the number of elements in 747230557Sjimharris * the free list. 748230557Sjimharris */ 749230557Sjimharris#define sci_abstract_list_freeList_size(freeList) (sci_abstract_list_size(freeList)) 750230557Sjimharris 751230557Sjimharris//****************************************************************************** 752230557Sjimharris//* 753230557Sjimharris//* P R I V A T E M E T H O D S 754230557Sjimharris//* 755230557Sjimharris//****************************************************************************** 756230557Sjimharris 757230557Sjimharris/** 758230557Sjimharris * This method simply performs the common portion of pushing a list element 759230557Sjimharris * onto a list. 760230557Sjimharris * 761230557Sjimharris * WARNING: This is a private helper method that should not be called directly 762230557Sjimharris * by any users. 763230557Sjimharris */ 764230557Sjimharris#define private_push_front( \ 765230557Sjimharris privateList_p, \ 766230557Sjimharris alElement_p \ 767230557Sjimharris) \ 768230557Sjimharris{ \ 769230557Sjimharris if ((privateList_p)->front_p == NULL) \ 770230557Sjimharris { \ 771230557Sjimharris (privateList_p)->front_p = (privateList_p)->back_p = (alElement_p); \ 772230557Sjimharris (alElement_p)->next_p = (alElement_p)->previous_p = NULL; \ 773230557Sjimharris } \ 774230557Sjimharris else \ 775230557Sjimharris { \ 776230557Sjimharris (alElement_p)->next_p = (privateList_p)->front_p; \ 777230557Sjimharris (alElement_p)->previous_p = NULL; \ 778230557Sjimharris (privateList_p)->front_p->previous_p = (alElement_p); \ 779230557Sjimharris (privateList_p)->front_p = (alElement_p); \ 780230557Sjimharris } \ 781230557Sjimharris \ 782230557Sjimharris (privateList_p)->size++; \ 783230557Sjimharris} 784230557Sjimharris 785230557Sjimharris/** 786230557Sjimharris * This method simply performs the common portion of popping a list element 787230557Sjimharris * from a list. 788230557Sjimharris * 789230557Sjimharris * WARNING: This is a private helper method that should not be called directly 790230557Sjimharris * by any users. 791230557Sjimharris */ 792230557Sjimharris#define private_pop_front( \ 793230557Sjimharris privateList_p \ 794230557Sjimharris) \ 795230557Sjimharris({ \ 796230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p = (privateList_p)->front_p; \ 797230557Sjimharris \ 798230557Sjimharris if (alElement_p != NULL) \ 799230557Sjimharris { \ 800230557Sjimharris if ((privateList_p)->front_p == (privateList_p)->back_p) \ 801230557Sjimharris { \ 802230557Sjimharris (privateList_p)->front_p = (privateList_p)->back_p = NULL; \ 803230557Sjimharris } \ 804230557Sjimharris else \ 805230557Sjimharris { \ 806230557Sjimharris (privateList_p)->front_p = (privateList_p)->front_p->next_p; \ 807230557Sjimharris (privateList_p)->front_p->previous_p = NULL; \ 808230557Sjimharris } \ 809230557Sjimharris \ 810230557Sjimharris (privateList_p)->size--; \ 811230557Sjimharris } \ 812230557Sjimharris \ 813230557Sjimharris alElement_p; \ 814230557Sjimharris}) 815230557Sjimharris 816230557Sjimharris/** 817230557Sjimharris * This method will simply search the supplied list for the desired object. 818230557Sjimharris * It will return a pointer to the abstract_list_element if found, otherwise 819230557Sjimharris * it will return NULL. 820230557Sjimharris */ 821230557Sjimharris#define private_find( \ 822230557Sjimharris list_p, \ 823230557Sjimharris obj_p \ 824230557Sjimharris) \ 825230557Sjimharris({ \ 826230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p = (list_p)->front_p; \ 827230557Sjimharris \ 828230557Sjimharris while (alElement_p != NULL) \ 829230557Sjimharris { \ 830230557Sjimharris /* Check to see if we found the object for which we are searching. */ \ 831230557Sjimharris if (alElement_p->object_p == (void*) (obj_p)) \ 832230557Sjimharris { \ 833230557Sjimharris break; \ 834230557Sjimharris } \ 835230557Sjimharris \ 836230557Sjimharris alElement_p = alElement_p->next_p; \ 837230557Sjimharris } \ 838230557Sjimharris \ 839230557Sjimharris alElement_p; \ 840230557Sjimharris}) 841230557Sjimharris 842230557Sjimharris/** 843230557Sjimharris * This private method will free the supplied list element back to the pool 844230557Sjimharris * of free list elements. 845230557Sjimharris */ 846230557Sjimharris#define private_pool_free( \ 847230557Sjimharris free_pool, \ 848230557Sjimharris alElement_p \ 849230557Sjimharris) \ 850230557Sjimharris{ \ 851230557Sjimharris /* Push the list element back to the head to get better locality of */ \ 852230557Sjimharris /* reference with the cache. */ \ 853230557Sjimharris private_push_front(&(free_pool)->free_list, (alElement_p)); \ 854230557Sjimharris} 855230557Sjimharris 856230557Sjimharris/** 857230557Sjimharris * This private method will allocate a list element from the pool of free 858230557Sjimharris * list elements. 859230557Sjimharris */ 860230557Sjimharris#define private_pool_allocate(free_pool) \ 861230557Sjimharris({ \ 862230557Sjimharris SCI_ABSTRACT_ELEMENT_T * alElement_p; \ 863230557Sjimharris \ 864230557Sjimharris alElement_p = private_pop_front(&(free_pool)->free_list); \ 865230557Sjimharris \ 866230557Sjimharris memset(alElement_p, 0, sizeof(SCI_ABSTRACT_ELEMENT_T)); \ 867230557Sjimharris alElement_p; \ 868230557Sjimharris}) 869230557Sjimharris 870230557Sjimharris#endif 871230557Sjimharris#endif // _ABSTRACT_LIST_H_ 872