2 * Copyright (c) 2005-2007, Kohsuke Ohtani
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * object.c - object service
35 * An object represents service, state, or policies etc. To manipulate
36 * objects, kernel provide 3 functions: create, delete, lookup.
37 * Prex task will create an object to provide its interface to other tasks.
38 * The tasks will communicate by sending a message to the object each other.
39 * For example, a server task creates some objects and client task will send
40 * a request message to it.
42 * A substance of object is stored in kernel space, and it is protected
43 * from user mode code. Each object data is managed with the hash table
44 * by using its name string. Usually, an object has a unique name within
45 * a system. Before a task sends a message to the specific object, it must
46 * obtain the object ID by looking up the name of the target object.
48 * An object can be created without its name. These object can be used as
49 * private objects that are used by threads in same task.
60 #define OBJ_MAXBUCKETS 64 /* Size of object hash buckets */
65 * All objects are hashed by its name string. If an object has no
66 * name, it is linked to index zero.
67 * The scheduler must be locked when this table is modified.
69 static struct list obj_table
[OBJ_MAXBUCKETS
];
72 * Calculate the hash index for specified name string.
73 * The name can be NULL if the object does not have name.
75 static u_int
object_hash(const char *name
)
82 h
= ((h
<< 5) + h
) + *name
++;
83 return h
& (OBJ_MAXBUCKETS
- 1);
87 * Find an object from the specified name.
89 static object_t
object_find(char *name
)
94 head
= &obj_table
[object_hash(name
)];
95 for (n
= list_first(head
); n
!= head
; n
= list_next(n
)) {
96 obj
= list_entry(n
, struct object
, name_link
);
97 ASSERT(obj
->magic
== OBJECT_MAGIC
);
98 if (!strncmp(obj
->name
, name
, MAX_OBJNAME
))
107 * Search an object in the object name space. The object name must
108 * be null-terminated string. The object ID is returned in obj on
111 __syscall
int object_lookup(char *name
, object_t
*pobj
)
115 char str
[MAX_OBJNAME
];
117 if (umem_strnlen(name
, MAX_OBJNAME
, &len
))
119 if (len
== 0 || len
>= MAX_OBJNAME
)
121 if (umem_copyin(name
, str
, len
+ 1))
125 obj
= object_find(str
);
129 if (umem_copyout(&obj
, pobj
, sizeof(object_t
)))
135 * Create a new object.
137 * The ID of the new object is stored in obj on success.
138 * The name of the object must be unique in the system. Or, the
139 * object can be created without name by setting NULL as name
140 * argument. This object can be used as a private object which
141 * can be accessed only by threads in same task.
143 __syscall
int object_create(char *name
, object_t
*pobj
)
146 char str
[MAX_OBJNAME
];
150 if (umem_strnlen(name
, MAX_OBJNAME
, &len
))
152 if (len
>= MAX_OBJNAME
)
154 if (umem_copyin(name
, str
, len
+ 1))
161 * Check user buffer first. This can reduce the error
162 * recovery for the following resource allocations.
164 if (umem_copyout(&obj
, pobj
, sizeof(object_t
))) {
168 if ((obj
= object_find(str
)) != NULL
) {
172 if ((obj
= kmem_alloc(sizeof(struct object
))) == NULL
) {
177 obj
->name
= kmem_alloc(len
+ 1);
178 if (obj
->name
== NULL
) {
183 strlcpy(obj
->name
, str
, len
+ 1);
185 queue_init(&obj
->sendq
);
186 queue_init(&obj
->recvq
);
187 obj
->owner
= cur_task();
188 obj
->magic
= OBJECT_MAGIC
;
189 list_insert(&obj_table
[object_hash(name
)], &obj
->name_link
);
190 list_insert(&(cur_task()->objects
), &obj
->task_link
);
192 umem_copyout(&obj
, pobj
, sizeof(object_t
));
200 * A thread can delete the object only when the target object is created
201 * by the thread of the same task. All pending messages related to the
202 * deleted object are automatically canceled.
204 __syscall
int object_delete(object_t obj
)
207 if (!object_valid(obj
)) {
211 if (obj
->owner
!= cur_task()) {
218 list_remove(&obj
->task_link
);
219 list_remove(&obj
->name_link
);
220 if (obj
->name
!= NULL
)
221 kmem_free(obj
->name
);
227 #if defined(DEBUG) && defined(CONFIG_KDUMP)
228 void object_dump(void)
234 printk("Object dump:\n");
235 printk(" object owner task name\n");
236 printk(" -------- ---------- ----------------\n");
238 for (i
= 0; i
< OBJ_MAXBUCKETS
; i
++) {
239 head
= &obj_table
[i
];
240 for (n
= list_first(head
); n
!= head
; n
= list_next(n
)) {
241 obj
= list_entry(n
, struct object
, name_link
);
242 printk(" %08x %08x %s\n", obj
, obj
->owner
,
243 (obj
->name
? obj
->name
: "NoName"));
249 void object_init(void)
253 /* Initialize object lookup table */
254 for (i
= 0; i
< OBJ_MAXBUCKETS
; i
++)
255 list_init(&obj_table
[i
]);