Annotation of Gnu-Mach/ipc/ipc_kmsg.h, revision 1.1.1.5

1.1.1.2   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989 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
1.1.1.2   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.2   root       22:  *
1.1       root       23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     File:   ipc/ipc_kmsg.h
                     28:  *     Author: Rich Draves
                     29:  *     Date:   1989
                     30:  *
                     31:  *     Definitions for kernel messages.
                     32:  */
                     33: 
                     34: #ifndef        _IPC_IPC_KMSG_H_
                     35: #define _IPC_IPC_KMSG_H_
                     36: 
                     37: #include <mach/machine/vm_types.h>
                     38: #include <mach/message.h>
                     39: #include <kern/assert.h>
1.1.1.3   root       40: #include <kern/cpu_number.h>
1.1.1.5 ! root       41: #include <kern/macros.h>
1.1       root       42: #include <kern/kalloc.h>
                     43: #include <ipc/ipc_marequest.h>
1.1.1.3   root       44: #include <ipc/ipc_object.h>
                     45: #include <ipc/ipc_types.h>
1.1       root       46: #include <vm/vm_map.h>
                     47: 
                     48: /*
                     49:  *     This structure is only the header for a kmsg buffer;
                     50:  *     the actual buffer is normally larger.  The rest of the buffer
                     51:  *     holds the body of the message.
                     52:  *
                     53:  *     In a kmsg, the port fields hold pointers to ports instead
                     54:  *     of port names.  These pointers hold references.
                     55:  *
                     56:  *     The ikm_header.msgh_remote_port field is the destination
                     57:  *     of the message.
                     58:  */
                     59: 
                     60: typedef struct ipc_kmsg {
                     61:        struct ipc_kmsg *ikm_next, *ikm_prev;
                     62:        vm_size_t ikm_size;
                     63:        ipc_marequest_t ikm_marequest;
                     64:        mach_msg_header_t ikm_header;
                     65: } *ipc_kmsg_t;
                     66: 
                     67: #define        IKM_NULL                ((ipc_kmsg_t) 0)
                     68: 
                     69: #define        IKM_OVERHEAD                                                    \
                     70:                (sizeof(struct ipc_kmsg) - sizeof(mach_msg_header_t))
                     71: 
                     72: #define        ikm_plus_overhead(size) ((vm_size_t)((size) + IKM_OVERHEAD))
                     73: #define        ikm_less_overhead(size) ((mach_msg_size_t)((size) - IKM_OVERHEAD))
                     74: 
1.1.1.4   root       75: #if    MACH_IPC_TEST
1.1       root       76: /*
1.1.1.4   root       77:  *     For debugging.
1.1       root       78:  */
                     79: #define IKM_BOGUS              ((ipc_kmsg_t) 0xffffff10)
                     80: 
1.1.1.4   root       81: #define        ikm_mark_bogus(kmsg)                                            \
                     82: MACRO_BEGIN                                                            \
                     83:        (kmsg)->ikm_next = IKM_BOGUS;                                   \
                     84:        (kmsg)->ikm_prev = IKM_BOGUS;                                   \
                     85: MACRO_END
                     86: 
                     87: #else  /* MACH_IPC_TEST */
                     88: 
                     89: #define        ikm_mark_bogus(kmsg)    ;
                     90: 
                     91: #endif /* MACH_IPC_TEST */
                     92: 
1.1       root       93: /*
                     94:  *     We keep a per-processor cache of kernel message buffers.
                     95:  *     The cache saves the overhead/locking of using kalloc/kfree.
                     96:  *     The per-processor cache seems to miss less than a per-thread cache,
                     97:  *     and it also uses less memory.  Access to the cache doesn't
                     98:  *     require locking.
                     99:  */
                    100: 
                    101: extern ipc_kmsg_t      ipc_kmsg_cache[NCPUS];
                    102: 
                    103: #define ikm_cache()     ipc_kmsg_cache[cpu_number()]
                    104: 
                    105: /*
                    106:  *     The size of the kernel message buffers that will be cached.
                    107:  *     IKM_SAVED_KMSG_SIZE includes overhead; IKM_SAVED_MSG_SIZE doesn't.
1.1.1.4   root      108:  *
                    109:  *     We use the page size for IKM_SAVED_KMSG_SIZE to make sure the
                    110:  *     page is pinned to a single processor.
1.1       root      111:  */
                    112: 
1.1.1.4   root      113: #define        IKM_SAVED_KMSG_SIZE     PAGE_SIZE
1.1       root      114: #define        IKM_SAVED_MSG_SIZE      ikm_less_overhead(IKM_SAVED_KMSG_SIZE)
                    115: 
                    116: #define        ikm_alloc(size)                                                 \
                    117:                ((ipc_kmsg_t) kalloc(ikm_plus_overhead(size)))
                    118: 
                    119: #define        ikm_init(kmsg, size)                                            \
                    120: MACRO_BEGIN                                                            \
                    121:        ikm_init_special((kmsg), ikm_plus_overhead(size));              \
                    122: MACRO_END
                    123: 
                    124: #define        ikm_init_special(kmsg, size)                                    \
                    125: MACRO_BEGIN                                                            \
                    126:        (kmsg)->ikm_size = (size);                                      \
                    127:        (kmsg)->ikm_marequest = IMAR_NULL;                              \
                    128: MACRO_END
                    129: 
                    130: #define        ikm_check_initialized(kmsg, size)                               \
                    131: MACRO_BEGIN                                                            \
                    132:        assert((kmsg)->ikm_size == (size));                             \
                    133:        assert((kmsg)->ikm_marequest == IMAR_NULL);                     \
                    134: MACRO_END
                    135: 
                    136: /*
                    137:  *     Non-positive message sizes are special.  They indicate that
                    138:  *     the message buffer doesn't come from ikm_alloc and
                    139:  *     requires some special handling to free.
                    140:  *
                    141:  *     ipc_kmsg_free is the non-macro form of ikm_free.
                    142:  *     It frees kmsgs of all varieties.
                    143:  */
                    144: 
                    145: #define        IKM_SIZE_NORMA          0
                    146: #define        IKM_SIZE_NETWORK        -1
                    147: 
                    148: #define        ikm_free(kmsg)                                                  \
                    149: MACRO_BEGIN                                                            \
                    150:        register vm_size_t _size = (kmsg)->ikm_size;                    \
                    151:                                                                        \
                    152:        if ((integer_t)_size > 0)                                       \
                    153:                kfree((vm_offset_t) (kmsg), _size);                     \
                    154:        else                                                            \
                    155:                ipc_kmsg_free(kmsg);                                    \
                    156: MACRO_END
                    157: 
                    158: /*
1.1.1.4   root      159:  *     struct ipc_kmsg_queue is defined in ipc/ipc_kmsg_queue.h
1.1       root      160:  */
                    161: 
                    162: #include <ipc/ipc_kmsg_queue.h>
                    163: 
                    164: typedef struct ipc_kmsg_queue *ipc_kmsg_queue_t;
                    165: 
                    166: #define        IKMQ_NULL               ((ipc_kmsg_queue_t) 0)
                    167: 
                    168: 
                    169: #define        ipc_kmsg_queue_init(queue)              \
                    170: MACRO_BEGIN                                    \
                    171:        (queue)->ikmq_base = IKM_NULL;          \
                    172: MACRO_END
                    173: 
                    174: #define        ipc_kmsg_queue_empty(queue)     ((queue)->ikmq_base == IKM_NULL)
                    175: 
                    176: /* Enqueue a kmsg */
                    177: extern void ipc_kmsg_enqueue(
                    178:        ipc_kmsg_queue_t        queue,
                    179:        ipc_kmsg_t              kmsg);
                    180: 
                    181: /* Dequeue and return a kmsg */
                    182: extern ipc_kmsg_t ipc_kmsg_dequeue(
                    183:        ipc_kmsg_queue_t        queue);
                    184: 
                    185: /* Pull a kmsg out of a queue */
                    186: extern void ipc_kmsg_rmqueue(
                    187:        ipc_kmsg_queue_t        queue,
                    188:        ipc_kmsg_t              kmsg);
                    189: 
                    190: #define        ipc_kmsg_queue_first(queue)             ((queue)->ikmq_base)
                    191: 
                    192: /* Return the kmsg following the given kmsg */
                    193: extern ipc_kmsg_t ipc_kmsg_queue_next(
                    194:        ipc_kmsg_queue_t        queue,
                    195:        ipc_kmsg_t              kmsg);
                    196: 
                    197: #define        ipc_kmsg_rmqueue_first_macro(queue, kmsg)                       \
                    198: MACRO_BEGIN                                                            \
                    199:        register ipc_kmsg_t _next;                                      \
                    200:                                                                        \
                    201:        assert((queue)->ikmq_base == (kmsg));                           \
                    202:                                                                        \
                    203:        _next = (kmsg)->ikm_next;                                       \
                    204:        if (_next == (kmsg)) {                                          \
                    205:                assert((kmsg)->ikm_prev == (kmsg));                     \
                    206:                (queue)->ikmq_base = IKM_NULL;                          \
                    207:        } else {                                                        \
                    208:                register ipc_kmsg_t _prev = (kmsg)->ikm_prev;           \
                    209:                                                                        \
                    210:                (queue)->ikmq_base = _next;                             \
                    211:                _next->ikm_prev = _prev;                                \
                    212:                _prev->ikm_next = _next;                                \
                    213:        }                                                               \
1.1.1.4   root      214:        ikm_mark_bogus (kmsg);                                          \
1.1       root      215: MACRO_END
                    216: 
                    217: #define        ipc_kmsg_enqueue_macro(queue, kmsg)                             \
                    218: MACRO_BEGIN                                                            \
                    219:        register ipc_kmsg_t _first = (queue)->ikmq_base;                \
                    220:                                                                        \
                    221:        if (_first == IKM_NULL) {                                       \
                    222:                (queue)->ikmq_base = (kmsg);                            \
                    223:                (kmsg)->ikm_next = (kmsg);                              \
                    224:                (kmsg)->ikm_prev = (kmsg);                              \
                    225:        } else {                                                        \
                    226:                register ipc_kmsg_t _last = _first->ikm_prev;           \
                    227:                                                                        \
                    228:                (kmsg)->ikm_next = _first;                              \
                    229:                (kmsg)->ikm_prev = _last;                               \
                    230:                _first->ikm_prev = (kmsg);                              \
                    231:                _last->ikm_next = (kmsg);                               \
                    232:        }                                                               \
                    233: MACRO_END
                    234: 
                    235: extern void
1.1.1.3   root      236: ipc_kmsg_destroy(ipc_kmsg_t);
1.1       root      237: 
                    238: extern void
1.1.1.3   root      239: ipc_kmsg_clean(ipc_kmsg_t);
1.1       root      240: 
                    241: extern void
1.1.1.3   root      242: ipc_kmsg_free(ipc_kmsg_t);
1.1       root      243: 
                    244: extern mach_msg_return_t
1.1.1.3   root      245: ipc_kmsg_get(mach_msg_header_t *, mach_msg_size_t, ipc_kmsg_t *);
1.1       root      246: 
                    247: extern mach_msg_return_t
1.1.1.3   root      248: ipc_kmsg_get_from_kernel(mach_msg_header_t *, mach_msg_size_t, ipc_kmsg_t *);
1.1       root      249: 
                    250: extern mach_msg_return_t
1.1.1.3   root      251: ipc_kmsg_put(mach_msg_header_t *, ipc_kmsg_t, mach_msg_size_t);
1.1       root      252: 
                    253: extern void
1.1.1.3   root      254: ipc_kmsg_put_to_kernel(mach_msg_header_t *, ipc_kmsg_t, mach_msg_size_t);
1.1       root      255: 
                    256: extern mach_msg_return_t
1.1.1.3   root      257: ipc_kmsg_copyin_header(mach_msg_header_t *, ipc_space_t, mach_port_t);
1.1       root      258: 
                    259: extern mach_msg_return_t
1.1.1.3   root      260: ipc_kmsg_copyin(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_t);
1.1       root      261: 
                    262: extern void
1.1.1.3   root      263: ipc_kmsg_copyin_from_kernel(ipc_kmsg_t);
1.1       root      264: 
                    265: extern mach_msg_return_t
1.1.1.3   root      266: ipc_kmsg_copyout_header(mach_msg_header_t *, ipc_space_t, mach_port_t);
1.1       root      267: 
                    268: extern mach_msg_return_t
1.1.1.3   root      269: ipc_kmsg_copyout_object(ipc_space_t, ipc_object_t,
                    270:                        mach_msg_type_name_t, mach_port_t *);
1.1       root      271: 
                    272: extern mach_msg_return_t
1.1.1.3   root      273: ipc_kmsg_copyout_body(vm_offset_t, vm_offset_t, ipc_space_t, vm_map_t);
1.1       root      274: 
                    275: extern mach_msg_return_t
1.1.1.3   root      276: ipc_kmsg_copyout(ipc_kmsg_t, ipc_space_t, vm_map_t, mach_port_t);
1.1       root      277: 
                    278: extern mach_msg_return_t
1.1.1.3   root      279: ipc_kmsg_copyout_pseudo(ipc_kmsg_t, ipc_space_t, vm_map_t);
1.1       root      280: 
                    281: extern void
1.1.1.3   root      282: ipc_kmsg_copyout_dest(ipc_kmsg_t, ipc_space_t);
1.1       root      283: 
1.1.1.2   root      284: #endif /* _IPC_IPC_KMSG_H_ */

unix.superglobalmegacorp.com

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