queue.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:17k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1991, 1993
  3.  * The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  *
  14.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  15.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  18.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24.  * SUCH DAMAGE.
  25.  *
  26.  * @(#)queue.h 8.5 (Berkeley) 8/20/94
  27.  * $FreeBSD: src/sys/sys/queue.h,v 1.38 2000/05/26 02:06:56 jake Exp $
  28.  */
  29. #ifndef _SYS_QUEUE_H_
  30. #define _SYS_QUEUE_H_
  31. /*
  32.  * This file defines five types of data structures: singly-linked lists,
  33.  * singly-linked tail queues, lists, tail queues, and circular queues.
  34.  *
  35.  * A singly-linked list is headed by a single forward pointer. The elements
  36.  * are singly linked for minimum space and pointer manipulation overhead at
  37.  * the expense of O(n) removal for arbitrary elements. New elements can be
  38.  * added to the list after an existing element or at the head of the list.
  39.  * Elements being removed from the head of the list should use the explicit
  40.  * macro for this purpose for optimum efficiency. A singly-linked list may
  41.  * only be traversed in the forward direction.  Singly-linked lists are ideal
  42.  * for applications with large datasets and few or no removals or for
  43.  * implementing a LIFO queue.
  44.  *
  45.  * A singly-linked tail queue is headed by a pair of pointers, one to the
  46.  * head of the list and the other to the tail of the list. The elements are
  47.  * singly linked for minimum space and pointer manipulation overhead at the
  48.  * expense of O(n) removal for arbitrary elements. New elements can be added
  49.  * to the list after an existing element, at the head of the list, or at the
  50.  * end of the list. Elements being removed from the head of the tail queue
  51.  * should use the explicit macro for this purpose for optimum efficiency.
  52.  * A singly-linked tail queue may only be traversed in the forward direction.
  53.  * Singly-linked tail queues are ideal for applications with large datasets
  54.  * and few or no removals or for implementing a FIFO queue.
  55.  *
  56.  * A list is headed by a single forward pointer (or an array of forward
  57.  * pointers for a hash table header). The elements are doubly linked
  58.  * so that an arbitrary element can be removed without a need to
  59.  * traverse the list. New elements can be added to the list before
  60.  * or after an existing element or at the head of the list. A list
  61.  * may only be traversed in the forward direction.
  62.  *
  63.  * A tail queue is headed by a pair of pointers, one to the head of the
  64.  * list and the other to the tail of the list. The elements are doubly
  65.  * linked so that an arbitrary element can be removed without a need to
  66.  * traverse the list. New elements can be added to the list before or
  67.  * after an existing element, at the head of the list, or at the end of
  68.  * the list. A tail queue may be traversed in either direction.
  69.  *
  70.  * A circle queue is headed by a pair of pointers, one to the head of the
  71.  * list and the other to the tail of the list. The elements are doubly
  72.  * linked so that an arbitrary element can be removed without a need to
  73.  * traverse the list. New elements can be added to the list before or after
  74.  * an existing element, at the head of the list, or at the end of the list.
  75.  * A circle queue may be traversed in either direction, but has a more
  76.  * complex end of list detection.
  77.  *
  78.  * For details on the use of these macros, see the queue(3) manual page.
  79.  *
  80.  *
  81.  * SLIST LIST STAILQ TAILQ CIRCLEQ
  82.  * _HEAD + + + + +
  83.  * _HEAD_INITIALIZER + + + + +
  84.  * _ENTRY + + + + +
  85.  * _INIT + + + + +
  86.  * _EMPTY + + + + +
  87.  * _FIRST + + + + +
  88.  * _NEXT + + + + +
  89.  * _PREV - - - + +
  90.  * _LAST - - + + +
  91.  * _FOREACH + + + + +
  92.  * _FOREACH_REVERSE - - - + +
  93.  * _INSERT_HEAD + + + + +
  94.  * _INSERT_BEFORE - + - + +
  95.  * _INSERT_AFTER + + + + +
  96.  * _INSERT_TAIL - - + + +
  97.  * _REMOVE_HEAD + - + - -
  98.  * _REMOVE + + + + +
  99.  *
  100.  */
  101. /*
  102.  * Singly-linked List declarations.
  103.  */
  104. #define SLIST_HEAD(name, type)
  105. struct name {
  106. struct type *slh_first; /* first element */
  107. }
  108. #define SLIST_HEAD_INITIALIZER(head)
  109. { NULL }
  110.  
  111. #define SLIST_ENTRY(type)
  112. struct {
  113. struct type *sle_next; /* next element */
  114. }
  115.  
  116. /*
  117.  * Singly-linked List functions.
  118.  */
  119. #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
  120. #define SLIST_FIRST(head) ((head)->slh_first)
  121. #define SLIST_FOREACH(var, head, field)
  122. for ((var) = SLIST_FIRST((head));
  123.     (var);
  124.     (var) = SLIST_NEXT((var), field))
  125. #define SLIST_INIT(head) do {
  126. SLIST_FIRST((head)) = NULL;
  127. } while (0)
  128. #define SLIST_INSERT_AFTER(slistelm, elm, field) do {
  129. SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);
  130. SLIST_NEXT((slistelm), field) = (elm);
  131. } while (0)
  132. #define SLIST_INSERT_HEAD(head, elm, field) do {
  133. SLIST_NEXT((elm), field) = SLIST_FIRST((head));
  134. SLIST_FIRST((head)) = (elm);
  135. } while (0)
  136. #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
  137. #define SLIST_REMOVE(head, elm, type, field) do {
  138. if (SLIST_FIRST((head)) == (elm)) {
  139. SLIST_REMOVE_HEAD((head), field);
  140. }
  141. else {
  142. struct type *curelm = SLIST_FIRST((head));
  143. while (SLIST_NEXT(curelm, field) != (elm))
  144. curelm = SLIST_NEXT(curelm, field);
  145. SLIST_NEXT(curelm, field) =
  146.     SLIST_NEXT(SLIST_NEXT(curelm, field), field);
  147. }
  148. } while (0)
  149. #define SLIST_REMOVE_HEAD(head, field) do {
  150. SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);
  151. } while (0)
  152. /*
  153.  * Singly-linked Tail queue declarations.
  154.  */
  155. #define STAILQ_HEAD(name, type)
  156. struct name {
  157. struct type *stqh_first;/* first element */
  158. struct type **stqh_last;/* addr of last next element */
  159. }
  160. #define STAILQ_HEAD_INITIALIZER(head)
  161. { NULL, &(head).stqh_first }
  162. #define STAILQ_ENTRY(type)
  163. struct {
  164. struct type *stqe_next; /* next element */
  165. }
  166. /*
  167.  * Singly-linked Tail queue functions.
  168.  */
  169. #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
  170. #define STAILQ_FIRST(head) ((head)->stqh_first)
  171. #define STAILQ_FOREACH(var, head, field)
  172. for((var) = STAILQ_FIRST((head));
  173.    (var);
  174.    (var) = STAILQ_NEXT((var), field))
  175. #define STAILQ_INIT(head) do {
  176. STAILQ_FIRST((head)) = NULL;
  177. (head)->stqh_last = &STAILQ_FIRST((head));
  178. } while (0)
  179. #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {
  180. if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)
  181. (head)->stqh_last = &STAILQ_NEXT((elm), field);
  182. STAILQ_NEXT((tqelm), field) = (elm);
  183. } while (0)
  184. #define STAILQ_INSERT_HEAD(head, elm, field) do {
  185. if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)
  186. (head)->stqh_last = &STAILQ_NEXT((elm), field);
  187. STAILQ_FIRST((head)) = (elm);
  188. } while (0)
  189. #define STAILQ_INSERT_TAIL(head, elm, field) do {
  190. STAILQ_NEXT((elm), field) = NULL;
  191. STAILQ_LAST((head)) = (elm);
  192. (head)->stqh_last = &STAILQ_NEXT((elm), field);
  193. } while (0)
  194. #define STAILQ_LAST(head) (*(head)->stqh_last)
  195. #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
  196. #define STAILQ_REMOVE(head, elm, type, field) do {
  197. if (STAILQ_FIRST((head)) == (elm)) {
  198. STAILQ_REMOVE_HEAD(head, field);
  199. }
  200. else {
  201. struct type *curelm = STAILQ_FIRST((head));
  202. while (STAILQ_NEXT(curelm, field) != (elm))
  203. curelm = STAILQ_NEXT(curelm, field);
  204. if ((STAILQ_NEXT(curelm, field) =
  205.      STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)
  206. (head)->stqh_last = &STAILQ_NEXT((curelm), field);
  207. }
  208. } while (0)
  209. #define STAILQ_REMOVE_HEAD(head, field) do {
  210. if ((STAILQ_FIRST((head)) =
  211.      STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)
  212. (head)->stqh_last = &STAILQ_FIRST((head));
  213. } while (0)
  214. #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {
  215. if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL)
  216. (head)->stqh_last = &STAILQ_FIRST((head));
  217. } while (0)
  218. /*
  219.  * List declarations.
  220.  */
  221. #define LIST_HEAD(name, type)
  222. struct name {
  223. struct type *lh_first; /* first element */
  224. }
  225. #define LIST_HEAD_INITIALIZER(head)
  226. { NULL }
  227. #define LIST_ENTRY(type)
  228. struct {
  229. struct type *le_next; /* next element */
  230. struct type **le_prev; /* address of previous next element */
  231. }
  232. /*
  233.  * List functions.
  234.  */
  235. #define LIST_EMPTY(head) ((head)->lh_first == NULL)
  236. #define LIST_FIRST(head) ((head)->lh_first)
  237. #define LIST_FOREACH(var, head, field)
  238. for ((var) = LIST_FIRST((head));
  239.     (var);
  240.     (var) = LIST_NEXT((var), field))
  241. #define LIST_INIT(head) do {
  242. LIST_FIRST((head)) = NULL;
  243. } while (0)
  244. #define LIST_INSERT_AFTER(listelm, elm, field) do {
  245. if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)
  246. LIST_NEXT((listelm), field)->field.le_prev =
  247.     &LIST_NEXT((elm), field);
  248. LIST_NEXT((listelm), field) = (elm);
  249. (elm)->field.le_prev = &LIST_NEXT((listelm), field);
  250. } while (0)
  251. #define LIST_INSERT_BEFORE(listelm, elm, field) do {
  252. (elm)->field.le_prev = (listelm)->field.le_prev;
  253. LIST_NEXT((elm), field) = (listelm);
  254. *(listelm)->field.le_prev = (elm);
  255. (listelm)->field.le_prev = &LIST_NEXT((elm), field);
  256. } while (0)
  257. #define LIST_INSERT_HEAD(head, elm, field) do {
  258. if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)
  259. LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);
  260. LIST_FIRST((head)) = (elm);
  261. (elm)->field.le_prev = &LIST_FIRST((head));
  262. } while (0)
  263. #define LIST_NEXT(elm, field) ((elm)->field.le_next)
  264. #define LIST_REMOVE(elm, field) do {
  265. if (LIST_NEXT((elm), field) != NULL)
  266. LIST_NEXT((elm), field)->field.le_prev = 
  267.     (elm)->field.le_prev;
  268. *(elm)->field.le_prev = LIST_NEXT((elm), field);
  269. } while (0)
  270. /*
  271.  * Tail queue declarations.
  272.  */
  273. #define TAILQ_HEAD(name, type)
  274. struct name {
  275. struct type *tqh_first; /* first element */
  276. struct type **tqh_last; /* addr of last next element */
  277. }
  278. #define TAILQ_HEAD_INITIALIZER(head)
  279. { NULL, &(head).tqh_first }
  280. #define TAILQ_ENTRY(type)
  281. struct {
  282. struct type *tqe_next; /* next element */
  283. struct type **tqe_prev; /* address of previous next element */
  284. }
  285. /*
  286.  * Tail queue functions.
  287.  */
  288. #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
  289. #define TAILQ_FIRST(head) ((head)->tqh_first)
  290. #define TAILQ_FOREACH(var, head, field)
  291. for ((var) = TAILQ_FIRST((head));
  292.     (var);
  293.     (var) = TAILQ_NEXT((var), field))
  294. #define TAILQ_FOREACH_REVERSE(var, head, headname, field)
  295. for ((var) = TAILQ_LAST((head), headname);
  296.     (var);
  297.     (var) = TAILQ_PREV((var), headname, field))
  298. #define TAILQ_INIT(head) do {
  299. TAILQ_FIRST((head)) = NULL;
  300. (head)->tqh_last = &TAILQ_FIRST((head));
  301. } while (0)
  302. #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {
  303. if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)
  304. TAILQ_NEXT((elm), field)->field.tqe_prev = 
  305.     &TAILQ_NEXT((elm), field);
  306. else
  307. (head)->tqh_last = &TAILQ_NEXT((elm), field);
  308. TAILQ_NEXT((listelm), field) = (elm);
  309. (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);
  310. } while (0)
  311. #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {
  312. (elm)->field.tqe_prev = (listelm)->field.tqe_prev;
  313. TAILQ_NEXT((elm), field) = (listelm);
  314. *(listelm)->field.tqe_prev = (elm);
  315. (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);
  316. } while (0)
  317. #define TAILQ_INSERT_HEAD(head, elm, field) do {
  318. if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)
  319. TAILQ_FIRST((head))->field.tqe_prev =
  320.     &TAILQ_NEXT((elm), field);
  321. else
  322. (head)->tqh_last = &TAILQ_NEXT((elm), field);
  323. TAILQ_FIRST((head)) = (elm);
  324. (elm)->field.tqe_prev = &TAILQ_FIRST((head));
  325. } while (0)
  326. #define TAILQ_INSERT_TAIL(head, elm, field) do {
  327. TAILQ_NEXT((elm), field) = NULL;
  328. (elm)->field.tqe_prev = (head)->tqh_last;
  329. *(head)->tqh_last = (elm);
  330. (head)->tqh_last = &TAILQ_NEXT((elm), field);
  331. } while (0)
  332. #define TAILQ_LAST(head, headname)
  333. (*(((struct headname *)((head)->tqh_last))->tqh_last))
  334. #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
  335. #define TAILQ_PREV(elm, headname, field)
  336. (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
  337. #define TAILQ_REMOVE(head, elm, field) do {
  338. if ((TAILQ_NEXT((elm), field)) != NULL)
  339. TAILQ_NEXT((elm), field)->field.tqe_prev = 
  340.     (elm)->field.tqe_prev;
  341. else
  342. (head)->tqh_last = (elm)->field.tqe_prev;
  343. *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);
  344. } while (0)
  345. /*
  346.  * Circular queue declarations.
  347.  */
  348. #define CIRCLEQ_HEAD(name, type)
  349. struct name {
  350. struct type *cqh_first; /* first element */
  351. struct type *cqh_last; /* last element */
  352. }
  353. #define CIRCLEQ_HEAD_INITIALIZER(head)
  354. { (void *)&(head), (void *)&(head) }
  355. #define CIRCLEQ_ENTRY(type)
  356. struct {
  357. struct type *cqe_next; /* next element */
  358. struct type *cqe_prev; /* previous element */
  359. }
  360. /*
  361.  * Circular queue functions.
  362.  */
  363. #define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
  364. #define CIRCLEQ_FIRST(head) ((head)->cqh_first)
  365. #define CIRCLEQ_FOREACH(var, head, field)
  366. for ((var) = CIRCLEQ_FIRST((head));
  367.     (var) != (void *)(head);
  368.     (var) = CIRCLEQ_NEXT((var), field))
  369. #define CIRCLEQ_FOREACH_REVERSE(var, head, field)
  370. for ((var) = CIRCLEQ_LAST((head));
  371.     (var) != (void *)(head);
  372.     (var) = CIRCLEQ_PREV((var), field))
  373. #define CIRCLEQ_INIT(head) do {
  374. CIRCLEQ_FIRST((head)) = (void *)(head);
  375. CIRCLEQ_LAST((head)) = (void *)(head);
  376. } while (0)
  377. #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {
  378. CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field);
  379. CIRCLEQ_PREV((elm), field) = (listelm);
  380. if (CIRCLEQ_NEXT((listelm), field) == (void *)(head))
  381. CIRCLEQ_LAST((head)) = (elm);
  382. else
  383. CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);
  384. CIRCLEQ_NEXT((listelm), field) = (elm);
  385. } while (0)
  386. #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {
  387. CIRCLEQ_NEXT((elm), field) = (listelm);
  388. CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field);
  389. if (CIRCLEQ_PREV((listelm), field) == (void *)(head))
  390. CIRCLEQ_FIRST((head)) = (elm);
  391. else
  392. CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);
  393. CIRCLEQ_PREV((listelm), field) = (elm);
  394. } while (0)
  395. #define CIRCLEQ_INSERT_HEAD(head, elm, field) do {
  396. CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head));
  397. CIRCLEQ_PREV((elm), field) = (void *)(head);
  398. if (CIRCLEQ_LAST((head)) == (void *)(head))
  399. CIRCLEQ_LAST((head)) = (elm);
  400. else
  401. CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm);
  402. CIRCLEQ_FIRST((head)) = (elm);
  403. } while (0)
  404. #define CIRCLEQ_INSERT_TAIL(head, elm, field) do {
  405. CIRCLEQ_NEXT((elm), field) = (void *)(head);
  406. CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head));
  407. if (CIRCLEQ_FIRST((head)) == (void *)(head))
  408. CIRCLEQ_FIRST((head)) = (elm);
  409. else
  410. CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm);
  411. CIRCLEQ_LAST((head)) = (elm);
  412. } while (0)
  413. #define CIRCLEQ_LAST(head) ((head)->cqh_last)
  414. #define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
  415. #define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
  416. #define CIRCLEQ_REMOVE(head, elm, field) do {
  417. if (CIRCLEQ_NEXT((elm), field) == (void *)(head))
  418. CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field);
  419. else
  420. CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) =
  421.     CIRCLEQ_PREV((elm), field);
  422. if (CIRCLEQ_PREV((elm), field) == (void *)(head))
  423. CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field);
  424. else
  425. CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) =
  426.     CIRCLEQ_NEXT((elm), field);
  427. } while (0)
  428. #endif /* !_SYS_QUEUE_H_ */