|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University.
4: * Copyright (c) 1993,1994 The University of Utah and
5: * the Computer Systems Laboratory (CSL).
6: * All rights reserved.
7: *
8: * Permission to use, copy, modify and distribute this software and its
9: * documentation is hereby granted, provided that both the copyright
10: * notice and this permission notice appear in all copies of the
11: * software, derivative works or modified versions, and any portions
12: * thereof, and that both notices appear in supporting documentation.
13: *
14: * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
15: * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
16: * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
17: * THIS SOFTWARE.
18: *
19: * Carnegie Mellon requests users of this software to return to
20: *
21: * Software Distribution Coordinator or [email protected]
22: * School of Computer Science
23: * Carnegie Mellon University
24: * Pittsburgh PA 15213-3890
25: *
26: * any improvements or extensions that they make and grant Carnegie Mellon
27: * the rights to redistribute these changes.
1.1.1.3 root 28: */
1.1 root 29: /*
30: * File: ipc/ipc_entry.c
31: * Author: Rich Draves
32: * Date: 1989
33: *
34: * Primitive functions to manipulate translation entries.
35: */
36:
1.1.1.3 root 37: #include <kern/printf.h>
38: #include <string.h>
39:
1.1 root 40: #include <mach/kern_return.h>
41: #include <mach/port.h>
42: #include <kern/assert.h>
43: #include <kern/sched_prim.h>
1.1.1.3 root 44: #include <kern/slab.h>
1.1 root 45: #include <ipc/port.h>
46: #include <ipc/ipc_types.h>
47: #include <ipc/ipc_entry.h>
48: #include <ipc/ipc_space.h>
49: #include <ipc/ipc_table.h>
50: #include <ipc/ipc_object.h>
51:
1.1.1.5 ! root 52: struct kmem_cache ipc_entry_cache;
1.1 root 53:
54: /*
55: * Routine: ipc_entry_alloc
56: * Purpose:
57: * Allocate an entry out of the space.
58: * Conditions:
1.1.1.5 ! root 59: * The space must be write-locked. May allocate memory.
1.1 root 60: * Returns:
61: * KERN_SUCCESS An entry was allocated.
62: * KERN_INVALID_TASK The space is dead.
63: * KERN_NO_SPACE No room for an entry in the space.
64: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory for an entry.
65: */
66:
67: kern_return_t
68: ipc_entry_alloc(
69: ipc_space_t space,
70: mach_port_t *namep,
71: ipc_entry_t *entryp)
72: {
73: kern_return_t kr;
1.1.1.5 ! root 74: ipc_entry_t entry;
! 75: rdxtree_key_t key;
1.1 root 76:
1.1.1.5 ! root 77: if (!space->is_active) {
! 78: return KERN_INVALID_TASK;
! 79: }
1.1 root 80:
1.1.1.5 ! root 81: kr = ipc_entry_get(space, namep, entryp);
! 82: if (kr == KERN_SUCCESS)
! 83: return kr;
! 84:
! 85: entry = ie_alloc();
! 86: if (entry == IE_NULL) {
! 87: return KERN_RESOURCE_SHORTAGE;
! 88: }
1.1 root 89:
1.1.1.5 ! root 90: kr = rdxtree_insert_alloc(&space->is_map, entry, &key);
! 91: if (kr) {
! 92: ie_free(entry);
! 93: return kr;
1.1 root 94: }
1.1.1.5 ! root 95: space->is_size += 1;
! 96:
! 97: entry->ie_bits = 0;
! 98: entry->ie_object = IO_NULL;
! 99: entry->ie_request = 0;
! 100: entry->ie_name = (mach_port_t) key;
! 101:
! 102: *entryp = entry;
! 103: *namep = (mach_port_t) key;
! 104: return KERN_SUCCESS;
1.1 root 105: }
106:
107: /*
108: * Routine: ipc_entry_alloc_name
109: * Purpose:
110: * Allocates/finds an entry with a specific name.
111: * If an existing entry is returned, its type will be nonzero.
112: * Conditions:
1.1.1.5 ! root 113: * The space must be write-locked. May allocate memory.
1.1 root 114: * Returns:
115: * KERN_SUCCESS Found existing entry with same name.
116: * KERN_SUCCESS Allocated a new entry.
117: * KERN_INVALID_TASK The space is dead.
118: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
119: */
120:
121: kern_return_t
122: ipc_entry_alloc_name(
123: ipc_space_t space,
124: mach_port_t name,
125: ipc_entry_t *entryp)
126: {
1.1.1.5 ! root 127: kern_return_t kr;
! 128: ipc_entry_t entry, e, *prevp;
! 129: void **slot;
1.1 root 130: assert(MACH_PORT_VALID(name));
131:
1.1.1.5 ! root 132: if (!space->is_active) {
! 133: return KERN_INVALID_TASK;
! 134: }
1.1 root 135:
1.1.1.5 ! root 136: slot = rdxtree_lookup_slot(&space->is_map, (rdxtree_key_t) name);
! 137: if (slot != NULL)
! 138: entry = *(ipc_entry_t *) slot;
! 139:
! 140: if (slot == NULL || entry == IE_NULL) {
! 141: entry = ie_alloc();
! 142: if (entry == IE_NULL) {
! 143: return KERN_RESOURCE_SHORTAGE;
1.1 root 144: }
145:
1.1.1.5 ! root 146: entry->ie_bits = 0;
! 147: entry->ie_object = IO_NULL;
! 148: entry->ie_request = 0;
! 149: entry->ie_name = name;
! 150:
! 151: if (slot != NULL)
! 152: rdxtree_replace_slot(slot, entry);
! 153: else {
! 154: kr = rdxtree_insert(&space->is_map,
! 155: (rdxtree_key_t) name, entry);
1.1 root 156: if (kr != KERN_SUCCESS) {
1.1.1.5 ! root 157: ie_free(entry);
1.1 root 158: return kr;
159: }
160: }
1.1.1.5 ! root 161: space->is_size += 1;
1.1 root 162:
1.1.1.5 ! root 163: *entryp = entry;
! 164: return KERN_SUCCESS;
1.1 root 165: }
166:
1.1.1.5 ! root 167: if (IE_BITS_TYPE(entry->ie_bits)) {
! 168: /* Used entry. */
! 169: *entryp = entry;
! 170: return KERN_SUCCESS;
1.1 root 171: }
172:
1.1.1.5 ! root 173: /* Free entry. Rip the entry out of the free list. */
! 174: for (prevp = &space->is_free_list, e = space->is_free_list;
! 175: e != entry;
! 176: ({ prevp = &e->ie_next_free; e = e->ie_next_free; }))
! 177: continue;
1.1 root 178:
1.1.1.5 ! root 179: *prevp = entry->ie_next_free;
! 180: space->is_free_list_size -= 1;
1.1 root 181:
1.1.1.5 ! root 182: entry->ie_bits = 0;
! 183: assert(entry->ie_object == IO_NULL);
! 184: assert(entry->ie_name == name);
! 185: entry->ie_request = 0;
1.1 root 186:
1.1.1.5 ! root 187: space->is_size += 1;
! 188: *entryp = entry;
1.1 root 189: return KERN_SUCCESS;
190: }
191:
192: #if MACH_KDB
193: #include <ddb/db_output.h>
1.1.1.2 root 194: #include <kern/task.h>
195:
1.1 root 196: #define printf kdbprintf
197:
198: ipc_entry_t
199: db_ipc_object_by_name(
1.1.1.4 root 200: const task_t task,
1.1 root 201: mach_port_t name)
202: {
203: ipc_space_t space = task->itk_space;
204: ipc_entry_t entry;
205:
206:
207: entry = ipc_entry_lookup(space, name);
208: if(entry != IE_NULL) {
209: iprintf("(task 0x%x, name 0x%x) ==> object 0x%x",
210: entry->ie_object);
211: return (ipc_entry_t) entry->ie_object;
212: }
213: return entry;
214: }
215: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.