|
|
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 <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> 1.1.1.2 ! root 51: #endif /* NORMA_IPC */ 1.1 root 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; 1.1.1.2 ! root 73: #endif /* NORMA_IPC */ 1.1 root 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: 1.1.1.2 ! root 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.