Annotation of Gnu-Mach/kern/queue.h, revision 1.1.1.4

1.1.1.2   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.2   root        5:  *
1.1       root        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.
1.1.1.2   root       11:  *
1.1       root       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.
1.1.1.2   root       15:  *
1.1       root       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: 
1.1.1.3   root       82: void           enqueue_head(queue_t, queue_entry_t);
                     83: void           enqueue_tail(queue_t, queue_entry_t);
                     84: queue_entry_t  dequeue_head(queue_t);
                     85: queue_entry_t  dequeue_tail(queue_t);
                     86: void           remqueue(queue_t, queue_entry_t);
                     87: void           insque(queue_entry_t, queue_entry_t);
1.1       root       88: 
                     89: /*
                     90:  *     Macro:          queue_init
                     91:  *     Function:
                     92:  *             Initialize the given queue.
                     93:  *     Header:
                     94:  *             void queue_init(q)
                     95:  *                     queue_t         q;      *MODIFIED*
                     96:  */
                     97: #define        queue_init(q)   ((q)->next = (q)->prev = q)
                     98: 
                     99: /*
                    100:  *     Macro:          queue_first
                    101:  *     Function:
                    102:  *             Returns the first entry in the queue,
                    103:  *     Header:
                    104:  *             queue_entry_t queue_first(q)
                    105:  *                     queue_t q;              *IN*
                    106:  */
                    107: #define        queue_first(q)  ((q)->next)
                    108: 
                    109: /*
                    110:  *     Macro:          queue_next
                    111:  *     Function:
                    112:  *             Returns the entry after an item in the queue.
                    113:  *     Header:
                    114:  *             queue_entry_t queue_next(qc)
                    115:  *                     queue_t qc;
                    116:  */
                    117: #define        queue_next(qc)  ((qc)->next)
                    118: 
                    119: /*
                    120:  *     Macro:          queue_last
                    121:  *     Function:
                    122:  *             Returns the last entry in the queue.
                    123:  *     Header:
                    124:  *             queue_entry_t queue_last(q)
                    125:  *                     queue_t q;               *IN*
                    126:  */
                    127: #define        queue_last(q)   ((q)->prev)
                    128: 
                    129: /*
                    130:  *     Macro:          queue_prev
                    131:  *     Function:
                    132:  *             Returns the entry before an item in the queue.
                    133:  *     Header:
                    134:  *             queue_entry_t queue_prev(qc)
                    135:  *                     queue_t qc;
                    136:  */
                    137: #define        queue_prev(qc)  ((qc)->prev)
                    138: 
                    139: /*
                    140:  *     Macro:          queue_end
                    141:  *     Function:
                    142:  *             Tests whether a new entry is really the end of
                    143:  *             the queue.
                    144:  *     Header:
                    145:  *             boolean_t queue_end(q, qe)
                    146:  *                     queue_t q;
                    147:  *                     queue_entry_t qe;
                    148:  */
                    149: #define        queue_end(q, qe)        ((q) == (qe))
                    150: 
                    151: /*
                    152:  *     Macro:          queue_empty
                    153:  *     Function:
                    154:  *             Tests whether a queue is empty.
                    155:  *     Header:
                    156:  *             boolean_t queue_empty(q)
                    157:  *                     queue_t q;
                    158:  */
                    159: #define        queue_empty(q)          queue_end((q), queue_first(q))
                    160: 
                    161: 
                    162: /*----------------------------------------------------------------*/
                    163: /*
                    164:  * Macros that operate on generic structures.  The queue
                    165:  * chain may be at any location within the structure, and there
                    166:  * may be more than one chain.
                    167:  */
                    168: 
                    169: /*
                    170:  *     Macro:          queue_enter
                    171:  *     Function:
                    172:  *             Insert a new element at the tail of the queue.
                    173:  *     Header:
                    174:  *             void queue_enter(q, elt, type, field)
                    175:  *                     queue_t q;
                    176:  *                     <type> elt;
                    177:  *                     <type> is what's in our queue
                    178:  *                     <field> is the chain field in (*<type>)
                    179:  */
                    180: #define queue_enter(head, elt, type, field)                    \
                    181: {                                                              \
1.1.1.4 ! root      182:        queue_entry_t prev;                                     \
1.1       root      183:                                                                \
                    184:        prev = (head)->prev;                                    \
                    185:        if ((head) == prev) {                                   \
                    186:                (head)->next = (queue_entry_t) (elt);           \
                    187:        }                                                       \
                    188:        else {                                                  \
                    189:                ((type)prev)->field.next = (queue_entry_t)(elt);\
                    190:        }                                                       \
                    191:        (elt)->field.prev = prev;                               \
                    192:        (elt)->field.next = head;                               \
                    193:        (head)->prev = (queue_entry_t) elt;                     \
                    194: }
                    195: 
                    196: /*
                    197:  *     Macro:          queue_enter_first
                    198:  *     Function:
                    199:  *             Insert a new element at the head of the queue.
                    200:  *     Header:
                    201:  *             void queue_enter_first(q, elt, type, field)
                    202:  *                     queue_t q;
                    203:  *                     <type> elt;
                    204:  *                     <type> is what's in our queue
                    205:  *                     <field> is the chain field in (*<type>)
                    206:  */
                    207: #define queue_enter_first(head, elt, type, field)              \
                    208: {                                                              \
1.1.1.4 ! root      209:        queue_entry_t next;                                     \
1.1       root      210:                                                                \
                    211:        next = (head)->next;                                    \
                    212:        if ((head) == next) {                                   \
                    213:                (head)->prev = (queue_entry_t) (elt);           \
                    214:        }                                                       \
                    215:        else {                                                  \
                    216:                ((type)next)->field.prev = (queue_entry_t)(elt);\
                    217:        }                                                       \
                    218:        (elt)->field.next = next;                               \
                    219:        (elt)->field.prev = head;                               \
                    220:        (head)->next = (queue_entry_t) elt;                     \
                    221: }
                    222: 
                    223: /*
                    224:  *     Macro:          queue_field [internal use only]
                    225:  *     Function:
                    226:  *             Find the queue_chain_t (or queue_t) for the
                    227:  *             given element (thing) in the given queue (head)
                    228:  */
                    229: #define        queue_field(head, thing, type, field)                   \
                    230:                (((head) == (thing)) ? (head) : &((type)(thing))->field)
                    231: 
                    232: /*
                    233:  *     Macro:          queue_remove
                    234:  *     Function:
                    235:  *             Remove an arbitrary item from the queue.
                    236:  *     Header:
                    237:  *             void queue_remove(q, qe, type, field)
                    238:  *                     arguments as in queue_enter
                    239:  */
                    240: #define        queue_remove(head, elt, type, field)                    \
                    241: {                                                              \
1.1.1.4 ! root      242:        queue_entry_t   next, prev;                             \
1.1       root      243:                                                                \
                    244:        next = (elt)->field.next;                               \
                    245:        prev = (elt)->field.prev;                               \
                    246:                                                                \
                    247:        if ((head) == next)                                     \
                    248:                (head)->prev = prev;                            \
                    249:        else                                                    \
                    250:                ((type)next)->field.prev = prev;                \
                    251:                                                                \
                    252:        if ((head) == prev)                                     \
                    253:                (head)->next = next;                            \
                    254:        else                                                    \
                    255:                ((type)prev)->field.next = next;                \
                    256: }
                    257: 
                    258: /*
                    259:  *     Macro:          queue_remove_first
                    260:  *     Function:
                    261:  *             Remove and return the entry at the head of
                    262:  *             the queue.
                    263:  *     Header:
                    264:  *             queue_remove_first(head, entry, type, field)
                    265:  *             entry is returned by reference
                    266:  */
                    267: #define        queue_remove_first(head, entry, type, field)            \
                    268: {                                                              \
1.1.1.4 ! root      269:        queue_entry_t   next;                                   \
1.1       root      270:                                                                \
                    271:        (entry) = (type) ((head)->next);                        \
                    272:        next = (entry)->field.next;                             \
                    273:                                                                \
                    274:        if ((head) == next)                                     \
                    275:                (head)->prev = (head);                          \
                    276:        else                                                    \
                    277:                ((type)(next))->field.prev = (head);            \
                    278:        (head)->next = next;                                    \
                    279: }
                    280: 
                    281: /*
                    282:  *     Macro:          queue_remove_last
                    283:  *     Function:
                    284:  *             Remove and return the entry at the tail of
                    285:  *             the queue.
                    286:  *     Header:
                    287:  *             queue_remove_last(head, entry, type, field)
                    288:  *             entry is returned by reference
                    289:  */
                    290: #define        queue_remove_last(head, entry, type, field)             \
                    291: {                                                              \
1.1.1.4 ! root      292:        queue_entry_t   prev;                                   \
1.1       root      293:                                                                \
                    294:        (entry) = (type) ((head)->prev);                        \
                    295:        prev = (entry)->field.prev;                             \
                    296:                                                                \
                    297:        if ((head) == prev)                                     \
                    298:                (head)->next = (head);                          \
                    299:        else                                                    \
                    300:                ((type)(prev))->field.next = (head);            \
                    301:        (head)->prev = prev;                                    \
                    302: }
                    303: 
                    304: /*
                    305:  *     Macro:          queue_assign
                    306:  */
                    307: #define        queue_assign(to, from, type, field)                     \
                    308: {                                                              \
                    309:        ((type)((from)->prev))->field.next = (to);              \
                    310:        ((type)((from)->next))->field.prev = (to);              \
                    311:        *to = *from;                                            \
                    312: }
                    313: 
                    314: /*
                    315:  *     Macro:          queue_iterate
                    316:  *     Function:
                    317:  *             iterate over each item in the queue.
                    318:  *             Generates a 'for' loop, setting elt to
                    319:  *             each item in turn (by reference).
                    320:  *     Header:
                    321:  *             queue_iterate(q, elt, type, field)
                    322:  *                     queue_t q;
                    323:  *                     <type> elt;
                    324:  *                     <type> is what's in our queue
                    325:  *                     <field> is the chain field in (*<type>)
                    326:  */
                    327: #define queue_iterate(head, elt, type, field)                  \
                    328:        for ((elt) = (type) queue_first(head);                  \
                    329:             !queue_end((head), (queue_entry_t)(elt));          \
                    330:             (elt) = (type) queue_next(&(elt)->field))
                    331: 
                    332: 
                    333: 
                    334: /*----------------------------------------------------------------*/
                    335: /*
                    336:  *     Define macros for queues with locks.
                    337:  */
                    338: struct mpqueue_head {
                    339:        struct queue_entry      head;           /* header for queue */
                    340:        struct slock            lock;           /* lock for queue */
                    341: };
                    342: 
                    343: typedef struct mpqueue_head    mpqueue_head_t;
                    344: 
                    345: #define        round_mpq(size)         (size)
                    346: 
                    347: #define mpqueue_init(q) \
                    348:        { \
                    349:                queue_init(&(q)->head); \
                    350:                simple_lock_init(&(q)->lock); \
                    351:        }
                    352: 
                    353: #define mpenqueue_tail(q, elt) \
                    354:                simple_lock(&(q)->lock); \
                    355:                enqueue_tail(&(q)->head, elt); \
                    356:                simple_unlock(&(q)->lock);
                    357: 
                    358: #define mpdequeue_head(q, elt) \
                    359:                simple_lock(&(q)->lock); \
                    360:                if (queue_empty(&(q)->head)) \
                    361:                        *(elt) = 0; \
                    362:                else \
                    363:                        *(elt) = dequeue_head(&(q)->head); \
                    364:                simple_unlock(&(q)->lock);
                    365: 
                    366: /*
                    367:  *     Old queue stuff, will go away soon.
                    368:  */
                    369: 
1.1.1.2   root      370: #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.