diff --git a/share/man/man3/Makefile b/share/man/man3/Makefile index 446d0120f813..c654faffa6f7 100644 --- a/share/man/man3/Makefile +++ b/share/man/man3/Makefile @@ -110,6 +110,7 @@ MLINKS+= tree.3 RB_EMPTY.3 \ tree.3 RB_FIND.3 \ tree.3 RB_FOREACH.3 \ tree.3 RB_GENERATE.3 \ + tree.3 RB_GENERATE_STATIC.3 \ tree.3 RB_HEAD.3 \ tree.3 RB_INIT.3 \ tree.3 RB_INITIALIZER.3 \ @@ -121,6 +122,7 @@ MLINKS+= tree.3 RB_EMPTY.3 \ tree.3 RB_NFIND.3 \ tree.3 RB_PARENT.3 \ tree.3 RB_PROTOTYPE.3 \ + tree.3 RB_PROTOTYPE_STATIC.3 \ tree.3 RB_REMOVE.3 \ tree.3 RB_RIGHT.3 \ tree.3 RB_ROOT.3 \ diff --git a/share/man/man3/tree.3 b/share/man/man3/tree.3 index 77ab3686bbe3..78ba4b0c4621 100644 --- a/share/man/man3/tree.3 +++ b/share/man/man3/tree.3 @@ -30,7 +30,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 24, 2002 +.Dd January 17, 2006 .Dt TREE 3 .Os .Sh NAME @@ -52,7 +52,9 @@ .Nm SPLAY_INSERT , .Nm SPLAY_REMOVE , .Nm RB_PROTOTYPE , +.Nm RB_PROTOTYPE_STATIC , .Nm RB_GENERATE , +.Nm RB_GENERATE_STATIC , .Nm RB_ENTRY , .Nm RB_HEAD , .Nm RB_INITIALIZER , @@ -102,7 +104,9 @@ .Ft "struct TYPE *" .Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm" .Fn RB_PROTOTYPE NAME TYPE FIELD CMP +.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP .Fn RB_GENERATE NAME TYPE FIELD CMP +.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP .Fn RB_ENTRY TYPE .Fn RB_HEAD HEADNAME TYPE .Fn RB_INITIALIZER "RB_HEAD *head" @@ -156,14 +160,16 @@ The argument .Fa NAME has to be a unique name prefix for every tree that is defined. .Pp -The function prototypes are declared with either +The function prototypes are declared with .Fn SPLAY_PROTOTYPE , +.Fn RB_PROTOTYPE , or -.Fn RB_PROTOTYPE . -The function bodies are generated with either +.Fn RB_PROTOTYPE_STATIC . +The function bodies are generated with .Fn SPLAY_GENERATE , +.Fn RB_GENERATE , or -.Fn RB_GENERATE . +.Fn RB_GENERATE_STATIC . See the examples below for further explanation of how these macros are used. .Sh SPLAY TREES A splay tree is a self-organizing data structure. @@ -344,6 +350,8 @@ macro declares a structure that allows elements to be connected in the tree. In order to use the functions that manipulate the tree structure, their prototypes need to be declared with the .Fn RB_PROTOTYPE +or +.Fn RB_PROTOTYPE_STATIC macro, where .Fa NAME @@ -359,10 +367,14 @@ argument is the name of the element defined by .Pp The function bodies are generated with the .Fn RB_GENERATE +or +.Fn RB_GENERATE_STATIC macro. -It takes the same arguments as the +These macros take the same arguments as the .Fn RB_PROTOTYPE -macro, but should be used only once. +and +.Fn RB_PROTOTYPE_STATIC +macros, but should be used only once. .Pp Finally, the diff --git a/sys/sys/tree.h b/sys/sys/tree.h index 47fd098cac47..c2157eea488a 100644 --- a/sys/sys/tree.h +++ b/sys/sys/tree.h @@ -30,6 +30,8 @@ #ifndef _SYS_TREE_H_ #define _SYS_TREE_H_ +#include + /* * This file defines data structures for different types of trees: * splay trees and red-black trees. @@ -376,22 +378,30 @@ struct { \ } while (/*CONSTCOND*/ 0) /* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ -void name##_RB_INSERT_COLOR(struct name *, struct type *); \ -void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ -struct type *name##_RB_REMOVE(struct name *, struct type *); \ -struct type *name##_RB_INSERT(struct name *, struct type *); \ -struct type *name##_RB_FIND(struct name *, struct type *); \ -struct type *name##_RB_NFIND(struct name *, struct type *); \ -struct type *name##_RB_NEXT(struct type *); \ -struct type *name##_RB_MINMAX(struct name *, int); \ +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ +attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ +attr struct type *name##_RB_INSERT(struct name *, struct type *); \ +attr struct type *name##_RB_FIND(struct name *, struct type *); \ +attr struct type *name##_RB_NFIND(struct name *, struct type *); \ +attr struct type *name##_RB_NEXT(struct type *); \ +attr struct type *name##_RB_MINMAX(struct name *, int); \ \ /* Main rb operation. * Moves node close to the key of elm to top */ -#define RB_GENERATE(name, type, field, cmp) \ -void \ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ +attr void \ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ { \ struct type *parent, *gparent, *tmp; \ @@ -435,7 +445,7 @@ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ RB_COLOR(head->rbh_root, field) = RB_BLACK; \ } \ \ -void \ +attr void \ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ { \ struct type *tmp; \ @@ -513,7 +523,7 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) RB_COLOR(elm, field) = RB_BLACK; \ } \ \ -struct type * \ +attr struct type * \ name##_RB_REMOVE(struct name *head, struct type *elm) \ { \ struct type *child, *parent, *old = elm; \ @@ -581,7 +591,7 @@ color: \ } \ \ /* Inserts a node into the RB tree */ \ -struct type * \ +attr struct type * \ name##_RB_INSERT(struct name *head, struct type *elm) \ { \ struct type *tmp; \ @@ -612,7 +622,7 @@ name##_RB_INSERT(struct name *head, struct type *elm) \ } \ \ /* Finds the node with the same key as elm */ \ -struct type * \ +attr struct type * \ name##_RB_FIND(struct name *head, struct type *elm) \ { \ struct type *tmp = RB_ROOT(head); \ @@ -630,7 +640,7 @@ name##_RB_FIND(struct name *head, struct type *elm) \ } \ \ /* Finds the first node greater than or equal to the search key */ \ -struct type * \ +attr struct type * \ name##_RB_NFIND(struct name *head, struct type *elm) \ { \ struct type *ret = RB_ROOT(head); \ @@ -659,7 +669,7 @@ name##_RB_NFIND(struct name *head, struct type *elm) \ } \ \ /* ARGSUSED */ \ -struct type * \ +attr struct type * \ name##_RB_NEXT(struct type *elm) \ { \ if (RB_RIGHT(elm, field)) { \ @@ -680,7 +690,7 @@ name##_RB_NEXT(struct type *elm) \ return (elm); \ } \ \ -struct type * \ +attr struct type * \ name##_RB_MINMAX(struct name *head, int val) \ { \ struct type *tmp = RB_ROOT(head); \