|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1989 Carnegie-Mellon University ! 28: * Copyright (c) 1988 Carnegie-Mellon University ! 29: * Copyright (c) 1987 Carnegie-Mellon University ! 30: * All rights reserved. The CMU software License Agreement specifies ! 31: * the terms and conditions for use and redistribution. ! 32: */ ! 33: /* ! 34: * File: queue.h ! 35: * ! 36: * Type definitions for generic queues. ! 37: */ ! 38: ! 39: #ifdef KERNEL_PRIVATE ! 40: #warning Obsolete header file: <kernserv/queue.h>, use <kern/queue.h> \ ! 41: instead; or better yet, just say no!! ! 42: #import <kern/queue.h> ! 43: ! 44: #else /* KERNEL_PRIVATE */ ! 45: ! 46: #ifndef _KERN_QUEUE_H_ ! 47: #define _KERN_QUEUE_H_ ! 48: ! 49: #import <mach/machine/vm_types.h> ! 50: #import <kernserv/lock.h> ! 51: #import <kernserv/macro_help.h> ! 52: ! 53: /* ! 54: * Queue of abstract objects. Queue is maintained ! 55: * within that object. ! 56: * ! 57: * Supports fast removal from within the queue. ! 58: * ! 59: * How to declare a queue of elements of type "foo_t": ! 60: * In the "*foo_t" type, you must have a field of ! 61: * type "queue_chain_t" to hold together this queue. ! 62: * There may be more than one chain through a ! 63: * "foo_t", for use by different queues. ! 64: * ! 65: * Declare the queue as a "queue_t" type. ! 66: * ! 67: * Elements of the queue (of type "foo_t", that is) ! 68: * are referred to by reference, and cast to type ! 69: * "queue_entry_t" within this module. ! 70: */ ! 71: ! 72: /* ! 73: * A generic doubly-linked list (queue). ! 74: */ ! 75: ! 76: struct queue_entry { ! 77: struct queue_entry *next; /* next element */ ! 78: struct queue_entry *prev; /* previous element */ ! 79: }; ! 80: ! 81: typedef struct queue_entry *queue_t; ! 82: typedef struct queue_entry queue_head_t; ! 83: typedef struct queue_entry queue_chain_t; ! 84: typedef struct queue_entry *queue_entry_t; ! 85: ! 86: /* ! 87: * enqueue puts "elt" on the "queue". ! 88: * dequeue returns the first element in the "queue". ! 89: * remqueue removes the specified "elt" from the specified "queue". ! 90: */ ! 91: ! 92: #define enqueue(queue,elt) enqueue_tail(queue, elt) ! 93: #define dequeue(queue) dequeue_head(queue) ! 94: ! 95: extern void enqueue_head(); ! 96: extern void enqueue_tail(); ! 97: extern queue_entry_t dequeue_head(); ! 98: extern queue_entry_t dequeue_tail(); ! 99: extern void remqueue(); ! 100: ! 101: ! 102: /* ! 103: * Macro: queue_init ! 104: * Function: ! 105: * Initialize the given queue. ! 106: * Header: ! 107: * void queue_init(q) ! 108: * queue_t q; \* MODIFIED *\ ! 109: */ ! 110: #define queue_init(q) ((q)->next = (q)->prev = q) ! 111: ! 112: /* ! 113: * Macro: queue_first ! 114: * Function: ! 115: * Returns the first entry in the queue, ! 116: * Header: ! 117: * queue_entry_t queue_first(q) ! 118: * queue_t q; \* IN *\ ! 119: */ ! 120: #define queue_first(q) ((q)->next) ! 121: ! 122: /* ! 123: * Macro: queue_next ! 124: * Header: ! 125: * queue_entry_t queue_next(qc) ! 126: * queue_t qc; ! 127: */ ! 128: #define queue_next(qc) ((qc)->next) ! 129: ! 130: /* ! 131: * Macro: queue_end ! 132: * Header: ! 133: * boolean_t queue_end(q, qe) ! 134: * queue_t q; ! 135: * queue_entry_t qe; ! 136: */ ! 137: #define queue_end(q, qe) ((q) == (qe)) ! 138: ! 139: #define queue_empty(q) queue_end((q), queue_first(q)) ! 140: ! 141: /* ! 142: * Macro: queue_enter ! 143: * Header: ! 144: * void queue_enter(q, elt, type, field) ! 145: * queue_t q; ! 146: * <type> elt; ! 147: * <type> is what's in our queue ! 148: * <field> is the chain field in (*<type>) ! 149: */ ! 150: #define queue_enter(head, elt, type, field) \ ! 151: MACRO_BEGIN \ ! 152: if (queue_empty((head))) { \ ! 153: (head)->next = (queue_entry_t) elt; \ ! 154: (head)->prev = (queue_entry_t) elt; \ ! 155: (elt)->field.next = head; \ ! 156: (elt)->field.prev = head; \ ! 157: } \ ! 158: else { \ ! 159: register queue_entry_t prev; \ ! 160: \ ! 161: prev = (head)->prev; \ ! 162: (elt)->field.prev = prev; \ ! 163: (elt)->field.next = head; \ ! 164: (head)->prev = (queue_entry_t)(elt); \ ! 165: ((type)prev)->field.next = (queue_entry_t)(elt);\ ! 166: } \ ! 167: MACRO_END ! 168: ! 169: /* ! 170: * Macro: queue_field [internal use only] ! 171: * Function: ! 172: * Find the queue_chain_t (or queue_t) for the ! 173: * given element (thing) in the given queue (head) ! 174: */ ! 175: #define queue_field(head, thing, type, field) \ ! 176: (((head) == (thing)) ? (head) : &((type)(thing))->field) ! 177: ! 178: /* ! 179: * Macro: queue_remove ! 180: * Header: ! 181: * void queue_remove(q, qe, type, field) ! 182: * arguments as in queue_enter ! 183: */ ! 184: #define queue_remove(head, elt, type, field) \ ! 185: MACRO_BEGIN \ ! 186: register queue_entry_t next, prev; \ ! 187: \ ! 188: next = (elt)->field.next; \ ! 189: prev = (elt)->field.prev; \ ! 190: \ ! 191: queue_field((head), next, type, field)->prev = prev; \ ! 192: queue_field((head), prev, type, field)->next = next; \ ! 193: MACRO_END ! 194: ! 195: /* ! 196: * Macro: queue_assign ! 197: */ ! 198: #define queue_assign(to, from, type, field) \ ! 199: MACRO_BEGIN \ ! 200: ((type)((from)->prev))->field.next = (to); \ ! 201: ((type)((from)->next))->field.prev = (to); \ ! 202: *to = *from; \ ! 203: MACRO_END ! 204: ! 205: #define queue_remove_first(h, e, t, f) \ ! 206: MACRO_BEGIN \ ! 207: e = (t) queue_first((h)); \ ! 208: queue_remove((h), (e), t, f); \ ! 209: MACRO_END ! 210: ! 211: #define queue_remove_last(h, e, t, f) \ ! 212: MACRO_BEGIN \ ! 213: e = (t) queue_last((h)); \ ! 214: queue_remove((h), (e), t, f); \ ! 215: MACRO_END ! 216: ! 217: /* ! 218: * Macro: queue_enter_first ! 219: * Header: ! 220: * void queue_enter_first(q, elt, type, field) ! 221: * queue_t q; ! 222: * <type> elt; ! 223: * <type> is what's in our queue ! 224: * <field> is the chain field in (*<type>) ! 225: */ ! 226: #define queue_enter_first(head, elt, type, field) \ ! 227: MACRO_BEGIN \ ! 228: if (queue_empty((head))) { \ ! 229: (head)->next = (queue_entry_t) elt; \ ! 230: (head)->prev = (queue_entry_t) elt; \ ! 231: (elt)->field.next = head; \ ! 232: (elt)->field.prev = head; \ ! 233: } \ ! 234: else { \ ! 235: register queue_entry_t next; \ ! 236: \ ! 237: next = (head)->next; \ ! 238: (elt)->field.prev = head; \ ! 239: (elt)->field.next = next; \ ! 240: (head)->next = (queue_entry_t)(elt); \ ! 241: ((type)next)->field.prev = (queue_entry_t)(elt);\ ! 242: } \ ! 243: MACRO_END ! 244: ! 245: /* ! 246: * Macro: queue_last ! 247: * Function: ! 248: * Returns the last entry in the queue, ! 249: * Header: ! 250: * queue_entry_t queue_last(q) ! 251: * queue_t q; \* IN *\ ! 252: */ ! 253: #define queue_last(q) ((q)->prev) ! 254: ! 255: /* ! 256: * Macro: queue_prev ! 257: * Header: ! 258: * queue_entry_t queue_prev(qc) ! 259: * queue_t qc; ! 260: */ ! 261: #define queue_prev(qc) ((qc)->prev) ! 262: ! 263: /* ! 264: * Macro: queue_iterate ! 265: * Function: ! 266: * iterate over each item in the queue. ! 267: * Generates a 'for' loop, setting elt to ! 268: * each item in turn (by reference). ! 269: * Header: ! 270: * queue_iterate(q, elt, type, field) ! 271: * queue_t q; ! 272: * <type> elt; ! 273: * <type> is what's in our queue ! 274: * <field> is the chain field in (*<type>) ! 275: */ ! 276: #define queue_iterate(head, elt, type, field) \ ! 277: for ((elt) = (type) queue_first(head); \ ! 278: !queue_end((head), (queue_entry_t)(elt)); \ ! 279: (elt) = (type) queue_next(&(elt)->field)) ! 280: ! 281: #ifdef KERNEL ! 282: ! 283: /* ! 284: * Define macros for queues with locks. ! 285: */ ! 286: struct mpqueue_head { ! 287: struct queue_entry head; /* header for queue */ ! 288: simple_lock_data_t lock; /* lock for queue */ ! 289: }; ! 290: ! 291: typedef struct mpqueue_head mpqueue_head_t; ! 292: ! 293: #define round_mpq(size) (size) ! 294: ! 295: #define mpqueue_init(q) \ ! 296: MACRO_BEGIN \ ! 297: queue_init(&(q)->head); \ ! 298: simple_lock_init(&(q)->lock); \ ! 299: MACRO_END ! 300: ! 301: #define mpenqueue_tail(q, elt) \ ! 302: MACRO_BEGIN \ ! 303: simple_lock(&(q)->lock); \ ! 304: enqueue_tail(&(q)->head, elt); \ ! 305: simple_unlock(&(q)->lock); \ ! 306: MACRO_END ! 307: ! 308: #define mpdequeue_head(q, elt) \ ! 309: MACRO_BEGIN \ ! 310: simple_lock(&(q)->lock); \ ! 311: if (queue_empty(&(q)->head)) \ ! 312: *(elt) = 0; \ ! 313: else \ ! 314: *(elt) = dequeue_head(&(q)->head); \ ! 315: simple_unlock(&(q)->lock); \ ! 316: MACRO_END ! 317: ! 318: #endif /* KERNEL */ ! 319: ! 320: #endif /* _KERN_QUEUE_H_ */ ! 321: ! 322: #endif /* KERNEL_PRIVATE */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.