Annotation of kernel/kern/queue.h, revision 1.1.1.1

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) 1991,1990,1989,1988,1987 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  *
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  *
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon rights
                     48:  * to redistribute these changes.
                     49:  */
                     50: /*
                     51:  *     File:   queue.h
                     52:  *     Author: Avadis Tevanian, Jr.
                     53:  *     Date:   1985
                     54:  *
                     55:  *     Type definitions for generic queues.
                     56:  *
                     57:  */
                     58: 
                     59: #ifndef        _KERN_QUEUE_H_
                     60: #define        _KERN_QUEUE_H_
                     61: 
                     62: #include <kern/lock.h>
                     63: #include <kern/macro_help.h>
                     64: 
                     65: /*
                     66:  *     Queue of abstract objects.  Queue is maintained
                     67:  *     within that object.
                     68:  *
                     69:  *     Supports fast removal from within the queue.
                     70:  *
                     71:  *     How to declare a queue of elements of type "foo_t":
                     72:  *             In the "*foo_t" type, you must have a field of
                     73:  *             type "queue_chain_t" to hold together this queue.
                     74:  *             There may be more than one chain through a
                     75:  *             "foo_t", for use by different queues.
                     76:  *
                     77:  *             Declare the queue as a "queue_t" type.
                     78:  *
                     79:  *             Elements of the queue (of type "foo_t", that is)
                     80:  *             are referred to by reference, and cast to type
                     81:  *             "queue_entry_t" within this module.
                     82:  */
                     83: 
                     84: /*
                     85:  *     A generic doubly-linked list (queue).
                     86:  */
                     87: 
                     88: struct queue_entry {
                     89:        struct queue_entry      *next;          /* next element */
                     90:        struct queue_entry      *prev;          /* previous element */
                     91: };
                     92: 
                     93: typedef struct queue_entry     *queue_t;
                     94: typedef        struct queue_entry      queue_head_t;
                     95: typedef        struct queue_entry      queue_chain_t;
                     96: typedef        struct queue_entry      *queue_entry_t;
                     97: 
                     98: /*
                     99:  *     enqueue puts "elt" on the "queue".
                    100:  *     dequeue returns the first element in the "queue".
                    101:  *     remqueue removes the specified "elt" from the specified "queue".
                    102:  */
                    103: 
                    104: #define enqueue(queue,elt)     enqueue_tail(queue, elt)
                    105: #define        dequeue(queue)          dequeue_head(queue)
                    106: 
                    107: /*
                    108:  *     Routines to implement queue package.
                    109:  */
                    110:  
                    111: #ifndef        _KERN_QUEUE_FUNCTION_SCOPE_
                    112: #define        _KERN_QUEUE_FUNCTION_SCOPE_ static __inline__
                    113: #define _KERN_QUEUE_H_INTERNAL_SCOPING_
                    114: #endif
                    115: 
                    116: /*
                    117:  *     Insert element at head of queue.
                    118:  */
                    119: _KERN_QUEUE_FUNCTION_SCOPE_
                    120: void enqueue_head(
                    121:        register queue_t        que,
                    122:        register queue_entry_t  elt)
                    123: {
                    124:        elt->next = que->next;
                    125:        elt->prev = que;
                    126:        elt->next->prev = elt;
                    127:        que->next = elt;
                    128: }
                    129: 
                    130: /*
                    131:  *     Insert element at tail of queue.
                    132:  */
                    133: _KERN_QUEUE_FUNCTION_SCOPE_
                    134: void enqueue_tail(
                    135:        register queue_t        que,
                    136:        register queue_entry_t  elt)
                    137: {
                    138:        elt->next = que;
                    139:        elt->prev = que->prev;
                    140:        elt->prev->next = elt;
                    141:        que->prev = elt;
                    142: }
                    143: 
                    144: /*
                    145:  *     Remove and return element at head of queue.
                    146:  */
                    147: _KERN_QUEUE_FUNCTION_SCOPE_
                    148: queue_entry_t dequeue_head(
                    149:        register queue_t        que)
                    150: {
                    151:        register queue_entry_t  elt;
                    152: 
                    153:        if (que->next == que)
                    154:                return((queue_entry_t)0);
                    155: 
                    156:        elt = que->next;
                    157:        elt->next->prev = que;
                    158:        que->next = elt->next;
                    159:        return(elt);
                    160: }
                    161: 
                    162: /*
                    163:  *     Remove and return element at tail of queue.
                    164:  */
                    165: _KERN_QUEUE_FUNCTION_SCOPE_
                    166: queue_entry_t dequeue_tail(
                    167:        register queue_t        que)
                    168: {
                    169:        register queue_entry_t  elt;
                    170: 
                    171:        if (que->prev == que)
                    172:                return((queue_entry_t)0);
                    173: 
                    174:        elt = que->prev;
                    175:        elt->prev->next = que;
                    176:        que->prev = elt->prev;
                    177:        return(elt);
                    178: }
                    179: 
                    180: /*
                    181:  *     Remove arbitrary element from queue.
                    182:  *     Does not check whether element is on queue - the world
                    183:  *     will go haywire if it isn't.
                    184:  */
                    185: 
                    186: _KERN_QUEUE_FUNCTION_SCOPE_
                    187: /*ARGSUSED*/
                    188: void remqueue(
                    189:        queue_t                 que,
                    190:        register queue_entry_t  elt)
                    191: {
                    192:        elt->next->prev = elt->prev;
                    193:        elt->prev->next = elt->next;
                    194: }
                    195: 
                    196: /*
                    197:  *     Routines to directly imitate the VAX hardware queue
                    198:  *     package.
                    199:  */
                    200:  _KERN_QUEUE_FUNCTION_SCOPE_
                    201: void insque(
                    202:        register struct queue_entry *entry,
                    203:        register struct queue_entry *pred)
                    204: {
                    205:        entry->next = pred->next;
                    206:        entry->prev = pred;
                    207:        (pred->next)->prev = entry;
                    208:        pred->next = entry;
                    209: }
                    210: 
                    211: _KERN_QUEUE_FUNCTION_SCOPE_
                    212: struct queue_entry
                    213: *remque(
                    214:        register struct queue_entry *elt)
                    215: {
                    216:        (elt->next)->prev = elt->prev;
                    217:        (elt->prev)->next = elt->next;
                    218:        return(elt);
                    219: }
                    220: 
                    221: #ifdef _KERN_QUEUE_H_INTERNAL_SCOPING_
                    222: #undef _KERN_QUEUE_H_INTERNAL_SCOPING_
                    223: #endif
                    224: 
                    225: /*
                    226:  *     Macro:          queue_init
                    227:  *     Function:
                    228:  *             Initialize the given queue.
                    229:  *     Header:
                    230:  *             void queue_init(q)
                    231:  *                     queue_t         q;      *MODIFIED*
                    232:  */
                    233: #define        queue_init(q)   ((q)->next = (q)->prev = q)
                    234: 
                    235: /*
                    236:  *     Macro:          queue_first
                    237:  *     Function:
                    238:  *             Returns the first entry in the queue,
                    239:  *     Header:
                    240:  *             queue_entry_t queue_first(q)
                    241:  *                     queue_t q;              *IN*
                    242:  */
                    243: #define        queue_first(q)  ((q)->next)
                    244: 
                    245: /*
                    246:  *     Macro:          queue_next
                    247:  *     Function:
                    248:  *             Returns the entry after an item in the queue.
                    249:  *     Header:
                    250:  *             queue_entry_t queue_next(qc)
                    251:  *                     queue_t qc;
                    252:  */
                    253: #define        queue_next(qc)  ((qc)->next)
                    254: 
                    255: /*
                    256:  *     Macro:          queue_last
                    257:  *     Function:
                    258:  *             Returns the last entry in the queue.
                    259:  *     Header:
                    260:  *             queue_entry_t queue_last(q)
                    261:  *                     queue_t q;               *IN*
                    262:  */
                    263: #define        queue_last(q)   ((q)->prev)
                    264: 
                    265: /*
                    266:  *     Macro:          queue_prev
                    267:  *     Function:
                    268:  *             Returns the entry before an item in the queue.
                    269:  *     Header:
                    270:  *             queue_entry_t queue_prev(qc)
                    271:  *                     queue_t qc;
                    272:  */
                    273: #define        queue_prev(qc)  ((qc)->prev)
                    274: 
                    275: /*
                    276:  *     Macro:          queue_end
                    277:  *     Function:
                    278:  *             Tests whether a new entry is really the end of
                    279:  *             the queue.
                    280:  *     Header:
                    281:  *             boolean_t queue_end(q, qe)
                    282:  *                     queue_t q;
                    283:  *                     queue_entry_t qe;
                    284:  */
                    285: #define        queue_end(q, qe)        ((q) == (qe))
                    286: 
                    287: /*
                    288:  *     Macro:          queue_empty
                    289:  *     Function:
                    290:  *             Tests whether a queue is empty.
                    291:  *     Header:
                    292:  *             boolean_t queue_empty(q)
                    293:  *                     queue_t q;
                    294:  */
                    295: #define        queue_empty(q)          queue_end((q), queue_first(q))
                    296: 
                    297: 
                    298: /*----------------------------------------------------------------*/
                    299: /*
                    300:  * Macros that operate on generic structures.  The queue
                    301:  * chain may be at any location within the structure, and there
                    302:  * may be more than one chain.
                    303:  */
                    304: 
                    305: /*
                    306:  *     Macro:          queue_enter
                    307:  *     Function:
                    308:  *             Insert a new element at the tail of the queue.
                    309:  *     Header:
                    310:  *             void queue_enter(q, elt, type, field)
                    311:  *                     queue_t q;
                    312:  *                     <type> elt;
                    313:  *                     <type> is what's in our queue
                    314:  *                     <field> is the chain field in (*<type>)
                    315:  */
                    316: #define queue_enter(head, elt, type, field)                    \
                    317: MACRO_BEGIN                                                    \
                    318:        register queue_entry_t prev;                            \
                    319:                                                                \
                    320:        prev = (head)->prev;                                    \
                    321:        if ((head) == prev) {                                   \
                    322:                (head)->next = (queue_entry_t) (elt);           \
                    323:        }                                                       \
                    324:        else {                                                  \
                    325:                ((type)prev)->field.next = (queue_entry_t)(elt);\
                    326:        }                                                       \
                    327:        (elt)->field.prev = prev;                               \
                    328:        (elt)->field.next = head;                               \
                    329:        (head)->prev = (queue_entry_t) elt;                     \
                    330: MACRO_END
                    331: 
                    332: /*
                    333:  *     Macro:          queue_enter_first
                    334:  *     Function:
                    335:  *             Insert a new element at the head of the queue.
                    336:  *     Header:
                    337:  *             void queue_enter_first(q, elt, type, field)
                    338:  *                     queue_t q;
                    339:  *                     <type> elt;
                    340:  *                     <type> is what's in our queue
                    341:  *                     <field> is the chain field in (*<type>)
                    342:  */
                    343: #define queue_enter_first(head, elt, type, field)              \
                    344: MACRO_BEGIN                                                    \
                    345:        register queue_entry_t next;                            \
                    346:                                                                \
                    347:        next = (head)->next;                                    \
                    348:        if ((head) == next) {                                   \
                    349:                (head)->prev = (queue_entry_t) (elt);           \
                    350:        }                                                       \
                    351:        else {                                                  \
                    352:                ((type)next)->field.prev = (queue_entry_t)(elt);\
                    353:        }                                                       \
                    354:        (elt)->field.next = next;                               \
                    355:        (elt)->field.prev = head;                               \
                    356:        (head)->next = (queue_entry_t) elt;                     \
                    357: MACRO_END
                    358: 
                    359: /*
                    360:  *     Macro:          queue_field [internal use only]
                    361:  *     Function:
                    362:  *             Find the queue_chain_t (or queue_t) for the
                    363:  *             given element (thing) in the given queue (head)
                    364:  */
                    365: #define        queue_field(head, thing, type, field)                   \
                    366:                (((head) == (thing)) ? (head) : &((type)(thing))->field)
                    367: 
                    368: /*
                    369:  *     Macro:          queue_remove
                    370:  *     Function:
                    371:  *             Remove an arbitrary item from the queue.
                    372:  *     Header:
                    373:  *             void queue_remove(q, qe, type, field)
                    374:  *                     arguments as in queue_enter
                    375:  */
                    376: #define        queue_remove(head, elt, type, field)                    \
                    377: MACRO_BEGIN                                                    \
                    378:        register queue_entry_t  next, prev;                     \
                    379:                                                                \
                    380:        next = (elt)->field.next;                               \
                    381:        prev = (elt)->field.prev;                               \
                    382:                                                                \
                    383:        if ((head) == next)                                     \
                    384:                (head)->prev = prev;                            \
                    385:        else                                                    \
                    386:                ((type)next)->field.prev = prev;                \
                    387:                                                                \
                    388:        if ((head) == prev)                                     \
                    389:                (head)->next = next;                            \
                    390:        else                                                    \
                    391:                ((type)prev)->field.next = next;                \
                    392: MACRO_END
                    393: 
                    394: /*
                    395:  *     Macro:          queue_remove_first
                    396:  *     Function:
                    397:  *             Remove and return the entry at the head of
                    398:  *             the queue.
                    399:  *     Header:
                    400:  *             queue_remove_first(head, entry, type, field)
                    401:  *             entry is returned by reference
                    402:  */
                    403: #define        queue_remove_first(head, entry, type, field)            \
                    404: MACRO_BEGIN                                                    \
                    405:        register queue_entry_t  next;                           \
                    406:                                                                \
                    407:        (entry) = (type) ((head)->next);                        \
                    408:        next = (entry)->field.next;                             \
                    409:                                                                \
                    410:        if ((head) == next)                                     \
                    411:                (head)->prev = (head);                          \
                    412:        else                                                    \
                    413:                ((type)(next))->field.prev = (head);            \
                    414:        (head)->next = next;                                    \
                    415: MACRO_END
                    416: 
                    417: /*
                    418:  *     Macro:          queue_remove_last
                    419:  *     Function:
                    420:  *             Remove and return the entry at the tail of
                    421:  *             the queue.
                    422:  *     Header:
                    423:  *             queue_remove_last(head, entry, type, field)
                    424:  *             entry is returned by reference
                    425:  */
                    426: #define        queue_remove_last(head, entry, type, field)             \
                    427: MACRO_BEGIN                                                    \
                    428:        register queue_entry_t  prev;                           \
                    429:                                                                \
                    430:        (entry) = (type) ((head)->prev);                        \
                    431:        prev = (entry)->field.prev;                             \
                    432:                                                                \
                    433:        if ((head) == prev)                                     \
                    434:                (head)->next = (head);                          \
                    435:        else                                                    \
                    436:                ((type)(prev))->field.next = (head);            \
                    437:        (head)->prev = prev;                                    \
                    438: MACRO_END
                    439: 
                    440: /*
                    441:  *     Macro:          queue_assign
                    442:  */
                    443: #define        queue_assign(to, from, type, field)                     \
                    444: MACRO_BEGIN                                                    \
                    445:        ((type)((from)->prev))->field.next = (to);              \
                    446:        ((type)((from)->next))->field.prev = (to);              \
                    447:        *to = *from;                                            \
                    448: MACRO_END
                    449: 
                    450: /*
                    451:  *     Macro:          queue_iterate
                    452:  *     Function:
                    453:  *             iterate over each item in the queue.
                    454:  *             Generates a 'for' loop, setting elt to
                    455:  *             each item in turn (by reference).
                    456:  *     Header:
                    457:  *             queue_iterate(q, elt, type, field)
                    458:  *                     queue_t q;
                    459:  *                     <type> elt;
                    460:  *                     <type> is what's in our queue
                    461:  *                     <field> is the chain field in (*<type>)
                    462:  */
                    463: #define queue_iterate(head, elt, type, field)                  \
                    464:        for ((elt) = (type) queue_first(head);                  \
                    465:             !queue_end((head), (queue_entry_t)(elt));          \
                    466:             (elt) = (type) queue_next(&(elt)->field))
                    467: 
                    468: #endif /* _KERN_QUEUE_H_ */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.