Annotation of kernel/kernserv/queue.h, revision 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) 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 */

unix.superglobalmegacorp.com

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