Template Version: @(#)sac_nextcase 1.68 02/23/09 SMI
This information is Copyright 2009 Sun Microsystems
1. Introduction
    1.1. Project/Component Working Name:
         Public linked lists
    1.2. Name of Document Author/Supplier:
         Author:  Garrett D'Amore
    1.3  Date of This Document:
        08 September, 2009
4. Technical Description

Problem
-------

Unlike virtually every other FOSS, we Solaris has not common faciility that
is *public* for driver developers for managing linked lists.

Yet managing linked lists is one of the most common tasks that device driver
developers are faced with.

Solaris has a facility, but it was never reviewed by ARC and remains some
form of private.

Solution
--------

We propose that the definitions and declarations that make up sys/list.h
are added to the public Committed DDI.  Note that these linked lists are
actually doubly linked to allow O(1) insertions and removals anywhere on 
the list, as well as to allow efficient traversal in either direction.

We are requesting Patch binding, although at present four of the functions
interfaces described here are not present on Solaris 10 and would need to
be backported.  (The Patch binding makes this possible if some enterprising
individual should choose to this, although the project team has no specific
intention to do this at this time.)  The functions not present on S10 are
identified in the Exported Interfaces table below.

Details
-------

<sys/list.h> contains the following types:

typedef struct list_node list_node_t;

    This is an opaque structure node on a linked list.  It can be placed 
    as a member of a structure that will be linked together.  (Its valid to
    take the size of this structure, but individual members remain private.)

typedef struct list list_t;

    This is an opaque structure representing a linked list itself.  It 
    is valid to take the size of this structure, but individual members remain
    private.


The following functions are used to access linked lists.  Note that the linked
lists themselves are not protected by any locks; it is the responsibility of
the developer to provide locking to protect the linkage of lists created
with these functions.

void list_create(list_t *, size_t size, size_t offset);

    This function initializes a new list.  The driver supplies the storage
    for the list handle, and the size of an individual element, and the
    offset of a list_node_t within the element to use for the links of
    the list.

void list_destroy(list_t *);

    This function destroys the list handle, including freeing up any
    resources which may have been internally allocated for the list.
    The list *must* be empty when this function is called.

void list_insert_after(list_t *, void *reference_item, void *new_item);
void list_insert_before(list_t *, void *reference_item, void *new_item);

    These functions insert new_item into the linked list at a location
    after or before the reference item, which must already be on the list.

void list_insert_head(list_t *, void *new_item);
void list_insert_tail(list_t *, void *new_item);

    These functions insert the new_item on the list at either the head or
    tail of the list.  (The head is the first item, the tail is the last item).

void list_remove(list_t *, void *item);

    This function removes the item from the list.

void *list_remove_head(list_t *);
void *list_remove_tail(list_t *);

    These functions remove the head (first) or tail (last) item from the
    list.  The item removed is returned to the caller.  If the list is empty
    when these functions are called, then no change is made and NULL is
    returned to the caller.

void *list_head(list_t *);
void *list_tail(list_t *);

    These functions simply return the head (first) or tail (last) item on
    the list.  NULL is returned if the list is empty.

void *list_next(list_t * void *reference_item);
void *list_prev(list_t * void *reference_item);

    These functions returne the next or previous item in the list, relative
    to the named reference item which must be linked on the list.

int list_is_empty(list_t *);

    This functions returns zero if the list has items in it, or non-zero
    otherwise.

void list_link_init(list_node_t *node);
 
    This function initializes the list_node_t.  It is functionally equivalent
    to bzero(node, sizeof (*node));

int list_link_active(list_node_t *);
 
    This functions returns non-zero if the node is on an active list.

void list_move_tail(list_t *dst, list_t *src);

    This function is used to append the items on the src list to the end of
    the dst list.  It is mandatory that the two lists were initialized using
    identical size and offset parameters.  Upon completion, the src list will
    be empty.

void list_link_replace(list_node_t *, list_node_t *);

    This function swaps two items on a list.  Note that the items need not
    be on the same list, but extreme care must be used to ensure that both
    lists are locked, and that the lists were initialized with identical
    size and offset parameters.


Interface Tables
----------------

Exported Interfaces
+-----------------------+---------------+-------------------------------+
| Interface             | Stability     | Comments                      |
+-----------------------+---------------+-------------------------------+
| <sys/list.h>          | Committed     | Header file                   |
| list_node_t           | Committed     | Opaque datatype               |
| list_t                | Committed     |                               |
| sizeof (list_node_t)  | Committed     | Sizes are committed           |
| sizeof (list_t)       | Committed     |                               |
| list_create()         | Committed     | List handling functions       |
| list_destroy()        | Committed     |                               |
| list_insert_after()   | Committed     |                               |
| list_insert_before()  | Committed     |                               |
| list_insert_head()    | Committed     |                               |
| list_insert_tail()    | Committed     |                               |
| list_remove()         | Committed     |                               |
| list_remove_head()    | Committed     | Not currently in S10          |
| list_remove_tail()    | Committed     | Not currently in S10          |
| list_move_tail()      | Committed     |                               |
| list_head()           | Committed     |                               |
| list_tail()           | Committed     |                               |
| list_next()           | Committed     |                               |
| list_prev()           | Committed     |                               |
| list_is_empty()       | Committed     |                               |
| list_link_init()      | Committed     | Not currently in S10          |
| list_link_replace()   | Committed     | Not currently in S10          |
| list_link_active()    | Committed     |                               |
+-----------------------+---------------+-------------------------------+

Imported Interfaces

None.

6. Resources and Schedule
    6.4. Steering Committee requested information
        6.4.1. Consolidation C-team Name:
                ON
    6.5. ARC review type: FastTrack
    6.6. ARC Exposure: open

Reply via email to