musl: install a few extra headers to improve compatibility with various packages
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 41056
This commit is contained in:
		| @@ -25,6 +25,7 @@ endef | ||||
| define Host/Install | ||||
| 	$(call Host/SetToolchainInfo) | ||||
| 	$(MAKE) $(MUSL_MAKEOPTS) DESTDIR="$(TOOLCHAIN_DIR)/" install | ||||
| 	$(CP) ./include $(TOOLCHAIN_DIR)/ | ||||
| endef | ||||
|  | ||||
| $(eval $(call HostBuild)) | ||||
|   | ||||
							
								
								
									
										1
									
								
								toolchain/musl/include/bits/wordsize.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								toolchain/musl/include/bits/wordsize.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| #include <sys/user.h> | ||||
							
								
								
									
										56
									
								
								toolchain/musl/include/features.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								toolchain/musl/include/features.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| #ifndef _FEATURES_H | ||||
| #define _FEATURES_H | ||||
|  | ||||
| #ifdef _ALL_SOURCE | ||||
| #define _GNU_SOURCE 1 | ||||
| #endif | ||||
|  | ||||
| #if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \ | ||||
|  && !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \ | ||||
|  && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__) | ||||
| #define _BSD_SOURCE 1 | ||||
| #define _XOPEN_SOURCE 700 | ||||
| #endif | ||||
|  | ||||
| #if __STDC_VERSION__ >= 199901L | ||||
| #define __restrict restrict | ||||
| #elif !defined(__GNUC__) | ||||
| #define __restrict | ||||
| #endif | ||||
|  | ||||
| #if __STDC_VERSION__ >= 199901L || defined(__cplusplus) | ||||
| #define __inline inline | ||||
| #endif | ||||
|  | ||||
| #if __STDC_VERSION__ >= 201112L | ||||
| #elif defined(__GNUC__) | ||||
| #define _Noreturn __attribute__((__noreturn__)) | ||||
| #else | ||||
| #define _Noreturn | ||||
| #endif | ||||
|  | ||||
| /* Convenience macros to test the versions of glibc and gcc. | ||||
|    Use them like this: | ||||
|    #if __GNUC_PREREQ (2,8) | ||||
|    ... code requiring gcc 2.8 or later ... | ||||
|    #endif | ||||
|    Note - they won't work for gcc1 or glibc1, since the _MINOR macros | ||||
|    were not defined then.  */ | ||||
| #if defined __GNUC__ && defined __GNUC_MINOR__ | ||||
| # define __GNUC_PREREQ(maj, min) \ | ||||
| 	((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) | ||||
| #else | ||||
| # define __GNUC_PREREQ(maj, min) 0 | ||||
| #endif | ||||
|  | ||||
| #if !defined __FORCE_NOGLIBC && (!defined _LIBC || defined __FORCE_GLIBC) | ||||
| #undef __GNU_LIBRARY__ | ||||
| #define __GNU_LIBRARY__ 6 | ||||
|  | ||||
| #define __GLIBC__ 2 | ||||
| #define __GLIBC_MINOR__ 16 | ||||
| #endif | ||||
|  | ||||
| #include <sys/glibc-types.h> | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										378
									
								
								toolchain/musl/include/sys/cdefs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								toolchain/musl/include/sys/cdefs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,378 @@ | ||||
| /* Copyright (C) 1992-2002, 2004, 2005, 2006, 2007, 2009, 2011, 2012 | ||||
|    Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C Library is free software; you can redistribute it and/or | ||||
|    modify it under the terms of the GNU Lesser General Public | ||||
|    License as published by the Free Software Foundation; either | ||||
|    version 2.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C Library 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 | ||||
|    Lesser General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU Lesser General Public | ||||
|    License along with the GNU C Library; if not, see | ||||
|    <http://www.gnu.org/licenses/>.  */ | ||||
|  | ||||
| #ifndef	_SYS_CDEFS_H | ||||
| #define	_SYS_CDEFS_H	1 | ||||
|  | ||||
| /* We are almost always included from features.h. */ | ||||
| #ifndef _FEATURES_H | ||||
| # include <features.h> | ||||
| #endif | ||||
|  | ||||
| /* The GNU libc does not support any K&R compilers or the traditional mode | ||||
|    of ISO C compilers anymore.  Check for some of the combinations not | ||||
|    anymore supported.  */ | ||||
| #if defined __GNUC__ && !defined __STDC__ | ||||
| # error "You need a ISO C conforming compiler to use the glibc headers" | ||||
| #endif | ||||
|  | ||||
| /* Some user header file might have defined this before.  */ | ||||
| #undef	__P | ||||
| #undef	__PMT | ||||
|  | ||||
| #ifdef __GNUC__ | ||||
|  | ||||
| /* All functions, except those with callbacks or those that | ||||
|    synchronize memory, are leaf functions.  */ | ||||
| # if __GNUC_PREREQ (4, 6) && !defined _LIBC | ||||
| #  define __LEAF , __leaf__ | ||||
| #  define __LEAF_ATTR __attribute__ ((__leaf__)) | ||||
| # else | ||||
| #  define __LEAF | ||||
| #  define __LEAF_ATTR | ||||
| # endif | ||||
|  | ||||
| /* GCC can always grok prototypes.  For C++ programs we add throw() | ||||
|    to help it optimize the function calls.  But this works only with | ||||
|    gcc 2.8.x and egcs.  For gcc 3.2 and up we even mark C functions | ||||
|    as non-throwing using a function attribute since programs can use | ||||
|    the -fexceptions options for C code as well.  */ | ||||
| # if !defined __cplusplus && __GNUC_PREREQ (3, 3) | ||||
| #  define __THROW	__attribute__ ((__nothrow__ __LEAF)) | ||||
| #  define __THROWNL	__attribute__ ((__nothrow__)) | ||||
| #  define __NTH(fct)	__attribute__ ((__nothrow__ __LEAF)) fct | ||||
| # else | ||||
| #  if defined __cplusplus && __GNUC_PREREQ (2,8) | ||||
| #   define __THROW	throw () | ||||
| #   define __THROWNL	throw () | ||||
| #   define __NTH(fct)	__LEAF_ATTR fct throw () | ||||
| #  else | ||||
| #   define __THROW | ||||
| #   define __THROWNL | ||||
| #   define __NTH(fct)	fct | ||||
| #  endif | ||||
| # endif | ||||
|  | ||||
| #else	/* Not GCC.  */ | ||||
|  | ||||
| # define __inline		/* No inline functions.  */ | ||||
|  | ||||
| # define __THROW | ||||
| # define __THROWNL | ||||
| # define __NTH(fct)	fct | ||||
|  | ||||
| #endif	/* GCC.  */ | ||||
|  | ||||
| /* These two macros are not used in glibc anymore.  They are kept here | ||||
|    only because some other projects expect the macros to be defined.  */ | ||||
| #define __P(args)	args | ||||
| #define __PMT(args)	args | ||||
|  | ||||
| /* For these things, GCC behaves the ANSI way normally, | ||||
|    and the non-ANSI way under -traditional.  */ | ||||
|  | ||||
| #define __CONCAT(x,y)	x ## y | ||||
| #define __STRING(x)	#x | ||||
|  | ||||
| /* This is not a typedef so `const __ptr_t' does the right thing.  */ | ||||
| #define __ptr_t void * | ||||
| #define __long_double_t  long double | ||||
|  | ||||
|  | ||||
| /* C++ needs to know that types and declarations are C, not C++.  */ | ||||
| #ifdef	__cplusplus | ||||
| # define __BEGIN_DECLS	extern "C" { | ||||
| # define __END_DECLS	} | ||||
| #else | ||||
| # define __BEGIN_DECLS | ||||
| # define __END_DECLS | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* The standard library needs the functions from the ISO C90 standard | ||||
|    in the std namespace.  At the same time we want to be safe for | ||||
|    future changes and we include the ISO C99 code in the non-standard | ||||
|    namespace __c99.  The C++ wrapper header take case of adding the | ||||
|    definitions to the global namespace.  */ | ||||
| #if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES | ||||
| # define __BEGIN_NAMESPACE_STD	namespace std { | ||||
| # define __END_NAMESPACE_STD	} | ||||
| # define __USING_NAMESPACE_STD(name) using std::name; | ||||
| # define __BEGIN_NAMESPACE_C99	namespace __c99 { | ||||
| # define __END_NAMESPACE_C99	} | ||||
| # define __USING_NAMESPACE_C99(name) using __c99::name; | ||||
| #else | ||||
| /* For compatibility we do not add the declarations into any | ||||
|    namespace.  They will end up in the global namespace which is what | ||||
|    old code expects.  */ | ||||
| # define __BEGIN_NAMESPACE_STD | ||||
| # define __END_NAMESPACE_STD | ||||
| # define __USING_NAMESPACE_STD(name) | ||||
| # define __BEGIN_NAMESPACE_C99 | ||||
| # define __END_NAMESPACE_C99 | ||||
| # define __USING_NAMESPACE_C99(name) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* Support for bounded pointers.  */ | ||||
| #ifndef __BOUNDED_POINTERS__ | ||||
| # define __bounded	/* nothing */ | ||||
| # define __unbounded	/* nothing */ | ||||
| # define __ptrvalue	/* nothing */ | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* Fortify support.  */ | ||||
| #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) | ||||
| #define __bos0(ptr) __builtin_object_size (ptr, 0) | ||||
| #define __fortify_function __extern_always_inline __attribute_artificial__ | ||||
|  | ||||
| #if __GNUC_PREREQ (4,3) | ||||
| # define __warndecl(name, msg) \ | ||||
|   extern void name (void) __attribute__((__warning__ (msg))) | ||||
| # define __warnattr(msg) __attribute__((__warning__ (msg))) | ||||
| # define __errordecl(name, msg) \ | ||||
|   extern void name (void) __attribute__((__error__ (msg))) | ||||
| #else | ||||
| # define __warndecl(name, msg) extern void name (void) | ||||
| # define __warnattr(msg) | ||||
| # define __errordecl(name, msg) extern void name (void) | ||||
| #endif | ||||
|  | ||||
| /* Support for flexible arrays.  */ | ||||
| #if __GNUC_PREREQ (2,97) | ||||
| /* GCC 2.97 supports C99 flexible array members.  */ | ||||
| # define __flexarr	[] | ||||
| #else | ||||
| # ifdef __GNUC__ | ||||
| #  define __flexarr	[0] | ||||
| # else | ||||
| #  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L | ||||
| #   define __flexarr	[] | ||||
| #  else | ||||
| /* Some other non-C99 compiler.  Approximate with [1].  */ | ||||
| #   define __flexarr	[1] | ||||
| #  endif | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* __asm__ ("xyz") is used throughout the headers to rename functions | ||||
|    at the assembly language level.  This is wrapped by the __REDIRECT | ||||
|    macro, in order to support compilers that can do this some other | ||||
|    way.  When compilers don't support asm-names at all, we have to do | ||||
|    preprocessor tricks instead (which don't have exactly the right | ||||
|    semantics, but it's the best we can do). | ||||
|  | ||||
|    Example: | ||||
|    int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */ | ||||
|  | ||||
| #if defined __GNUC__ && __GNUC__ >= 2 | ||||
|  | ||||
| # define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias)) | ||||
| # ifdef __cplusplus | ||||
| #  define __REDIRECT_NTH(name, proto, alias) \ | ||||
|      name proto __THROW __asm__ (__ASMNAME (#alias)) | ||||
| #  define __REDIRECT_NTHNL(name, proto, alias) \ | ||||
|      name proto __THROWNL __asm__ (__ASMNAME (#alias)) | ||||
| # else | ||||
| #  define __REDIRECT_NTH(name, proto, alias) \ | ||||
|      name proto __asm__ (__ASMNAME (#alias)) __THROW | ||||
| #  define __REDIRECT_NTHNL(name, proto, alias) \ | ||||
|      name proto __asm__ (__ASMNAME (#alias)) __THROWNL | ||||
| # endif | ||||
| # define __ASMNAME(cname)  __ASMNAME2 (__USER_LABEL_PREFIX__, cname) | ||||
| # define __ASMNAME2(prefix, cname) __STRING (prefix) cname | ||||
|  | ||||
| /* | ||||
| #elif __SOME_OTHER_COMPILER__ | ||||
|  | ||||
| # define __REDIRECT(name, proto, alias) name proto; \ | ||||
| 	_Pragma("let " #name " = " #alias) | ||||
| */ | ||||
| #endif | ||||
|  | ||||
| /* GCC has various useful declarations that can be made with the | ||||
|    `__attribute__' syntax.  All of the ways we use this do fine if | ||||
|    they are omitted for compilers that don't understand it. */ | ||||
| #if !defined __GNUC__ || __GNUC__ < 2 | ||||
| # define __attribute__(xyz)	/* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* At some point during the gcc 2.96 development the `malloc' attribute | ||||
|    for functions was introduced.  We don't want to use it unconditionally | ||||
|    (although this would be possible) since it generates warnings.  */ | ||||
| #if __GNUC_PREREQ (2,96) | ||||
| # define __attribute_malloc__ __attribute__ ((__malloc__)) | ||||
| #else | ||||
| # define __attribute_malloc__ /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* At some point during the gcc 2.96 development the `pure' attribute | ||||
|    for functions was introduced.  We don't want to use it unconditionally | ||||
|    (although this would be possible) since it generates warnings.  */ | ||||
| #if __GNUC_PREREQ (2,96) | ||||
| # define __attribute_pure__ __attribute__ ((__pure__)) | ||||
| #else | ||||
| # define __attribute_pure__ /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* This declaration tells the compiler that the value is constant.  */ | ||||
| #if __GNUC_PREREQ (2,5) | ||||
| # define __attribute_const__ __attribute__ ((__const__)) | ||||
| #else | ||||
| # define __attribute_const__ /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* At some point during the gcc 3.1 development the `used' attribute | ||||
|    for functions was introduced.  We don't want to use it unconditionally | ||||
|    (although this would be possible) since it generates warnings.  */ | ||||
| #if __GNUC_PREREQ (3,1) | ||||
| # define __attribute_used__ __attribute__ ((__used__)) | ||||
| # define __attribute_noinline__ __attribute__ ((__noinline__)) | ||||
| #else | ||||
| # define __attribute_used__ __attribute__ ((__unused__)) | ||||
| # define __attribute_noinline__ /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* gcc allows marking deprecated functions.  */ | ||||
| #if __GNUC_PREREQ (3,2) | ||||
| # define __attribute_deprecated__ __attribute__ ((__deprecated__)) | ||||
| #else | ||||
| # define __attribute_deprecated__ /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* At some point during the gcc 2.8 development the `format_arg' attribute | ||||
|    for functions was introduced.  We don't want to use it unconditionally | ||||
|    (although this would be possible) since it generates warnings. | ||||
|    If several `format_arg' attributes are given for the same function, in | ||||
|    gcc-3.0 and older, all but the last one are ignored.  In newer gccs, | ||||
|    all designated arguments are considered.  */ | ||||
| #if __GNUC_PREREQ (2,8) | ||||
| # define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x))) | ||||
| #else | ||||
| # define __attribute_format_arg__(x) /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* At some point during the gcc 2.97 development the `strfmon' format | ||||
|    attribute for functions was introduced.  We don't want to use it | ||||
|    unconditionally (although this would be possible) since it | ||||
|    generates warnings.  */ | ||||
| #if __GNUC_PREREQ (2,97) | ||||
| # define __attribute_format_strfmon__(a,b) \ | ||||
|   __attribute__ ((__format__ (__strfmon__, a, b))) | ||||
| #else | ||||
| # define __attribute_format_strfmon__(a,b) /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* The nonull function attribute allows to mark pointer parameters which | ||||
|    must not be NULL.  */ | ||||
| #if __GNUC_PREREQ (3,3) | ||||
| # define __nonnull(params) __attribute__ ((__nonnull__ params)) | ||||
| #else | ||||
| # define __nonnull(params) | ||||
| #endif | ||||
|  | ||||
| /* If fortification mode, we warn about unused results of certain | ||||
|    function calls which can lead to problems.  */ | ||||
| #if __GNUC_PREREQ (3,4) | ||||
| # define __attribute_warn_unused_result__ \ | ||||
|    __attribute__ ((__warn_unused_result__)) | ||||
| # if __USE_FORTIFY_LEVEL > 0 | ||||
| #  define __wur __attribute_warn_unused_result__ | ||||
| # endif | ||||
| #else | ||||
| # define __attribute_warn_unused_result__ /* empty */ | ||||
| #endif | ||||
| #ifndef __wur | ||||
| # define __wur /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* Forces a function to be always inlined.  */ | ||||
| #if __GNUC_PREREQ (3,2) | ||||
| # define __always_inline __inline __attribute__ ((__always_inline__)) | ||||
| #else | ||||
| # define __always_inline __inline | ||||
| #endif | ||||
|  | ||||
| /* Associate error messages with the source location of the call site rather | ||||
|    than with the source location inside the function.  */ | ||||
| #if __GNUC_PREREQ (4,3) | ||||
| # define __attribute_artificial__ __attribute__ ((__artificial__)) | ||||
| #else | ||||
| # define __attribute_artificial__ /* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 | ||||
|    inline semantics, unless -fgnu89-inline is used.  */ | ||||
| #if !defined __cplusplus || __GNUC_PREREQ (4,3) | ||||
| # if defined __GNUC_STDC_INLINE__ || defined __cplusplus | ||||
| #  define __extern_inline extern __inline __attribute__ ((__gnu_inline__)) | ||||
| #  define __extern_always_inline \ | ||||
|   extern __always_inline __attribute__ ((__gnu_inline__)) | ||||
| # else | ||||
| #  define __extern_inline extern __inline | ||||
| #  define __extern_always_inline extern __always_inline | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
| /* GCC 4.3 and above allow passing all anonymous arguments of an | ||||
|    __extern_always_inline function to some other vararg function.  */ | ||||
| #if __GNUC_PREREQ (4,3) | ||||
| # define __va_arg_pack() __builtin_va_arg_pack () | ||||
| # define __va_arg_pack_len() __builtin_va_arg_pack_len () | ||||
| #endif | ||||
|  | ||||
| /* It is possible to compile containing GCC extensions even if GCC is | ||||
|    run in pedantic mode if the uses are carefully marked using the | ||||
|    `__extension__' keyword.  But this is not generally available before | ||||
|    version 2.8.  */ | ||||
| #if !__GNUC_PREREQ (2,8) | ||||
| # define __extension__		/* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* __restrict is known in EGCS 1.2 and above. */ | ||||
| #if !__GNUC_PREREQ (2,92) | ||||
| # define __restrict	/* Ignore */ | ||||
| #endif | ||||
|  | ||||
| /* ISO C99 also allows to declare arrays as non-overlapping.  The syntax is | ||||
|      array_name[restrict] | ||||
|    GCC 3.1 supports this.  */ | ||||
| #if __GNUC_PREREQ (3,1) && !defined __GNUG__ | ||||
| # define __restrict_arr	__restrict | ||||
| #else | ||||
| # ifdef __GNUC__ | ||||
| #  define __restrict_arr	/* Not supported in old GCC.  */ | ||||
| # else | ||||
| #  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L | ||||
| #   define __restrict_arr	restrict | ||||
| #  else | ||||
| /* Some other non-C99 compiler.  */ | ||||
| #   define __restrict_arr	/* Not supported.  */ | ||||
| #  endif | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
| #if __GNUC__ >= 3 | ||||
| # define __glibc_unlikely(cond) __builtin_expect((cond), 0) | ||||
| #else | ||||
| # define __glibc_unlikely(cond) (cond) | ||||
| #endif | ||||
|  | ||||
| #endif	 /* sys/cdefs.h */ | ||||
							
								
								
									
										29
									
								
								toolchain/musl/include/sys/glibc-types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								toolchain/musl/include/sys/glibc-types.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #ifndef __MUSL_GLIBC_TYPES_H | ||||
| #define __MUSL_GLIBC_TYPES_H | ||||
|  | ||||
| /* Convenience types.  */ | ||||
| typedef unsigned char __u_char; | ||||
| typedef unsigned short int __u_short; | ||||
| typedef unsigned int __u_int; | ||||
| typedef unsigned long int __u_long; | ||||
|  | ||||
| /* Fixed-size types, underlying types depend on word size and compiler.  */ | ||||
| typedef signed char __int8_t; | ||||
| typedef unsigned char __uint8_t; | ||||
| typedef signed short int __int16_t; | ||||
| typedef unsigned short int __uint16_t; | ||||
| typedef signed int __int32_t; | ||||
| typedef unsigned int __uint32_t; | ||||
| #if __WORDSIZE == 64 | ||||
| typedef signed long int __int64_t; | ||||
| typedef unsigned long int __uint64_t; | ||||
| #else | ||||
| __extension__ typedef signed long long int __int64_t; | ||||
| __extension__ typedef unsigned long long int __uint64_t; | ||||
| #endif | ||||
|  | ||||
| #define __off64_t off_t | ||||
| #define __loff_t off_t | ||||
| typedef char *__caddr_t; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										574
									
								
								toolchain/musl/include/sys/queue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										574
									
								
								toolchain/musl/include/sys/queue.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,574 @@ | ||||
| /* | ||||
|  * Copyright (c) 1991, 1993 | ||||
|  *	The Regents of the University of California.  All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * 3. Neither the name of the University nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  * | ||||
|  *	@(#)queue.h	8.5 (Berkeley) 8/20/94 | ||||
|  */ | ||||
|  | ||||
| #ifndef	_SYS_QUEUE_H_ | ||||
| #define	_SYS_QUEUE_H_ | ||||
|  | ||||
| /* | ||||
|  * This file defines five types of data structures: singly-linked lists, | ||||
|  * lists, simple queues, tail queues, and circular queues. | ||||
|  * | ||||
|  * A singly-linked list is headed by a single forward pointer. The | ||||
|  * elements are singly linked for minimum space and pointer manipulation | ||||
|  * overhead at the expense of O(n) removal for arbitrary elements. New | ||||
|  * elements can be added to the list after an existing element or at the | ||||
|  * head of the list.  Elements being removed from the head of the list | ||||
|  * should use the explicit macro for this purpose for optimum | ||||
|  * efficiency. A singly-linked list may only be traversed in the forward | ||||
|  * direction.  Singly-linked lists are ideal for applications with large | ||||
|  * datasets and few or no removals or for implementing a LIFO queue. | ||||
|  * | ||||
|  * A list is headed by a single forward pointer (or an array of forward | ||||
|  * pointers for a hash table header). The elements are doubly linked | ||||
|  * so that an arbitrary element can be removed without a need to | ||||
|  * traverse the list. New elements can be added to the list before | ||||
|  * or after an existing element or at the head of the list. A list | ||||
|  * may only be traversed in the forward direction. | ||||
|  * | ||||
|  * A simple queue is headed by a pair of pointers, one the head of the | ||||
|  * list and the other to the tail of the list. The elements are singly | ||||
|  * linked to save space, so elements can only be removed from the | ||||
|  * head of the list. New elements can be added to the list after | ||||
|  * an existing element, at the head of the list, or at the end of the | ||||
|  * list. A simple queue may only be traversed in the forward direction. | ||||
|  * | ||||
|  * A tail queue is headed by a pair of pointers, one to the head of the | ||||
|  * list and the other to the tail of the list. The elements are doubly | ||||
|  * linked so that an arbitrary element can be removed without a need to | ||||
|  * traverse the list. New elements can be added to the list before or | ||||
|  * after an existing element, at the head of the list, or at the end of | ||||
|  * the list. A tail queue may be traversed in either direction. | ||||
|  * | ||||
|  * A circle queue is headed by a pair of pointers, one to the head of the | ||||
|  * list and the other to the tail of the list. The elements are doubly | ||||
|  * linked so that an arbitrary element can be removed without a need to | ||||
|  * traverse the list. New elements can be added to the list before or after | ||||
|  * an existing element, at the head of the list, or at the end of the list. | ||||
|  * A circle queue may be traversed in either direction, but has a more | ||||
|  * complex end of list detection. | ||||
|  * | ||||
|  * For details on the use of these macros, see the queue(3) manual page. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * List definitions. | ||||
|  */ | ||||
| #define	LIST_HEAD(name, type)						\ | ||||
| struct name {								\ | ||||
| 	struct type *lh_first;	/* first element */			\ | ||||
| } | ||||
|  | ||||
| #define	LIST_HEAD_INITIALIZER(head)					\ | ||||
| 	{ NULL } | ||||
|  | ||||
| #define	LIST_ENTRY(type)						\ | ||||
| struct {								\ | ||||
| 	struct type *le_next;	/* next element */			\ | ||||
| 	struct type **le_prev;	/* address of previous next element */	\ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * List functions. | ||||
|  */ | ||||
| #define	LIST_INIT(head) do {						\ | ||||
| 	(head)->lh_first = NULL;					\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	LIST_INSERT_AFTER(listelm, elm, field) do {			\ | ||||
| 	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\ | ||||
| 		(listelm)->field.le_next->field.le_prev =		\ | ||||
| 		    &(elm)->field.le_next;				\ | ||||
| 	(listelm)->field.le_next = (elm);				\ | ||||
| 	(elm)->field.le_prev = &(listelm)->field.le_next;		\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\ | ||||
| 	(elm)->field.le_prev = (listelm)->field.le_prev;		\ | ||||
| 	(elm)->field.le_next = (listelm);				\ | ||||
| 	*(listelm)->field.le_prev = (elm);				\ | ||||
| 	(listelm)->field.le_prev = &(elm)->field.le_next;		\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	LIST_INSERT_HEAD(head, elm, field) do {				\ | ||||
| 	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\ | ||||
| 		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\ | ||||
| 	(head)->lh_first = (elm);					\ | ||||
| 	(elm)->field.le_prev = &(head)->lh_first;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	LIST_REMOVE(elm, field) do {					\ | ||||
| 	if ((elm)->field.le_next != NULL)				\ | ||||
| 		(elm)->field.le_next->field.le_prev = 			\ | ||||
| 		    (elm)->field.le_prev;				\ | ||||
| 	*(elm)->field.le_prev = (elm)->field.le_next;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	LIST_FOREACH(var, head, field)					\ | ||||
| 	for ((var) = ((head)->lh_first);				\ | ||||
| 		(var);							\ | ||||
| 		(var) = ((var)->field.le_next)) | ||||
|  | ||||
| /* | ||||
|  * List access methods. | ||||
|  */ | ||||
| #define	LIST_EMPTY(head)		((head)->lh_first == NULL) | ||||
| #define	LIST_FIRST(head)		((head)->lh_first) | ||||
| #define	LIST_NEXT(elm, field)		((elm)->field.le_next) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Singly-linked List definitions. | ||||
|  */ | ||||
| #define	SLIST_HEAD(name, type)						\ | ||||
| struct name {								\ | ||||
| 	struct type *slh_first;	/* first element */			\ | ||||
| } | ||||
|  | ||||
| #define	SLIST_HEAD_INITIALIZER(head)					\ | ||||
| 	{ NULL } | ||||
|  | ||||
| #define	SLIST_ENTRY(type)						\ | ||||
| struct {								\ | ||||
| 	struct type *sle_next;	/* next element */			\ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Singly-linked List functions. | ||||
|  */ | ||||
| #define	SLIST_INIT(head) do {						\ | ||||
| 	(head)->slh_first = NULL;					\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\ | ||||
| 	(elm)->field.sle_next = (slistelm)->field.sle_next;		\ | ||||
| 	(slistelm)->field.sle_next = (elm);				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SLIST_INSERT_HEAD(head, elm, field) do {			\ | ||||
| 	(elm)->field.sle_next = (head)->slh_first;			\ | ||||
| 	(head)->slh_first = (elm);					\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SLIST_REMOVE_HEAD(head, field) do {				\ | ||||
| 	(head)->slh_first = (head)->slh_first->field.sle_next;		\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SLIST_REMOVE(head, elm, type, field) do {			\ | ||||
| 	if ((head)->slh_first == (elm)) {				\ | ||||
| 		SLIST_REMOVE_HEAD((head), field);			\ | ||||
| 	}								\ | ||||
| 	else {								\ | ||||
| 		struct type *curelm = (head)->slh_first;		\ | ||||
| 		while(curelm->field.sle_next != (elm))			\ | ||||
| 			curelm = curelm->field.sle_next;		\ | ||||
| 		curelm->field.sle_next =				\ | ||||
| 		    curelm->field.sle_next->field.sle_next;		\ | ||||
| 	}								\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SLIST_FOREACH(var, head, field)					\ | ||||
| 	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) | ||||
|  | ||||
| /* | ||||
|  * Singly-linked List access methods. | ||||
|  */ | ||||
| #define	SLIST_EMPTY(head)	((head)->slh_first == NULL) | ||||
| #define	SLIST_FIRST(head)	((head)->slh_first) | ||||
| #define	SLIST_NEXT(elm, field)	((elm)->field.sle_next) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Singly-linked Tail queue declarations. | ||||
|  */ | ||||
| #define	STAILQ_HEAD(name, type)					\ | ||||
| struct name {								\ | ||||
| 	struct type *stqh_first;	/* first element */			\ | ||||
| 	struct type **stqh_last;	/* addr of last next element */		\ | ||||
| } | ||||
|  | ||||
| #define	STAILQ_HEAD_INITIALIZER(head)					\ | ||||
| 	{ NULL, &(head).stqh_first } | ||||
|  | ||||
| #define	STAILQ_ENTRY(type)						\ | ||||
| struct {								\ | ||||
| 	struct type *stqe_next;	/* next element */			\ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Singly-linked Tail queue functions. | ||||
|  */ | ||||
| #define	STAILQ_INIT(head) do {						\ | ||||
| 	(head)->stqh_first = NULL;					\ | ||||
| 	(head)->stqh_last = &(head)->stqh_first;				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	STAILQ_INSERT_HEAD(head, elm, field) do {			\ | ||||
| 	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\ | ||||
| 		(head)->stqh_last = &(elm)->field.stqe_next;		\ | ||||
| 	(head)->stqh_first = (elm);					\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	STAILQ_INSERT_TAIL(head, elm, field) do {			\ | ||||
| 	(elm)->field.stqe_next = NULL;					\ | ||||
| 	*(head)->stqh_last = (elm);					\ | ||||
| 	(head)->stqh_last = &(elm)->field.stqe_next;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\ | ||||
| 	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\ | ||||
| 		(head)->stqh_last = &(elm)->field.stqe_next;		\ | ||||
| 	(listelm)->field.stqe_next = (elm);				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	STAILQ_REMOVE_HEAD(head, field) do {				\ | ||||
| 	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \ | ||||
| 		(head)->stqh_last = &(head)->stqh_first;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	STAILQ_REMOVE(head, elm, type, field) do {			\ | ||||
| 	if ((head)->stqh_first == (elm)) {				\ | ||||
| 		STAILQ_REMOVE_HEAD((head), field);			\ | ||||
| 	} else {							\ | ||||
| 		struct type *curelm = (head)->stqh_first;		\ | ||||
| 		while (curelm->field.stqe_next != (elm))			\ | ||||
| 			curelm = curelm->field.stqe_next;		\ | ||||
| 		if ((curelm->field.stqe_next =				\ | ||||
| 			curelm->field.stqe_next->field.stqe_next) == NULL) \ | ||||
| 			    (head)->stqh_last = &(curelm)->field.stqe_next; \ | ||||
| 	}								\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	STAILQ_FOREACH(var, head, field)				\ | ||||
| 	for ((var) = ((head)->stqh_first);				\ | ||||
| 		(var);							\ | ||||
| 		(var) = ((var)->field.stqe_next)) | ||||
|  | ||||
| #define	STAILQ_CONCAT(head1, head2) do {				\ | ||||
| 	if (!STAILQ_EMPTY((head2))) {					\ | ||||
| 		*(head1)->stqh_last = (head2)->stqh_first;		\ | ||||
| 		(head1)->stqh_last = (head2)->stqh_last;		\ | ||||
| 		STAILQ_INIT((head2));					\ | ||||
| 	}								\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| /* | ||||
|  * Singly-linked Tail queue access methods. | ||||
|  */ | ||||
| #define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL) | ||||
| #define	STAILQ_FIRST(head)	((head)->stqh_first) | ||||
| #define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Simple queue definitions. | ||||
|  */ | ||||
| #define	SIMPLEQ_HEAD(name, type)					\ | ||||
| struct name {								\ | ||||
| 	struct type *sqh_first;	/* first element */			\ | ||||
| 	struct type **sqh_last;	/* addr of last next element */		\ | ||||
| } | ||||
|  | ||||
| #define	SIMPLEQ_HEAD_INITIALIZER(head)					\ | ||||
| 	{ NULL, &(head).sqh_first } | ||||
|  | ||||
| #define	SIMPLEQ_ENTRY(type)						\ | ||||
| struct {								\ | ||||
| 	struct type *sqe_next;	/* next element */			\ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Simple queue functions. | ||||
|  */ | ||||
| #define	SIMPLEQ_INIT(head) do {						\ | ||||
| 	(head)->sqh_first = NULL;					\ | ||||
| 	(head)->sqh_last = &(head)->sqh_first;				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\ | ||||
| 	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\ | ||||
| 		(head)->sqh_last = &(elm)->field.sqe_next;		\ | ||||
| 	(head)->sqh_first = (elm);					\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\ | ||||
| 	(elm)->field.sqe_next = NULL;					\ | ||||
| 	*(head)->sqh_last = (elm);					\ | ||||
| 	(head)->sqh_last = &(elm)->field.sqe_next;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\ | ||||
| 	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ | ||||
| 		(head)->sqh_last = &(elm)->field.sqe_next;		\ | ||||
| 	(listelm)->field.sqe_next = (elm);				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SIMPLEQ_REMOVE_HEAD(head, field) do {				\ | ||||
| 	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ | ||||
| 		(head)->sqh_last = &(head)->sqh_first;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SIMPLEQ_REMOVE(head, elm, type, field) do {			\ | ||||
| 	if ((head)->sqh_first == (elm)) {				\ | ||||
| 		SIMPLEQ_REMOVE_HEAD((head), field);			\ | ||||
| 	} else {							\ | ||||
| 		struct type *curelm = (head)->sqh_first;		\ | ||||
| 		while (curelm->field.sqe_next != (elm))			\ | ||||
| 			curelm = curelm->field.sqe_next;		\ | ||||
| 		if ((curelm->field.sqe_next =				\ | ||||
| 			curelm->field.sqe_next->field.sqe_next) == NULL) \ | ||||
| 			    (head)->sqh_last = &(curelm)->field.sqe_next; \ | ||||
| 	}								\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	SIMPLEQ_FOREACH(var, head, field)				\ | ||||
| 	for ((var) = ((head)->sqh_first);				\ | ||||
| 		(var);							\ | ||||
| 		(var) = ((var)->field.sqe_next)) | ||||
|  | ||||
| /* | ||||
|  * Simple queue access methods. | ||||
|  */ | ||||
| #define	SIMPLEQ_EMPTY(head)		((head)->sqh_first == NULL) | ||||
| #define	SIMPLEQ_FIRST(head)		((head)->sqh_first) | ||||
| #define	SIMPLEQ_NEXT(elm, field)	((elm)->field.sqe_next) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Tail queue definitions. | ||||
|  */ | ||||
| #define	_TAILQ_HEAD(name, type, qual)					\ | ||||
| struct name {								\ | ||||
| 	qual type *tqh_first;		/* first element */		\ | ||||
| 	qual type *qual *tqh_last;	/* addr of last next element */	\ | ||||
| } | ||||
| #define TAILQ_HEAD(name, type)	_TAILQ_HEAD(name, struct type,) | ||||
|  | ||||
| #define	TAILQ_HEAD_INITIALIZER(head)					\ | ||||
| 	{ NULL, &(head).tqh_first } | ||||
|  | ||||
| #define	_TAILQ_ENTRY(type, qual)					\ | ||||
| struct {								\ | ||||
| 	qual type *tqe_next;		/* next element */		\ | ||||
| 	qual type *qual *tqe_prev;	/* address of previous next element */\ | ||||
| } | ||||
| #define TAILQ_ENTRY(type)	_TAILQ_ENTRY(struct type,) | ||||
|  | ||||
| /* | ||||
|  * Tail queue functions. | ||||
|  */ | ||||
| #define	TAILQ_INIT(head) do {						\ | ||||
| 	(head)->tqh_first = NULL;					\ | ||||
| 	(head)->tqh_last = &(head)->tqh_first;				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	TAILQ_INSERT_HEAD(head, elm, field) do {			\ | ||||
| 	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\ | ||||
| 		(head)->tqh_first->field.tqe_prev =			\ | ||||
| 		    &(elm)->field.tqe_next;				\ | ||||
| 	else								\ | ||||
| 		(head)->tqh_last = &(elm)->field.tqe_next;		\ | ||||
| 	(head)->tqh_first = (elm);					\ | ||||
| 	(elm)->field.tqe_prev = &(head)->tqh_first;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	TAILQ_INSERT_TAIL(head, elm, field) do {			\ | ||||
| 	(elm)->field.tqe_next = NULL;					\ | ||||
| 	(elm)->field.tqe_prev = (head)->tqh_last;			\ | ||||
| 	*(head)->tqh_last = (elm);					\ | ||||
| 	(head)->tqh_last = &(elm)->field.tqe_next;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\ | ||||
| 	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ | ||||
| 		(elm)->field.tqe_next->field.tqe_prev = 		\ | ||||
| 		    &(elm)->field.tqe_next;				\ | ||||
| 	else								\ | ||||
| 		(head)->tqh_last = &(elm)->field.tqe_next;		\ | ||||
| 	(listelm)->field.tqe_next = (elm);				\ | ||||
| 	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\ | ||||
| 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\ | ||||
| 	(elm)->field.tqe_next = (listelm);				\ | ||||
| 	*(listelm)->field.tqe_prev = (elm);				\ | ||||
| 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	TAILQ_REMOVE(head, elm, field) do {				\ | ||||
| 	if (((elm)->field.tqe_next) != NULL)				\ | ||||
| 		(elm)->field.tqe_next->field.tqe_prev = 		\ | ||||
| 		    (elm)->field.tqe_prev;				\ | ||||
| 	else								\ | ||||
| 		(head)->tqh_last = (elm)->field.tqe_prev;		\ | ||||
| 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	TAILQ_FOREACH(var, head, field)					\ | ||||
| 	for ((var) = ((head)->tqh_first);				\ | ||||
| 		(var);							\ | ||||
| 		(var) = ((var)->field.tqe_next)) | ||||
|  | ||||
| #define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\ | ||||
| 	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\ | ||||
| 		(var);							\ | ||||
| 		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) | ||||
|  | ||||
| #define	TAILQ_CONCAT(head1, head2, field) do {				\ | ||||
| 	if (!TAILQ_EMPTY(head2)) {					\ | ||||
| 		*(head1)->tqh_last = (head2)->tqh_first;		\ | ||||
| 		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\ | ||||
| 		(head1)->tqh_last = (head2)->tqh_last;			\ | ||||
| 		TAILQ_INIT((head2));					\ | ||||
| 	}								\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| /* | ||||
|  * Tail queue access methods. | ||||
|  */ | ||||
| #define	TAILQ_EMPTY(head)		((head)->tqh_first == NULL) | ||||
| #define	TAILQ_FIRST(head)		((head)->tqh_first) | ||||
| #define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next) | ||||
|  | ||||
| #define	TAILQ_LAST(head, headname) \ | ||||
| 	(*(((struct headname *)((head)->tqh_last))->tqh_last)) | ||||
| #define	TAILQ_PREV(elm, headname, field) \ | ||||
| 	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Circular queue definitions. | ||||
|  */ | ||||
| #define	CIRCLEQ_HEAD(name, type)					\ | ||||
| struct name {								\ | ||||
| 	struct type *cqh_first;		/* first element */		\ | ||||
| 	struct type *cqh_last;		/* last element */		\ | ||||
| } | ||||
|  | ||||
| #define	CIRCLEQ_HEAD_INITIALIZER(head)					\ | ||||
| 	{ (void *)&head, (void *)&head } | ||||
|  | ||||
| #define	CIRCLEQ_ENTRY(type)						\ | ||||
| struct {								\ | ||||
| 	struct type *cqe_next;		/* next element */		\ | ||||
| 	struct type *cqe_prev;		/* previous element */		\ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Circular queue functions. | ||||
|  */ | ||||
| #define	CIRCLEQ_INIT(head) do {						\ | ||||
| 	(head)->cqh_first = (void *)(head);				\ | ||||
| 	(head)->cqh_last = (void *)(head);				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\ | ||||
| 	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\ | ||||
| 	(elm)->field.cqe_prev = (listelm);				\ | ||||
| 	if ((listelm)->field.cqe_next == (void *)(head))		\ | ||||
| 		(head)->cqh_last = (elm);				\ | ||||
| 	else								\ | ||||
| 		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\ | ||||
| 	(listelm)->field.cqe_next = (elm);				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\ | ||||
| 	(elm)->field.cqe_next = (listelm);				\ | ||||
| 	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\ | ||||
| 	if ((listelm)->field.cqe_prev == (void *)(head))		\ | ||||
| 		(head)->cqh_first = (elm);				\ | ||||
| 	else								\ | ||||
| 		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\ | ||||
| 	(listelm)->field.cqe_prev = (elm);				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\ | ||||
| 	(elm)->field.cqe_next = (head)->cqh_first;			\ | ||||
| 	(elm)->field.cqe_prev = (void *)(head);				\ | ||||
| 	if ((head)->cqh_last == (void *)(head))				\ | ||||
| 		(head)->cqh_last = (elm);				\ | ||||
| 	else								\ | ||||
| 		(head)->cqh_first->field.cqe_prev = (elm);		\ | ||||
| 	(head)->cqh_first = (elm);					\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\ | ||||
| 	(elm)->field.cqe_next = (void *)(head);				\ | ||||
| 	(elm)->field.cqe_prev = (head)->cqh_last;			\ | ||||
| 	if ((head)->cqh_first == (void *)(head))			\ | ||||
| 		(head)->cqh_first = (elm);				\ | ||||
| 	else								\ | ||||
| 		(head)->cqh_last->field.cqe_next = (elm);		\ | ||||
| 	(head)->cqh_last = (elm);					\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	CIRCLEQ_REMOVE(head, elm, field) do {				\ | ||||
| 	if ((elm)->field.cqe_next == (void *)(head))			\ | ||||
| 		(head)->cqh_last = (elm)->field.cqe_prev;		\ | ||||
| 	else								\ | ||||
| 		(elm)->field.cqe_next->field.cqe_prev =			\ | ||||
| 		    (elm)->field.cqe_prev;				\ | ||||
| 	if ((elm)->field.cqe_prev == (void *)(head))			\ | ||||
| 		(head)->cqh_first = (elm)->field.cqe_next;		\ | ||||
| 	else								\ | ||||
| 		(elm)->field.cqe_prev->field.cqe_next =			\ | ||||
| 		    (elm)->field.cqe_next;				\ | ||||
| } while (/*CONSTCOND*/0) | ||||
|  | ||||
| #define	CIRCLEQ_FOREACH(var, head, field)				\ | ||||
| 	for ((var) = ((head)->cqh_first);				\ | ||||
| 		(var) != (const void *)(head);				\ | ||||
| 		(var) = ((var)->field.cqe_next)) | ||||
|  | ||||
| #define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\ | ||||
| 	for ((var) = ((head)->cqh_last);				\ | ||||
| 		(var) != (const void *)(head);				\ | ||||
| 		(var) = ((var)->field.cqe_prev)) | ||||
|  | ||||
| /* | ||||
|  * Circular queue access methods. | ||||
|  */ | ||||
| #define	CIRCLEQ_EMPTY(head)		((head)->cqh_first == (void *)(head)) | ||||
| #define	CIRCLEQ_FIRST(head)		((head)->cqh_first) | ||||
| #define	CIRCLEQ_LAST(head)		((head)->cqh_last) | ||||
| #define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next) | ||||
| #define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev) | ||||
|  | ||||
| #define CIRCLEQ_LOOP_NEXT(head, elm, field)				\ | ||||
| 	(((elm)->field.cqe_next == (void *)(head))			\ | ||||
| 	    ? ((head)->cqh_first)					\ | ||||
| 	    : (elm->field.cqe_next)) | ||||
| #define CIRCLEQ_LOOP_PREV(head, elm, field)				\ | ||||
| 	(((elm)->field.cqe_prev == (void *)(head))			\ | ||||
| 	    ? ((head)->cqh_last)					\ | ||||
| 	    : (elm->field.cqe_prev)) | ||||
|  | ||||
| #endif	/* sys/queue.h */ | ||||
		Reference in New Issue
	
	Block a user
	 Felix Fietkau
					Felix Fietkau