]> git.proxmox.com Git - mirror_spl-debian.git/commitdiff
User space build fixes:
authorbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>
Tue, 26 Feb 2008 23:20:41 +0000 (23:20 +0000)
committerbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>
Tue, 26 Feb 2008 23:20:41 +0000 (23:20 +0000)
- Add list handling compatibility library
- Drop uu_* list handling in favor of local list implementation
- libtoolize
- generic makefile cleanup

git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@3 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c

12 files changed:
autogen.sh
configure.ac
include/Makefile.am
include/list.h [new file with mode: 0644]
include/splat.h
src/Makefile.am
src/cmd/Makefile.am
src/cmd/splat.c
src/lib/Makefile.am [new file with mode: 0644]
src/lib/list.c [new file with mode: 0644]
src/spl/Makefile.in
src/spl/linux-kmem.c

index 340b2c673d64d2b5aad7943b2a82651f8a489078..2e5965e73060371f26fd28f3cff8dc69702ea339 100755 (executable)
@@ -1,6 +1,8 @@
 #!/bin/sh
 
 find . -type d -name .deps | xargs rm -rf
+rm -rf config.guess config.sub ltmain.sh
+libtoolize
 aclocal 2>/dev/null &&
 autoheader &&
 automake --add-missing --include-deps # 2>/dev/null &&
index 52bc4f593b68d4b7fdd76df049159b2606acb921..833514dc11ab64145d7004844276b646afd4aaf9 100644 (file)
@@ -6,6 +6,7 @@ AC_CONFIG_HEADERS([config.h])
 
 AC_PROG_INSTALL
 AC_PROG_CC
+AC_PROG_LIBTOOL
 
 ver=`uname -r`
 KERNELCFLAGS=
@@ -88,21 +89,6 @@ else
        AC_MSG_RESULT([no])
 fi
 
-AC_MSG_CHECKING([if inode has i_private field])
-if egrep -qw "i_private" $kernelsrc/include/linux/fs.h; then
-       AC_DEFINE(HAVE_I_PRIVATE, 1, [inode has i_private field])
-       AC_MSG_RESULT([yes])
-else
-       AC_MSG_RESULT([no])
-fi
-
-AC_MSG_CHECKING([if inode has i_mutex field ])
-if egrep -qw "i_mutex" $kernelsrc/include/linux/fs.h; then
-       AC_DEFINE(HAVE_I_MUTEX, 1, [inode has i_mutex field])
-       AC_MSG_RESULT([yes])
-else
-       AC_MSG_RESULT([no])
-fi
 
 AC_MSG_CHECKING([if kernel has mutex.h ])
 if test -f $kernelsrc/include/linux/mutex.h; then
@@ -122,6 +108,7 @@ AC_SUBST(KERNELCFLAGS)
 
 AC_CONFIG_FILES([ Makefile
                   src/Makefile
+                  src/lib/Makefile
                   src/cmd/Makefile
                   src/spl/Makefile
                   src/splat/Makefile
index 42bbb2399187a040889cefeae3a62ec69054ec38..5b063fd094d303c594fd96766f0f07d0278ca5ba 100644 (file)
@@ -1,5 +1,7 @@
-EXTRA_DIST  = spl.h splat.h splat-ctl.h
+EXTRA_DIST  = spl.h 
+EXTRA_DIST += splat.h splat-ctl.h
 EXTRA_DIST += linux-condvar.h linux-kmem.h linux-random.h linux-thread.h
 EXTRA_DIST += linux-types.h linux-cred.h linux-kstat.h linux-rwlock.h
 EXTRA_DIST += linux-time.h linux-callb.h linux-generic.h linux-mutex.h  
 EXTRA_DIST += linux-taskq.h linux-timer.h
+EXTRA_DIST += list.h
diff --git a/include/list.h b/include/list.h
new file mode 100644 (file)
index 0000000..fe3fd00
--- /dev/null
@@ -0,0 +1,281 @@
+/*****************************************************************************
+ *  $Id: list.h 2899 2002-12-11 19:00:36Z dun $
+ *****************************************************************************
+ *  Copyright (C) 2001-2002 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Chris Dunlap <cdunlap@llnl.gov>.
+ *  
+ *  This file is from LSD-Tools, the LLNL Software Development Toolbox.
+ *
+ *  LSD-Tools is free software; you can redistribute it and/or modify it under
+ *  the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *
+ *  LSD-Tools is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with LSD-Tools; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ *****************************************************************************/
+
+
+#ifndef LSD_LIST_H
+#define LSD_LIST_H
+
+
+/***********
+ *  Notes  *
+ ***********/
+/*
+ *  If NDEBUG is not defined, internal debug code will be enabled.  This is
+ *  intended for development use only and production code should define NDEBUG.
+ *
+ *  If WITH_LSD_FATAL_ERROR_FUNC is defined, the linker will expect to
+ *  find an external lsd_fatal_error(file,line,mesg) function.  By default,
+ *  lsd_fatal_error(file,line,mesg) is a macro definition that outputs an
+ *  error message to stderr.  This macro may be redefined to invoke another
+ *  routine instead.
+ *
+ *  If WITH_LSD_NOMEM_ERROR_FUNC is defined, the linker will expect to
+ *  find an external lsd_nomem_error(file,line,mesg) function.  By default,
+ *  lsd_nomem_error(file,line,mesg) is a macro definition that returns NULL.
+ *  This macro may be redefined to invoke another routine instead.
+ *
+ *  If WITH_PTHREADS is defined, these routines will be thread-safe.
+ */
+
+
+/****************
+ *  Data Types  *
+ ****************/
+
+typedef struct list * List;
+/*
+ *  List opaque data type.
+ */
+
+typedef struct listIterator * ListIterator;
+/*
+ *  List Iterator opaque data type.
+ */
+
+typedef void (*ListDelF) (void *x);
+/*
+ *  Function prototype to deallocate data stored in a list.
+ *    This function is responsible for freeing all memory associated
+ *    with an item, including all subordinate items (if applicable).
+ */
+
+typedef int (*ListCmpF) (void *x, void *y);
+/*
+ *  Function prototype for comparing two items in a list.
+ *  Returns less-than-zero if (x<y), zero if (x==y), and
+ *    greather-than-zero if (x>y).
+ */
+
+typedef int (*ListFindF) (void *x, void *key);
+/*
+ *  Function prototype for matching items in a list.
+ *  Returns non-zero if (x==key); o/w returns zero.
+ */
+
+typedef int (*ListForF) (void *x, void *arg);
+/*
+ *  Function prototype for operating on each item in a list.
+ *  Returns less-than-zero on error.
+ */
+
+
+/*******************************
+ *  General-Purpose Functions  *
+ *******************************/
+
+List list_create (ListDelF f);
+/*
+ *  Creates and returns a new empty list, or lsd_nomem_error() on failure.
+ *  The deletion function [f] is used to deallocate memory used by items
+ *    in the list; if this is NULL, memory associated with these items
+ *    will not be freed when the list is destroyed.
+ *  Note: Abandoning a list without calling list_destroy() will result
+ *    in a memory leak.
+ */
+
+void list_destroy (List l);
+/*
+ *  Destroys list [l], freeing memory used for list iterators and the
+ *    list itself; if a deletion function was specified when the list
+ *    was created, it will be called for each item in the list.
+ */
+
+int list_is_empty (List l);
+/*
+ *  Returns non-zero if list [l] is empty; o/w returns zero.
+ */
+
+int list_count (List l);
+/*
+ *  Returns the number of items in list [l].
+ */
+
+
+/***************************
+ *  List Access Functions  *
+ ***************************/
+
+void * list_append (List l, void *x);
+/*
+ *  Inserts data [x] at the end of list [l].
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_prepend (List l, void *x);
+/*
+ *  Inserts data [x] at the beginning of list [l].
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_find_first (List l, ListFindF f, void *key);
+/*
+ *  Traverses list [l] using [f] to match each item with [key].
+ *  Returns a ptr to the first item for which the function [f]
+ *    returns non-zero, or NULL if no such item is found.
+ *  Note: This function differs from list_find() in that it does not require
+ *    a list iterator; it should only be used when all list items are known
+ *    to be unique (according to the function [f]).
+ */
+
+int list_delete_all (List l, ListFindF f, void *key);
+/*
+ *  Traverses list [l] using [f] to match each item with [key].
+ *  Removes all items from the list for which the function [f] returns
+ *    non-zero; if a deletion function was specified when the list was
+ *    created, it will be called to deallocate each item being removed.
+ *  Returns a count of the number of items removed from the list.
+ */
+
+int list_for_each (List l, ListForF f, void *arg);
+/*
+ *  For each item in list [l], invokes the function [f] with [arg].
+ *  Returns a count of the number of items on which [f] was invoked.
+ *  If [f] returns <0 for a given item, the iteration is aborted and the
+ *    function returns the negative of that item's position in the list.
+ */
+
+void list_sort (List l, ListCmpF f);
+/*
+ *  Sorts list [l] into ascending order according to the function [f].
+ *  Note: Sorting a list resets all iterators associated with the list.
+ *  Note: The sort algorithm is stable.
+ */
+
+
+/****************************
+ *  Stack Access Functions  *
+ ****************************/
+
+void * list_push (List l, void *x);
+/*
+ *  Pushes data [x] onto the top of stack [l].
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_pop (List l);
+/*
+ *  Pops the data item at the top of the stack [l].
+ *  Returns the data's ptr, or NULL if the stack is empty.
+ */
+
+void * list_peek (List l);
+/*
+ *  Peeks at the data item at the top of the stack (or head of the queue) [l].
+ *  Returns the data's ptr, or NULL if the stack (or queue) is empty.
+ *  Note: The item is not removed from the list.
+ */
+
+
+/****************************
+ *  Queue Access Functions  *
+ ****************************/
+
+void * list_enqueue (List l, void *x);
+/*
+ *  Enqueues data [x] at the tail of queue [l].
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_dequeue (List l);
+/*
+ *  Dequeues the data item at the head of the queue [l].
+ *  Returns the data's ptr, or NULL if the queue is empty.
+ */
+
+
+/*****************************
+ *  List Iterator Functions  *
+ *****************************/
+
+ListIterator list_iterator_create (List l);
+/*
+ *  Creates and returns a list iterator for non-destructively traversing
+ *    list [l], or lsd_nomem_error() on failure.
+ */
+
+void list_iterator_reset (ListIterator i);
+/*
+ *  Resets the list iterator [i] to start traversal at the beginning
+ *    of the list.
+ */
+
+void list_iterator_destroy (ListIterator i);
+/*
+ *  Destroys the list iterator [i]; list iterators not explicitly destroyed
+ *    in this manner will be destroyed when the list is deallocated via
+ *    list_destroy().
+ */
+
+void * list_next (ListIterator i);
+/*
+ *  Returns a ptr to the next item's data,
+ *    or NULL once the end of the list is reached.
+ *  Example: i=list_iterator_create(i); while ((x=list_next(i))) {...}
+ */
+
+void * list_insert (ListIterator i, void *x);
+/*
+ *  Inserts data [x] immediately before the last item returned via list
+ *    iterator [i]; once the list iterator reaches the end of the list,
+ *    insertion is made at the list's end.
+ *  Returns the data's ptr, or lsd_nomem_error() if insertion failed.
+ */
+
+void * list_find (ListIterator i, ListFindF f, void *key);
+/*
+ *  Traverses the list from the point of the list iterator [i]
+ *    using [f] to match each item with [key].
+ *  Returns a ptr to the next item for which the function [f]
+ *    returns non-zero, or NULL once the end of the list is reached.
+ *  Example: i=list_iterator_reset(i); while ((x=list_find(i,f,k))) {...}
+ */
+
+void * list_remove (ListIterator i);
+/*
+ *  Removes from the list the last item returned via list iterator [i]
+ *    and returns the data's ptr.
+ *  Note: The client is responsible for freeing the returned data.
+ */
+
+int list_delete (ListIterator i);
+/*
+ *  Removes from the list the last item returned via list iterator [i];
+ *    if a deletion function was specified when the list was created,
+ *    it will be called to deallocate the item being removed.
+ *  Returns a count of the number of items removed from the list
+ *    (ie, '1' if the item was removed, and '0' otherwise).
+ */
+
+
+#endif /* !LSD_LIST_H */
index 69cb387ad1c0c0682e75908469f114215ead1de0..f9341b5d9d83ceb0b61e8122ea9e5568d136503f 100644 (file)
@@ -1,7 +1,8 @@
-#ifndef _KZT_H
-#define _KZT_H
+#ifndef _SPLAT_H
+#define _SPLAT_H
 
-#include <sys/splat-ctl.h>
+#include "list.h"
+#include "splat-ctl.h"
 
 #define DEV_NAME                       "/dev/kztctl"
 #define COLOR_BLACK                    "\033[0;30m"
 #define COLOR_RESET                    "\033[0m"
 
 typedef struct subsystem {
-       uu_list_node_t sub_node;        /* Linkage for global subsystem list */
        kzt_user_t sub_desc;            /* Subsystem description */
-       uu_list_t *sub_tests;           /* Assocated subsystem tests list */
+       List sub_tests;                 /* Assocated subsystem tests list */
 } subsystem_t;
 
 typedef struct test {
-       uu_list_node_t test_node;       /* Linkage for globals test list */
        kzt_user_t test_desc;           /* Test description */
        subsystem_t *test_sub;          /* Parent subsystem */
 } test_t;
@@ -40,8 +39,8 @@ typedef struct cmd_args {
        int args_do_all;                /* Run all tests flag */
        int args_do_color;              /* Colorize output */
        int args_exit_on_error;         /* Exit on first error flag */
-       uu_list_t *args_tests;          /* Requested subsystems/tests */
+       List args_tests;                /* Requested subsystems/tests */
 } cmd_args_t;
 
-#endif /* _KZT_H */
+#endif /* _SPLAT_H */
 
index 86f519112a45b01f1139a5927e6efd8a0d7fe2f3..51013b8d1213658dfbc46401dc77cf2069ca772c 100644 (file)
@@ -1 +1 @@
-SUBDIRS = cmd spl splat
+SUBDIRS = lib cmd spl splat
index 38a21099c95a33b3441eb3ae1a749e12fc26d401..ae3961a9778e4535d9e0b07ffda3560f34e5eaf7 100644 (file)
@@ -1,3 +1,5 @@
-AM_CFLAGS = @EXTRA_CFLAGS@ -g -O2 -W -Wall -Wstrict-prototypes -Wshadow
+AM_CFLAGS = -g -O2 -W -Wall -Wstrict-prototypes -Wshadow
+INCLUDES = -I$(top_srcdir)/include
 sbin_PROGRAMS = splat
 splat_SOURCES = splat.c
+splat_LDFLAGS = $(top_builddir)/src/lib/libcommon.la
index 0ad65490c986fbde0d3c2feadb01710c11bd73a5..56181af3d30120828646636e5d25f9896d7f1baf 100644 (file)
@@ -1,4 +1,4 @@
-/* Kernel ZFS Test (KZT) user space command interface */
+/* Solaris Porting Layer Aggressive Test (SPLAT) userspace interface */
 
 #include <stdlib.h>
 #include <stddef.h>
@@ -8,7 +8,6 @@
 #include <getopt.h>
 #include <assert.h>
 #include <fcntl.h>
-#include <libuutil.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -29,17 +28,17 @@ static const struct option longOpts[] = {
        { 0,                 0,                 0, 0   }
 };
 
-static uu_list_t *subsystems;                  /* Subsystem/tests */
-static uu_list_pool_t *subsystem_pool;         /* Subsystem pool */
-static uu_list_pool_t *test_pool;              /* Test pool */
+static List subsystems;                                /* Subsystem/tests */
 static int kztctl_fd;                          /* Control file descriptor */
 static char kzt_version[KZT_VERSION_SIZE];     /* Kernel version string */
 static char *kzt_buffer = NULL;                        /* Scratch space area */
 static int kzt_buffer_size = 0;                        /* Scratch space size */
 
 
-static void test_list(uu_list_t *, int);
+static void test_list(List, int);
 static int dev_clear(void);
+static void subsystem_fini(subsystem_t *);
+static void test_fini(test_t *);
 
 
 static int usage(void) {
@@ -69,9 +68,8 @@ static subsystem_t *subsystem_init(kzt_user_t *desc)
                return NULL;
 
        memcpy(&sub->sub_desc, desc, sizeof(*desc));
-       uu_list_node_init(sub, &sub->sub_node, subsystem_pool);
 
-       sub->sub_tests = uu_list_create(test_pool, NULL, 0);
+       sub->sub_tests = list_create((ListDelF)test_fini);
        if (sub->sub_tests == NULL) {
                free(sub);
                return NULL;
@@ -83,8 +81,6 @@ static subsystem_t *subsystem_init(kzt_user_t *desc)
 static void subsystem_fini(subsystem_t *sub)
 {
        assert(sub != NULL);
-
-       uu_list_node_fini(sub, &sub->sub_node, subsystem_pool);
        free(sub);
 }
 
@@ -149,13 +145,15 @@ static int subsystem_setup(void)
                        return -ENOMEM;
                }
 
-               uu_list_insert(subsystems, sub, 0);
+               list_append(subsystems, sub);
        }
 
        free(cfg);
        return 0;
 }
 
+/* XXX - Commented out until we sort the lists */
+#if 0
 static int subsystem_compare(const void *l_arg, const void *r_arg, void *private)
 {
        const subsystem_t *l = l_arg;
@@ -169,9 +167,11 @@ static int subsystem_compare(const void *l_arg, const void *r_arg, void *private
 
        return 0;
 }
+#endif
 
-static void subsystem_list(uu_list_t *list, int indent)
+static void subsystem_list(List l, int indent)
 {
+       ListIterator i;
        subsystem_t *sub;
 
        fprintf(stdout,
@@ -179,8 +179,9 @@ static void subsystem_list(uu_list_t *list, int indent)
                "Available KZT Tests "
                "-------------------------------\n");
 
-       for (sub = uu_list_first(list); sub != NULL;
-            sub = uu_list_next(list, sub)) {
+       i = list_iterator_create(l);
+
+       while ((sub = list_next(i))) {
                fprintf(stdout, "%*s0x%0*x %-*s ---- %s ----\n",
                        indent, "",
                        4, sub->sub_desc.id,
@@ -188,6 +189,8 @@ static void subsystem_list(uu_list_t *list, int indent)
                        sub->sub_desc.desc);
                test_list(sub->sub_tests, indent + 7);
        }
+
+       list_iterator_destroy(i);
 }
 
 static test_t *test_init(subsystem_t *sub, kzt_user_t *desc)
@@ -200,7 +203,6 @@ static test_t *test_init(subsystem_t *sub, kzt_user_t *desc)
 
        test->test_sub = sub;
        memcpy(&test->test_desc, desc, sizeof(*desc));
-       uu_list_node_init(test, &test->test_node, test_pool);
 
        return test;
 }
@@ -208,8 +210,6 @@ static test_t *test_init(subsystem_t *sub, kzt_user_t *desc)
 static void test_fini(test_t *test)
 {
        assert(test != NULL);
-
-       uu_list_node_fini(test, &test->test_node, test_pool);
        free(test);
 }
 
@@ -274,13 +274,15 @@ static int test_setup(subsystem_t *sub)
                        return -ENOMEM;
                }
 
-               uu_list_insert(sub->sub_tests, test, 0);
+               list_append(sub->sub_tests, test);
        }
 
        free(cfg);
        return 0;
 }
 
+/* XXX - Commented out until we sort the lists */
+#if 0
 static int test_compare(const void *l_arg, const void *r_arg, void *private)
 {
        const test_t *l = l_arg;
@@ -294,27 +296,33 @@ static int test_compare(const void *l_arg, const void *r_arg, void *private)
 
        return 0;
 }
+#endif
 
 static test_t *test_copy(test_t *test)
 {
        return test_init(test->test_sub, &test->test_desc);
 }
 
-static void test_list(uu_list_t *list, int indent)
+static void test_list(List l, int indent)
 {
+       ListIterator i;
        test_t *test;
 
-       for (test = uu_list_first(list); test != NULL;
-            test = uu_list_next(list, test))
+       i = list_iterator_create(l);
+
+       while ((test = list_next(i)))
                fprintf(stdout, "%*s0x%0*x %-*s %-*s\n",
                        indent, "",
                        04, test->test_desc.id,
                        KZT_NAME_SIZE, test->test_desc.name,
                        KZT_DESC_SIZE, test->test_desc.desc);
+
+       list_iterator_destroy(i);
 }
 
 static test_t *test_find(char *sub_str, char *test_str)
 {
+       ListIterator si, ti;
        subsystem_t *sub;
        test_t *test;
        int sub_num, test_num;
@@ -326,22 +334,31 @@ static test_t *test_find(char *sub_str, char *test_str)
        sub_num = strtol(sub_str, NULL, 0);
        test_num = strtol(test_str, NULL, 0);
 
-       for (sub = uu_list_first(subsystems); sub != NULL;
-            sub = uu_list_next(subsystems, sub)) {
+        si = list_iterator_create(subsystems);
+
+        while ((sub = list_next(si))) {
 
                if (strncmp(sub->sub_desc.name, sub_str, KZT_NAME_SIZE) &&
                    sub->sub_desc.id != sub_num)
                        continue;
 
-               for (test = uu_list_first(sub->sub_tests); test != NULL;
-                    test = uu_list_next(sub->sub_tests, test)) {
+               ti = list_iterator_create(sub->sub_tests);
+
+               while ((test = list_next(ti))) {
 
                        if (!strncmp(test->test_desc.name, test_str,
-                           KZT_NAME_SIZE) || test->test_desc.id == test_num)
+                           KZT_NAME_SIZE) || test->test_desc.id == test_num) {
+                               list_iterator_destroy(ti);
+                               list_iterator_destroy(si);
                                return test;
+                       }
                }
+
+               list_iterator_destroy(ti);
         }
 
+        list_iterator_destroy(si);
+
        return NULL;
 }
 
@@ -353,27 +370,35 @@ static int test_add(cmd_args_t *args, test_t *test)
        if (tmp == NULL)
                return -ENOMEM;
 
-       uu_list_insert(args->args_tests, tmp, 0);
+       list_append(args->args_tests, tmp);
        return 0;
 }
 
 static int test_add_all(cmd_args_t *args)
 {
+       ListIterator si, ti;
        subsystem_t *sub;
        test_t *test;
        int rc;
 
-       for (sub = uu_list_first(subsystems); sub != NULL;
-            sub = uu_list_next(subsystems, sub)) {
+        si = list_iterator_create(subsystems);
 
-               for (test = uu_list_first(sub->sub_tests); test != NULL;
-                    test = uu_list_next(sub->sub_tests, test)) {
+        while ((sub = list_next(si))) {
+               ti = list_iterator_create(sub->sub_tests);
 
-                       if (rc = test_add(args, test))
+               while ((test = list_next(ti))) {
+                       if ((rc = test_add(args, test))) {
+                               list_iterator_destroy(ti);
+                               list_iterator_destroy(si);
                                return rc;
+                       }
                }
+
+               list_iterator_destroy(ti);
         }
 
+        list_iterator_destroy(si);
+
        return 0;
 }
 
@@ -428,6 +453,7 @@ static int test_run(cmd_args_t *args, test_t *test)
 
 static int tests_run(cmd_args_t *args)
 {
+        ListIterator i;
        test_t *test;
        int rc;
 
@@ -436,19 +462,23 @@ static int tests_run(cmd_args_t *args)
                "Running KZT Tests "
                "-------------------------------\n");
 
-       for (test = uu_list_first(args->args_tests); test != NULL;
-            test = uu_list_next(args->args_tests, test)) {
+       i = list_iterator_create(args->args_tests);
 
+       while ((test = list_next(i))) {
                rc = test_run(args, test);
-               if (rc && args->args_exit_on_error)
+               if (rc && args->args_exit_on_error) {
+                       list_iterator_destroy(i);
                        return rc;
+               }
        }
 
+       list_iterator_destroy(i);
        return 0;
 }
 
 static int args_parse_test(cmd_args_t *args, char *str)
 {
+        ListIterator si, ti;
        subsystem_t *s;
        test_t *t;
        char *sub_str, *test_str;
@@ -476,21 +506,26 @@ static int args_parse_test(cmd_args_t *args, char *str)
        if (!strncasecmp(test_str, "all", strlen(test_str)) || (test_num == -1))
                test_all = 1;
 
+       si = list_iterator_create(subsystems);
+
        if (sub_all) {
                if (test_all) {
                        /* Add all tests from all subsystems */
-                       for (s = uu_list_first(subsystems); s != NULL;
-                            s = uu_list_next(subsystems, s))
-                               for (t = uu_list_first(s->sub_tests);t != NULL;
-                                    t = uu_list_next(s->sub_tests, t))
-                                       if (rc = test_add(args, t))
+                       while ((s = list_next(si))) {
+                               ti = list_iterator_create(s->sub_tests);
+                               while ((t = list_next(ti))) {
+                                       if ((rc = test_add(args, t))) {
+                                               list_iterator_destroy(ti);
                                                goto error_run;
+                                       }
+                               }
+                               list_iterator_destroy(ti);
+                       }
                } else {
                        /* Add a specific test from all subsystems */
-                       for (s = uu_list_first(subsystems); s != NULL;
-                            s = uu_list_next(subsystems, s)) {
-                               if (t = test_find(s->sub_desc.name,test_str)) {
-                                       if (rc = test_add(args, t))
+                       while ((s = list_next(si))) {
+                               if ((t = test_find(s->sub_desc.name,test_str))) {
+                                       if ((rc = test_add(args, t)))
                                                goto error_run;
 
                                        flag = 1;
@@ -504,21 +539,24 @@ static int args_parse_test(cmd_args_t *args, char *str)
        } else {
                if (test_all) {
                        /* Add all tests from a specific subsystem */
-                       for (s = uu_list_first(subsystems); s != NULL;
-                            s = uu_list_next(subsystems, s)) {
+                       while ((s = list_next(si))) {
                                if (strncasecmp(sub_str, s->sub_desc.name,
                                    strlen(sub_str)))
                                        continue;
 
-                               for (t = uu_list_first(s->sub_tests);t != NULL;
-                                    t = uu_list_next(s->sub_tests, t))
-                                       if (rc = test_add(args, t))
+                               ti = list_iterator_create(s->sub_tests);
+                               while ((t = list_next(ti))) {
+                                       if ((rc = test_add(args, t))) {
+                                               list_iterator_destroy(ti);
                                                goto error_run;
+                                       }
+                               }
+                               list_iterator_destroy(ti);
                        }
                } else {
                        /* Add a specific test from a specific subsystem */
-                       if (t = test_find(sub_str, test_str)) {
-                               if (rc = test_add(args, t))
+                       if ((t = test_find(sub_str, test_str))) {
+                               if ((rc = test_add(args, t)))
                                        goto error_run;
                        } else {
                                fprintf(stderr, "Test '%s:%s' could not be "
@@ -528,25 +566,25 @@ static int args_parse_test(cmd_args_t *args, char *str)
                }
        }
 
+       list_iterator_destroy(si);
+
        return 0;
 
 error_run:
+       list_iterator_destroy(si);
+
        fprintf(stderr, "Test '%s:%s' not added to run list: %d\n",
                sub_str, test_str, rc);
+
        return rc;
 }
 
 static void args_fini(cmd_args_t *args)
 {
-       struct cmd_test *ptr1, *ptr2;
-
        assert(args != NULL);
 
-
-
-       if (args->args_tests != NULL) {
-               uu_list_destroy(args->args_tests);
-       }
+       if (args->args_tests != NULL)
+               list_destroy(args->args_tests);
 
        free(args);
 }
@@ -573,7 +611,7 @@ args_init(int argc, char **argv)
        args->args_do_all  = 0;
        args->args_do_color = 1;
        args->args_exit_on_error = 0;
-       args->args_tests = uu_list_create(test_pool, NULL, 0);
+       args->args_tests = list_create((ListDelF)test_fini);
        if (args->args_tests == NULL) {
                args_fini(args);
                return NULL;
@@ -674,6 +712,7 @@ dev_fini(void)
 static int
 dev_init(void)
 {
+       ListIterator i;
        subsystem_t *sub;
        int rc;
 
@@ -690,7 +729,7 @@ dev_init(void)
        if ((rc = read(kztctl_fd, kzt_version, KZT_VERSION_SIZE - 1)) == -1)
                goto error;
 
-       if (rc = dev_clear())
+       if ((rc = dev_clear()))
                goto error;
 
        if ((rc = dev_size(0)) < 0)
@@ -710,11 +749,16 @@ dev_init(void)
                goto error;
 
        /* Determine available tests for all subsystems */
-       for (sub = uu_list_first(subsystems); sub != NULL;
-            sub = uu_list_next(subsystems, sub))
-               if ((rc = test_setup(sub)) != 0)
+       i = list_iterator_create(subsystems);
+
+       while ((sub = list_next(i))) {
+               if ((rc = test_setup(sub)) != 0) {
+                       list_iterator_destroy(i);
                        goto error;
+               }
+       }
 
+       list_iterator_destroy(i);
        return 0;
 
 error:
@@ -731,42 +775,20 @@ error:
 int
 init(void)
 {
-       int rc;
-
-       /* Configure the subsystem pool */
-       subsystem_pool = uu_list_pool_create("sub_pool", sizeof(subsystem_t),
-                                            offsetof(subsystem_t, sub_node),
-                                            subsystem_compare, 0);
-       if (subsystem_pool == NULL)
-               return -ENOMEM;
-
-       /* Configure the test pool */
-       test_pool = uu_list_pool_create("test_pool", sizeof(test_t),
-                                       offsetof(test_t, test_node),
-                                       test_compare, 0);
-       if (test_pool == NULL) {
-               uu_list_pool_destroy(subsystem_pool);
-               return -ENOMEM;
-       }
+       int rc = 0;
 
        /* Allocate the subsystem list */
-       subsystems = uu_list_create(subsystem_pool, NULL, 0);
-       if (subsystems == NULL) {
-               uu_list_pool_destroy(test_pool);
-               uu_list_pool_destroy(subsystem_pool);
-               return -ENOMEM;
-       }
+       subsystems = list_create((ListDelF)subsystem_fini);
+       if (subsystems == NULL)
+               rc = ENOMEM;
 
-       return 0;
+       return rc;
 }
 
 void
 fini(void)
 {
-       /* XXX - Cleanup destroy lists release memory */
-
-       /* XXX - Remove contents of list first */
-       uu_list_destroy(subsystems);
+       list_destroy(subsystems);
 }
 
 
@@ -777,11 +799,11 @@ main(int argc, char **argv)
        int rc = 0;
 
        /* General init */
-       if (rc = init())
+       if ((rc = init()))
                return rc;
 
        /* Device specific init */
-       if (rc = dev_init())
+       if ((rc = dev_init()))
                goto out;
 
        /* Argument init and parsing */
@@ -802,12 +824,12 @@ main(int argc, char **argv)
 
        /* Add all available test to the list of tests to run */
        if (args->args_do_all) {
-               if (rc = test_add_all(args))
+               if ((rc = test_add_all(args)))
                        goto out;
        }
 
        /* Run all the requested tests */
-       if (rc = tests_run(args))
+       if ((rc = tests_run(args)))
                goto out;
 
 out:
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..91c228f
--- /dev/null
@@ -0,0 +1,3 @@
+INCLUDES = -I$(top_srcdir)/include
+noinst_LTLIBRARIES = libcommon.la
+libcommon_la_SOURCES = list.c
diff --git a/src/lib/list.c b/src/lib/list.c
new file mode 100644 (file)
index 0000000..6548cac
--- /dev/null
@@ -0,0 +1,833 @@
+/*****************************************************************************
+ *  $Id: list.c 3709 2006-11-29 00:51:22Z dun $
+ *****************************************************************************
+ *  Copyright (C) 2001-2002 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Chris Dunlap <cdunlap@llnl.gov>.
+ *
+ *  This file is from LSD-Tools, the LLNL Software Development Toolbox.
+ *
+ *  LSD-Tools is free software; you can redistribute it and/or modify it under
+ *  the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *
+ *  LSD-Tools is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with LSD-Tools; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ *****************************************************************************
+ *  Refer to "list.h" for documentation on public functions.
+ *****************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef WITH_PTHREADS
+#  include <pthread.h>
+#endif /* WITH_PTHREADS */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include "list.h"
+
+
+/*********************
+ *  lsd_fatal_error  *
+ *********************/
+
+#ifdef WITH_LSD_FATAL_ERROR_FUNC
+#  undef lsd_fatal_error
+   extern void lsd_fatal_error(char *file, int line, char *mesg);
+#else /* !WITH_LSD_FATAL_ERROR_FUNC */
+#  ifndef lsd_fatal_error
+#    include <errno.h>
+#    include <stdio.h>
+#    include <string.h>
+#    define lsd_fatal_error(file, line, mesg)                                 \
+       do {                                                                   \
+           fprintf(stderr, "ERROR: [%s:%d] %s: %s\n",                         \
+                   file, line, mesg, strerror(errno));                        \
+       } while (0)
+#  endif /* !lsd_fatal_error */
+#endif /* !WITH_LSD_FATAL_ERROR_FUNC */
+
+
+/*********************
+ *  lsd_nomem_error  *
+ *********************/
+
+#ifdef WITH_LSD_NOMEM_ERROR_FUNC
+#  undef lsd_nomem_error
+   extern void * lsd_nomem_error(char *file, int line, char *mesg);
+#else /* !WITH_LSD_NOMEM_ERROR_FUNC */
+#  ifndef lsd_nomem_error
+#    define lsd_nomem_error(file, line, mesg) (NULL)
+#  endif /* !lsd_nomem_error */
+#endif /* !WITH_LSD_NOMEM_ERROR_FUNC */
+
+
+/***************
+ *  Constants  *
+ ***************/
+
+#define LIST_ALLOC 32
+#define LIST_MAGIC 0xDEADBEEF
+
+
+/****************
+ *  Data Types  *
+ ****************/
+
+struct listNode {
+    void                 *data;         /* node's data                       */
+    struct listNode      *next;         /* next node in list                 */
+};
+
+struct listIterator {
+    struct list          *list;         /* the list being iterated           */
+    struct listNode      *pos;          /* the next node to be iterated      */
+    struct listNode     **prev;         /* addr of 'next' ptr to prv It node */
+    struct listIterator  *iNext;        /* iterator chain for list_destroy() */
+#ifndef NDEBUG
+    unsigned int          magic;        /* sentinel for asserting validity   */
+#endif /* !NDEBUG */
+};
+
+struct list {
+    struct listNode      *head;         /* head of the list                  */
+    struct listNode     **tail;         /* addr of last node's 'next' ptr    */
+    struct listIterator  *iNext;        /* iterator chain for list_destroy() */
+    ListDelF              fDel;         /* function to delete node data      */
+    int                   count;        /* number of nodes in list           */
+#ifdef WITH_PTHREADS
+    pthread_mutex_t       mutex;        /* mutex to protect access to list   */
+#endif /* WITH_PTHREADS */
+#ifndef NDEBUG
+    unsigned int          magic;        /* sentinel for asserting validity   */
+#endif /* !NDEBUG */
+};
+
+typedef struct listNode * ListNode;
+
+
+/****************
+ *  Prototypes  *
+ ****************/
+
+static void * list_node_create (List l, ListNode *pp, void *x);
+static void * list_node_destroy (List l, ListNode *pp);
+static List list_alloc (void);
+static void list_free (List l);
+static ListNode list_node_alloc (void);
+static void list_node_free (ListNode p);
+static ListIterator list_iterator_alloc (void);
+static void list_iterator_free (ListIterator i);
+static void * list_alloc_aux (int size, void *pfreelist);
+static void list_free_aux (void *x, void *pfreelist);
+
+
+/***************
+ *  Variables  *
+ ***************/
+
+static List list_free_lists = NULL;
+static ListNode list_free_nodes = NULL;
+static ListIterator list_free_iterators = NULL;
+
+#ifdef WITH_PTHREADS
+static pthread_mutex_t list_free_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif /* WITH_PTHREADS */
+
+
+/************
+ *  Macros  *
+ ************/
+
+#ifdef WITH_PTHREADS
+
+#  define list_mutex_init(mutex)                                              \
+     do {                                                                     \
+         int e = pthread_mutex_init(mutex, NULL);                             \
+         if (e != 0) {                                                        \
+             errno = e;                                                       \
+             lsd_fatal_error(__FILE__, __LINE__, "list mutex init");          \
+             abort();                                                         \
+         }                                                                    \
+     } while (0)
+
+#  define list_mutex_lock(mutex)                                              \
+     do {                                                                     \
+         int e = pthread_mutex_lock(mutex);                                   \
+         if (e != 0) {                                                        \
+             errno = e;                                                       \
+             lsd_fatal_error(__FILE__, __LINE__, "list mutex lock");          \
+             abort();                                                         \
+         }                                                                    \
+     } while (0)
+
+#  define list_mutex_unlock(mutex)                                            \
+     do {                                                                     \
+         int e = pthread_mutex_unlock(mutex);                                 \
+         if (e != 0) {                                                        \
+             errno = e;                                                       \
+             lsd_fatal_error(__FILE__, __LINE__, "list mutex unlock");        \
+             abort();                                                         \
+         }                                                                    \
+     } while (0)
+
+#  define list_mutex_destroy(mutex)                                           \
+     do {                                                                     \
+         int e = pthread_mutex_destroy(mutex);                                \
+         if (e != 0) {                                                        \
+             errno = e;                                                       \
+             lsd_fatal_error(__FILE__, __LINE__, "list mutex destroy");       \
+             abort();                                                         \
+         }                                                                    \
+     } while (0)
+
+#  ifndef NDEBUG
+     static int list_mutex_is_locked (pthread_mutex_t *mutex);
+#  endif /* !NDEBUG */
+
+#else /* !WITH_PTHREADS */
+
+#  define list_mutex_init(mutex)
+#  define list_mutex_lock(mutex)
+#  define list_mutex_unlock(mutex)
+#  define list_mutex_destroy(mutex)
+#  define list_mutex_is_locked(mutex) (1)
+
+#endif /* !WITH_PTHREADS */
+
+
+/***************
+ *  Functions  *
+ ***************/
+
+List
+list_create (ListDelF f)
+{
+    List l;
+
+    if (!(l = list_alloc()))
+        return(lsd_nomem_error(__FILE__, __LINE__, "list create"));
+    l->head = NULL;
+    l->tail = &l->head;
+    l->iNext = NULL;
+    l->fDel = f;
+    l->count = 0;
+    list_mutex_init(&l->mutex);
+    assert(l->magic = LIST_MAGIC);      /* set magic via assert abuse */
+    return(l);
+}
+
+
+void
+list_destroy (List l)
+{
+    ListIterator i, iTmp;
+    ListNode p, pTmp;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    i = l->iNext;
+    while (i) {
+        assert(i->magic == LIST_MAGIC);
+        iTmp = i->iNext;
+        assert(i->magic = ~LIST_MAGIC); /* clear magic via assert abuse */
+        list_iterator_free(i);
+        i = iTmp;
+    }
+    p = l->head;
+    while (p) {
+        pTmp = p->next;
+        if (p->data && l->fDel)
+            l->fDel(p->data);
+        list_node_free(p);
+        p = pTmp;
+    }
+    assert(l->magic = ~LIST_MAGIC);     /* clear magic via assert abuse */
+    list_mutex_unlock(&l->mutex);
+    list_mutex_destroy(&l->mutex);
+    list_free(l);
+    return;
+}
+
+
+int
+list_is_empty (List l)
+{
+    int n;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    n = l->count;
+    list_mutex_unlock(&l->mutex);
+    return(n == 0);
+}
+
+
+int
+list_count (List l)
+{
+    int n;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    n = l->count;
+    list_mutex_unlock(&l->mutex);
+    return(n);
+}
+
+
+void *
+list_append (List l, void *x)
+{
+    void *v;
+
+    assert(l != NULL);
+    assert(x != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_create(l, l->tail, x);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_prepend (List l, void *x)
+{
+    void *v;
+
+    assert(l != NULL);
+    assert(x != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_create(l, &l->head, x);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_find_first (List l, ListFindF f, void *key)
+{
+    ListNode p;
+    void *v = NULL;
+
+    assert(l != NULL);
+    assert(f != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    for (p=l->head; p; p=p->next) {
+        if (f(p->data, key)) {
+            v = p->data;
+            break;
+        }
+    }
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+int
+list_delete_all (List l, ListFindF f, void *key)
+{
+    ListNode *pp;
+    void *v;
+    int n = 0;
+
+    assert(l != NULL);
+    assert(f != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    pp = &l->head;
+    while (*pp) {
+        if (f((*pp)->data, key)) {
+            if ((v = list_node_destroy(l, pp))) {
+                if (l->fDel)
+                    l->fDel(v);
+                n++;
+            }
+        }
+        else {
+            pp = &(*pp)->next;
+        }
+    }
+    list_mutex_unlock(&l->mutex);
+    return(n);
+}
+
+
+int
+list_for_each (List l, ListForF f, void *arg)
+{
+    ListNode p;
+    int n = 0;
+
+    assert(l != NULL);
+    assert(f != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    for (p=l->head; p; p=p->next) {
+        n++;
+        if (f(p->data, arg) < 0) {
+            n = -n;
+            break;
+        }
+    }
+    list_mutex_unlock(&l->mutex);
+    return(n);
+}
+
+
+void
+list_sort (List l, ListCmpF f)
+{
+/*  Note: Time complexity O(n^2).
+ */
+    ListNode *pp, *ppPrev, *ppPos, pTmp;
+    ListIterator i;
+
+    assert(l != NULL);
+    assert(f != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    if (l->count > 1) {
+        ppPrev = &l->head;
+        pp = &(*ppPrev)->next;
+        while (*pp) {
+            if (f((*pp)->data, (*ppPrev)->data) < 0) {
+                ppPos = &l->head;
+                while (f((*pp)->data, (*ppPos)->data) >= 0)
+                    ppPos = &(*ppPos)->next;
+                pTmp = (*pp)->next;
+                (*pp)->next = *ppPos;
+                *ppPos = *pp;
+                *pp = pTmp;
+                if (ppPrev == ppPos)
+                    ppPrev = &(*ppPrev)->next;
+            }
+            else {
+                ppPrev = pp;
+                pp = &(*pp)->next;
+            }
+        }
+        l->tail = pp;
+
+        for (i=l->iNext; i; i=i->iNext) {
+            assert(i->magic == LIST_MAGIC);
+            i->pos = i->list->head;
+            i->prev = &i->list->head;
+        }
+    }
+    list_mutex_unlock(&l->mutex);
+    return;
+}
+
+
+void *
+list_push (List l, void *x)
+{
+    void *v;
+
+    assert(l != NULL);
+    assert(x != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_create(l, &l->head, x);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_pop (List l)
+{
+    void *v;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_destroy(l, &l->head);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_peek (List l)
+{
+    void *v;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = (l->head) ? l->head->data : NULL;
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_enqueue (List l, void *x)
+{
+    void *v;
+
+    assert(l != NULL);
+    assert(x != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_create(l, l->tail, x);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+void *
+list_dequeue (List l)
+{
+    void *v;
+
+    assert(l != NULL);
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    v = list_node_destroy(l, &l->head);
+    list_mutex_unlock(&l->mutex);
+    return(v);
+}
+
+
+ListIterator
+list_iterator_create (List l)
+{
+    ListIterator i;
+
+    assert(l != NULL);
+    if (!(i = list_iterator_alloc()))
+        return(lsd_nomem_error(__FILE__, __LINE__, "list iterator create"));
+    i->list = l;
+    list_mutex_lock(&l->mutex);
+    assert(l->magic == LIST_MAGIC);
+    i->pos = l->head;
+    i->prev = &l->head;
+    i->iNext = l->iNext;
+    l->iNext = i;
+    assert(i->magic = LIST_MAGIC);      /* set magic via assert abuse */
+    list_mutex_unlock(&l->mutex);
+    return(i);
+}
+
+
+void
+list_iterator_reset (ListIterator i)
+{
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    i->pos = i->list->head;
+    i->prev = &i->list->head;
+    list_mutex_unlock(&i->list->mutex);
+    return;
+}
+
+
+void
+list_iterator_destroy (ListIterator i)
+{
+    ListIterator *pi;
+
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    for (pi=&i->list->iNext; *pi; pi=&(*pi)->iNext) {
+        assert((*pi)->magic == LIST_MAGIC);
+        if (*pi == i) {
+            *pi = (*pi)->iNext;
+            break;
+        }
+    }
+    list_mutex_unlock(&i->list->mutex);
+    assert(i->magic = ~LIST_MAGIC);     /* clear magic via assert abuse */
+    list_iterator_free(i);
+    return;
+}
+
+
+void *
+list_next (ListIterator i)
+{
+    ListNode p;
+
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    if ((p = i->pos))
+        i->pos = p->next;
+    if (*i->prev != p)
+        i->prev = &(*i->prev)->next;
+    list_mutex_unlock(&i->list->mutex);
+    return(p ? p->data : NULL);
+}
+
+
+void *
+list_insert (ListIterator i, void *x)
+{
+    void *v;
+
+    assert(i != NULL);
+    assert(x != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    v = list_node_create(i->list, i->prev, x);
+    list_mutex_unlock(&i->list->mutex);
+    return(v);
+}
+
+
+void *
+list_find (ListIterator i, ListFindF f, void *key)
+{
+    void *v;
+
+    assert(i != NULL);
+    assert(f != NULL);
+    assert(i->magic == LIST_MAGIC);
+    while ((v=list_next(i)) && !f(v,key)) {;}
+    return(v);
+}
+
+
+void *
+list_remove (ListIterator i)
+{
+    void *v = NULL;
+
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    list_mutex_lock(&i->list->mutex);
+    assert(i->list->magic == LIST_MAGIC);
+    if (*i->prev != i->pos)
+        v = list_node_destroy(i->list, i->prev);
+    list_mutex_unlock(&i->list->mutex);
+    return(v);
+}
+
+
+int
+list_delete (ListIterator i)
+{
+    void *v;
+
+    assert(i != NULL);
+    assert(i->magic == LIST_MAGIC);
+    if ((v = list_remove(i))) {
+        if (i->list->fDel)
+            i->list->fDel(v);
+        return(1);
+    }
+    return(0);
+}
+
+
+static void *
+list_node_create (List l, ListNode *pp, void *x)
+{
+/*  Inserts data pointed to by [x] into list [l] after [pp],
+ *    the address of the previous node's "next" ptr.
+ *  Returns a ptr to data [x], or NULL if insertion fails.
+ *  This routine assumes the list is already locked upon entry.
+ */
+    ListNode p;
+    ListIterator i;
+
+    assert(l != NULL);
+    assert(l->magic == LIST_MAGIC);
+    assert(list_mutex_is_locked(&l->mutex));
+    assert(pp != NULL);
+    assert(x != NULL);
+    if (!(p = list_node_alloc()))
+        return(lsd_nomem_error(__FILE__, __LINE__, "list node create"));
+    p->data = x;
+    if (!(p->next = *pp))
+        l->tail = &p->next;
+    *pp = p;
+    l->count++;
+    for (i=l->iNext; i; i=i->iNext) {
+        assert(i->magic == LIST_MAGIC);
+        if (i->prev == pp)
+            i->prev = &p->next;
+        else if (i->pos == p->next)
+            i->pos = p;
+        assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next));
+    }
+    return(x);
+}
+
+
+static void *
+list_node_destroy (List l, ListNode *pp)
+{
+/*  Removes the node pointed to by [*pp] from from list [l],
+ *    where [pp] is the address of the previous node's "next" ptr.
+ *  Returns the data ptr associated with list item being removed,
+ *    or NULL if [*pp] points to the NULL element.
+ *  This routine assumes the list is already locked upon entry.
+ */
+    void *v;
+    ListNode p;
+    ListIterator i;
+
+    assert(l != NULL);
+    assert(l->magic == LIST_MAGIC);
+    assert(list_mutex_is_locked(&l->mutex));
+    assert(pp != NULL);
+    if (!(p = *pp))
+        return(NULL);
+    v = p->data;
+    if (!(*pp = p->next))
+        l->tail = pp;
+    l->count--;
+    for (i=l->iNext; i; i=i->iNext) {
+        assert(i->magic == LIST_MAGIC);
+        if (i->pos == p)
+            i->pos = p->next, i->prev = pp;
+        else if (i->prev == &p->next)
+            i->prev = pp;
+        assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next));
+    }
+    list_node_free(p);
+    return(v);
+}
+
+
+static List
+list_alloc (void)
+{
+    return(list_alloc_aux(sizeof(struct list), &list_free_lists));
+}
+
+
+static void
+list_free (List l)
+{
+    list_free_aux(l, &list_free_lists);
+    return;
+}
+
+
+static ListNode
+list_node_alloc (void)
+{
+    return(list_alloc_aux(sizeof(struct listNode), &list_free_nodes));
+}
+
+
+static void
+list_node_free (ListNode p)
+{
+    list_free_aux(p, &list_free_nodes);
+    return;
+}
+
+
+static ListIterator
+list_iterator_alloc (void)
+{
+    return(list_alloc_aux(sizeof(struct listIterator), &list_free_iterators));
+}
+
+
+static void
+list_iterator_free (ListIterator i)
+{
+    list_free_aux(i, &list_free_iterators);
+    return;
+}
+
+
+static void *
+list_alloc_aux (int size, void *pfreelist)
+{
+/*  Allocates an object of [size] bytes from the freelist [*pfreelist].
+ *  Memory is added to the freelist in chunks of size LIST_ALLOC.
+ *  Returns a ptr to the object, or NULL if the memory request fails.
+ */
+    void **px;
+    void **pfree = pfreelist;
+    void **plast;
+
+    assert(sizeof(char) == 1);
+    assert(size >= sizeof(void *));
+    assert(pfreelist != NULL);
+    assert(LIST_ALLOC > 0);
+    list_mutex_lock(&list_free_lock);
+    if (!*pfree) {
+        if ((*pfree = malloc(LIST_ALLOC * size))) {
+            px = *pfree;
+            plast = (void **) ((char *) *pfree + ((LIST_ALLOC - 1) * size));
+            while (px < plast)
+                *px = (char *) px + size, px = *px;
+            *plast = NULL;
+        }
+    }
+    if ((px = *pfree))
+        *pfree = *px;
+    else
+        errno = ENOMEM;
+    list_mutex_unlock(&list_free_lock);
+    return(px);
+}
+
+
+static void
+list_free_aux (void *x, void *pfreelist)
+{
+/*  Frees the object [x], returning it to the freelist [*pfreelist].
+ */
+    void **px = x;
+    void **pfree = pfreelist;
+
+    assert(x != NULL);
+    assert(pfreelist != NULL);
+    list_mutex_lock(&list_free_lock);
+    *px = *pfree;
+    *pfree = px;
+    list_mutex_unlock(&list_free_lock);
+    return;
+}
+
+
+#ifndef NDEBUG
+#ifdef WITH_PTHREADS
+static int
+list_mutex_is_locked (pthread_mutex_t *mutex)
+{
+/*  Returns true if the mutex is locked; o/w, returns false.
+ */
+    int rc;
+
+    assert(mutex != NULL);
+    rc = pthread_mutex_trylock(mutex);
+    return(rc == EBUSY ? 1 : 0);
+}
+#endif /* WITH_PTHREADS */
+#endif /* !NDEBUG */
index d052fc370151bbd44aff0ec6c93137ba5e392744..8a8674d6e6bc88477b4ae60360134bfc33af3d29 100644 (file)
@@ -5,8 +5,9 @@ MODULES := spl
 DISTFILES = Makefile.in \
             linux-kmem.c linux-rwlock.c linux-taskq.c linux-thread.c
 
+EXTRA_CFLAGS += -I$(src)
+
 # Removed '-std=gnu99' does to compile issues with i386 SPIN_LOCK_UNLOCKED
-# EXTRA_CFLAGS += -I$(src)
 # EXTRA_CFLAGS += -Wall -Wno-unknown-pragmas -Wno-missing-braces \
 #         -Wno-sign-compare -Wno-parentheses -Wno-uninitialized \
 #         -Wno-implicit-function-declaration -Wno-unused -Wno-trigraphs \
index 7de2b211d21fc7ad98ebc1eac7993e528ffcc1d1..e5ebdc17535e9d0e729a951075126eab4895341c 100644 (file)
@@ -1,4 +1,4 @@
-#include <sys/linux-kmem.h>
+#include "linux-kmem.h"
 
 /*
  * Memory allocation interfaces