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