Annotation of OSKit-Mach/kern/queue.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  *
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  *
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  *
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  *
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  *
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon rights
        !            24:  * to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:  *     File:   queue.h
        !            28:  *     Author: Avadis Tevanian, Jr.
        !            29:  *     Date:   1985
        !            30:  *
        !            31:  *     Type definitions for generic queues.
        !            32:  *
        !            33:  */
        !            34: 
        !            35: #ifndef        _KERN_QUEUE_H_
        !            36: #define        _KERN_QUEUE_H_
        !            37: 
        !            38: #include <kern/lock.h>
        !            39: 
        !            40: /*
        !            41:  *     Queue of abstract objects.  Queue is maintained
        !            42:  *     within that object.
        !            43:  *
        !            44:  *     Supports fast removal from within the queue.
        !            45:  *
        !            46:  *     How to declare a queue of elements of type "foo_t":
        !            47:  *             In the "*foo_t" type, you must have a field of
        !            48:  *             type "queue_chain_t" to hold together this queue.
        !            49:  *             There may be more than one chain through a
        !            50:  *             "foo_t", for use by different queues.
        !            51:  *
        !            52:  *             Declare the queue as a "queue_t" type.
        !            53:  *
        !            54:  *             Elements of the queue (of type "foo_t", that is)
        !            55:  *             are referred to by reference, and cast to type
        !            56:  *             "queue_entry_t" within this module.
        !            57:  */
        !            58: 
        !            59: /*
        !            60:  *     A generic doubly-linked list (queue).
        !            61:  */
        !            62: 
        !            63: struct queue_entry {
        !            64:        struct queue_entry      *next;          /* next element */
        !            65:        struct queue_entry      *prev;          /* previous element */
        !            66: };
        !            67: 
        !            68: typedef struct queue_entry     *queue_t;
        !            69: typedef        struct queue_entry      queue_head_t;
        !            70: typedef        struct queue_entry      queue_chain_t;
        !            71: typedef        struct queue_entry      *queue_entry_t;
        !            72: 
        !            73: /*
        !            74:  *     enqueue puts "elt" on the "queue".
        !            75:  *     dequeue returns the first element in the "queue".
        !            76:  *     remqueue removes the specified "elt" from the specified "queue".
        !            77:  */
        !            78: 
        !            79: #define enqueue(queue,elt)     enqueue_tail(queue, elt)
        !            80: #define        dequeue(queue)          dequeue_head(queue)
        !            81: 
        !            82: void           enqueue_head();
        !            83: void           enqueue_tail();
        !            84: queue_entry_t  dequeue_head();
        !            85: queue_entry_t  dequeue_tail();
        !            86: void           remqueue();
        !            87: 
        !            88: /*
        !            89:  *     Macro:          queue_init
        !            90:  *     Function:
        !            91:  *             Initialize the given queue.
        !            92:  *     Header:
        !            93:  *             void queue_init(q)
        !            94:  *                     queue_t         q;      *MODIFIED*
        !            95:  */
        !            96: #define        queue_init(q)   ((q)->next = (q)->prev = q)
        !            97: 
        !            98: /*
        !            99:  *     Macro:          queue_first
        !           100:  *     Function:
        !           101:  *             Returns the first entry in the queue,
        !           102:  *     Header:
        !           103:  *             queue_entry_t queue_first(q)
        !           104:  *                     queue_t q;              *IN*
        !           105:  */
        !           106: #define        queue_first(q)  ((q)->next)
        !           107: 
        !           108: /*
        !           109:  *     Macro:          queue_next
        !           110:  *     Function:
        !           111:  *             Returns the entry after an item in the queue.
        !           112:  *     Header:
        !           113:  *             queue_entry_t queue_next(qc)
        !           114:  *                     queue_t qc;
        !           115:  */
        !           116: #define        queue_next(qc)  ((qc)->next)
        !           117: 
        !           118: /*
        !           119:  *     Macro:          queue_last
        !           120:  *     Function:
        !           121:  *             Returns the last entry in the queue.
        !           122:  *     Header:
        !           123:  *             queue_entry_t queue_last(q)
        !           124:  *                     queue_t q;               *IN*
        !           125:  */
        !           126: #define        queue_last(q)   ((q)->prev)
        !           127: 
        !           128: /*
        !           129:  *     Macro:          queue_prev
        !           130:  *     Function:
        !           131:  *             Returns the entry before an item in the queue.
        !           132:  *     Header:
        !           133:  *             queue_entry_t queue_prev(qc)
        !           134:  *                     queue_t qc;
        !           135:  */
        !           136: #define        queue_prev(qc)  ((qc)->prev)
        !           137: 
        !           138: /*
        !           139:  *     Macro:          queue_end
        !           140:  *     Function:
        !           141:  *             Tests whether a new entry is really the end of
        !           142:  *             the queue.
        !           143:  *     Header:
        !           144:  *             boolean_t queue_end(q, qe)
        !           145:  *                     queue_t q;
        !           146:  *                     queue_entry_t qe;
        !           147:  */
        !           148: #define        queue_end(q, qe)        ((q) == (qe))
        !           149: 
        !           150: /*
        !           151:  *     Macro:          queue_empty
        !           152:  *     Function:
        !           153:  *             Tests whether a queue is empty.
        !           154:  *     Header:
        !           155:  *             boolean_t queue_empty(q)
        !           156:  *                     queue_t q;
        !           157:  */
        !           158: #define        queue_empty(q)          queue_end((q), queue_first(q))
        !           159: 
        !           160: 
        !           161: /*----------------------------------------------------------------*/
        !           162: /*
        !           163:  * Macros that operate on generic structures.  The queue
        !           164:  * chain may be at any location within the structure, and there
        !           165:  * may be more than one chain.
        !           166:  */
        !           167: 
        !           168: /*
        !           169:  *     Macro:          queue_enter
        !           170:  *     Function:
        !           171:  *             Insert a new element at the tail of the queue.
        !           172:  *     Header:
        !           173:  *             void queue_enter(q, elt, type, field)
        !           174:  *                     queue_t q;
        !           175:  *                     <type> elt;
        !           176:  *                     <type> is what's in our queue
        !           177:  *                     <field> is the chain field in (*<type>)
        !           178:  */
        !           179: #define queue_enter(head, elt, type, field)                    \
        !           180: {                                                              \
        !           181:        register queue_entry_t prev;                            \
        !           182:                                                                \
        !           183:        prev = (head)->prev;                                    \
        !           184:        if ((head) == prev) {                                   \
        !           185:                (head)->next = (queue_entry_t) (elt);           \
        !           186:        }                                                       \
        !           187:        else {                                                  \
        !           188:                ((type)prev)->field.next = (queue_entry_t)(elt);\
        !           189:        }                                                       \
        !           190:        (elt)->field.prev = prev;                               \
        !           191:        (elt)->field.next = head;                               \
        !           192:        (head)->prev = (queue_entry_t) elt;                     \
        !           193: }
        !           194: 
        !           195: /*
        !           196:  *     Macro:          queue_enter_first
        !           197:  *     Function:
        !           198:  *             Insert a new element at the head of the queue.
        !           199:  *     Header:
        !           200:  *             void queue_enter_first(q, elt, type, field)
        !           201:  *                     queue_t q;
        !           202:  *                     <type> elt;
        !           203:  *                     <type> is what's in our queue
        !           204:  *                     <field> is the chain field in (*<type>)
        !           205:  */
        !           206: #define queue_enter_first(head, elt, type, field)              \
        !           207: {                                                              \
        !           208:        register queue_entry_t next;                            \
        !           209:                                                                \
        !           210:        next = (head)->next;                                    \
        !           211:        if ((head) == next) {                                   \
        !           212:                (head)->prev = (queue_entry_t) (elt);           \
        !           213:        }                                                       \
        !           214:        else {                                                  \
        !           215:                ((type)next)->field.prev = (queue_entry_t)(elt);\
        !           216:        }                                                       \
        !           217:        (elt)->field.next = next;                               \
        !           218:        (elt)->field.prev = head;                               \
        !           219:        (head)->next = (queue_entry_t) elt;                     \
        !           220: }
        !           221: 
        !           222: /*
        !           223:  *     Macro:          queue_field [internal use only]
        !           224:  *     Function:
        !           225:  *             Find the queue_chain_t (or queue_t) for the
        !           226:  *             given element (thing) in the given queue (head)
        !           227:  */
        !           228: #define        queue_field(head, thing, type, field)                   \
        !           229:                (((head) == (thing)) ? (head) : &((type)(thing))->field)
        !           230: 
        !           231: /*
        !           232:  *     Macro:          queue_remove
        !           233:  *     Function:
        !           234:  *             Remove an arbitrary item from the queue.
        !           235:  *     Header:
        !           236:  *             void queue_remove(q, qe, type, field)
        !           237:  *                     arguments as in queue_enter
        !           238:  */
        !           239: #define        queue_remove(head, elt, type, field)                    \
        !           240: {                                                              \
        !           241:        register queue_entry_t  next, prev;                     \
        !           242:                                                                \
        !           243:        next = (elt)->field.next;                               \
        !           244:        prev = (elt)->field.prev;                               \
        !           245:                                                                \
        !           246:        if ((head) == next)                                     \
        !           247:                (head)->prev = prev;                            \
        !           248:        else                                                    \
        !           249:                ((type)next)->field.prev = prev;                \
        !           250:                                                                \
        !           251:        if ((head) == prev)                                     \
        !           252:                (head)->next = next;                            \
        !           253:        else                                                    \
        !           254:                ((type)prev)->field.next = next;                \
        !           255: }
        !           256: 
        !           257: /*
        !           258:  *     Macro:          queue_remove_first
        !           259:  *     Function:
        !           260:  *             Remove and return the entry at the head of
        !           261:  *             the queue.
        !           262:  *     Header:
        !           263:  *             queue_remove_first(head, entry, type, field)
        !           264:  *             entry is returned by reference
        !           265:  */
        !           266: #define        queue_remove_first(head, entry, type, field)            \
        !           267: {                                                              \
        !           268:        register queue_entry_t  next;                           \
        !           269:                                                                \
        !           270:        (entry) = (type) ((head)->next);                        \
        !           271:        next = (entry)->field.next;                             \
        !           272:                                                                \
        !           273:        if ((head) == next)                                     \
        !           274:                (head)->prev = (head);                          \
        !           275:        else                                                    \
        !           276:                ((type)(next))->field.prev = (head);            \
        !           277:        (head)->next = next;                                    \
        !           278: }
        !           279: 
        !           280: /*
        !           281:  *     Macro:          queue_remove_last
        !           282:  *     Function:
        !           283:  *             Remove and return the entry at the tail of
        !           284:  *             the queue.
        !           285:  *     Header:
        !           286:  *             queue_remove_last(head, entry, type, field)
        !           287:  *             entry is returned by reference
        !           288:  */
        !           289: #define        queue_remove_last(head, entry, type, field)             \
        !           290: {                                                              \
        !           291:        register queue_entry_t  prev;                           \
        !           292:                                                                \
        !           293:        (entry) = (type) ((head)->prev);                        \
        !           294:        prev = (entry)->field.prev;                             \
        !           295:                                                                \
        !           296:        if ((head) == prev)                                     \
        !           297:                (head)->next = (head);                          \
        !           298:        else                                                    \
        !           299:                ((type)(prev))->field.next = (head);            \
        !           300:        (head)->prev = prev;                                    \
        !           301: }
        !           302: 
        !           303: /*
        !           304:  *     Macro:          queue_assign
        !           305:  */
        !           306: #define        queue_assign(to, from, type, field)                     \
        !           307: {                                                              \
        !           308:        ((type)((from)->prev))->field.next = (to);              \
        !           309:        ((type)((from)->next))->field.prev = (to);              \
        !           310:        *to = *from;                                            \
        !           311: }
        !           312: 
        !           313: /*
        !           314:  *     Macro:          queue_iterate
        !           315:  *     Function:
        !           316:  *             iterate over each item in the queue.
        !           317:  *             Generates a 'for' loop, setting elt to
        !           318:  *             each item in turn (by reference).
        !           319:  *     Header:
        !           320:  *             queue_iterate(q, elt, type, field)
        !           321:  *                     queue_t q;
        !           322:  *                     <type> elt;
        !           323:  *                     <type> is what's in our queue
        !           324:  *                     <field> is the chain field in (*<type>)
        !           325:  */
        !           326: #define queue_iterate(head, elt, type, field)                  \
        !           327:        for ((elt) = (type) queue_first(head);                  \
        !           328:             !queue_end((head), (queue_entry_t)(elt));          \
        !           329:             (elt) = (type) queue_next(&(elt)->field))
        !           330: 
        !           331: 
        !           332: 
        !           333: /*----------------------------------------------------------------*/
        !           334: /*
        !           335:  *     Define macros for queues with locks.
        !           336:  */
        !           337: struct mpqueue_head {
        !           338:        struct queue_entry      head;           /* header for queue */
        !           339:        struct slock            lock;           /* lock for queue */
        !           340: };
        !           341: 
        !           342: typedef struct mpqueue_head    mpqueue_head_t;
        !           343: 
        !           344: #define        round_mpq(size)         (size)
        !           345: 
        !           346: #define mpqueue_init(q) \
        !           347:        { \
        !           348:                queue_init(&(q)->head); \
        !           349:                simple_lock_init(&(q)->lock); \
        !           350:        }
        !           351: 
        !           352: #define mpenqueue_tail(q, elt) \
        !           353:                simple_lock(&(q)->lock); \
        !           354:                enqueue_tail(&(q)->head, elt); \
        !           355:                simple_unlock(&(q)->lock);
        !           356: 
        !           357: #define mpdequeue_head(q, elt) \
        !           358:                simple_lock(&(q)->lock); \
        !           359:                if (queue_empty(&(q)->head)) \
        !           360:                        *(elt) = 0; \
        !           361:                else \
        !           362:                        *(elt) = dequeue_head(&(q)->head); \
        !           363:                simple_unlock(&(q)->lock);
        !           364: 
        !           365: /*
        !           366:  *     Old queue stuff, will go away soon.
        !           367:  */
        !           368: 
        !           369: #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.