[BACK]Return to object.c CVS log [TXT][DIR] Up to [local] / prex-old / sys / ipc

Annotation of prex-old/sys/ipc/object.c, Revision 1.1.1.1

1.1       nbrk        1: /*-
                      2:  * Copyright (c) 2005-2007, Kohsuke Ohtani
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      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.
                     16:  *
                     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
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
                     31:  * object.c - object service
                     32:  */
                     33:
                     34: /*
                     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
                     38:  * tasks. The tasks will communicate by sending a message to the object
                     39:  * each other. For example, a server task creates some objects and client
                     40:  * task will send a request message to it.
                     41:  *
                     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.
                     47:  *
                     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.
                     50:  */
                     51:
                     52: #include <kernel.h>
                     53: #include <queue.h>
                     54: #include <kmem.h>
                     55: #include <sched.h>
                     56: #include <task.h>
                     57: #include <ipc.h>
                     58:
                     59: #define OBJ_MAXBUCKETS 32      /* Size of object hash buckets */
                     60:
                     61: /*
                     62:  * Object hash table
                     63:  *
                     64:  * All objects are hashed by its name string. If an object has no
                     65:  * name, it is linked to index zero.
                     66:  * The scheduler must be locked when this table is touched.
                     67:  */
                     68: static struct list obj_table[OBJ_MAXBUCKETS];
                     69:
                     70: /*
                     71:  * Calculate the hash index for specified name string.
                     72:  * The name can be NULL if the object does not have name.
                     73:  */
                     74: static u_int
                     75: object_hash(const char *name)
                     76: {
                     77:        u_int h = 0;
                     78:
                     79:        if (name == NULL)
                     80:                return 0;
                     81:        while (*name)
                     82:                h = ((h << 5) + h) + *name++;
                     83:        return h & (OBJ_MAXBUCKETS - 1);
                     84: }
                     85:
                     86: /*
                     87:  * Helper function to find the object from the specified name.
                     88:  * Returns NULL if not found.
                     89:  */
                     90: static object_t
                     91: object_find(const char *name)
                     92: {
                     93:        list_t head, n;
                     94:        object_t obj = NULL;
                     95:
                     96:        head = &obj_table[object_hash(name)];
                     97:        for (n = list_first(head); n != head; n = list_next(n)) {
                     98:                obj = list_entry(n, struct object, name_link);
                     99:                ASSERT(obj->magic == OBJECT_MAGIC);
                    100:                if (!strncmp(obj->name, name, MAXOBJNAME))
                    101:                        break;
                    102:        }
                    103:        if (n == head)
                    104:                return NULL;
                    105:        return obj;
                    106: }
                    107:
                    108: /*
                    109:  * Search an object in the object name space. The object name must
                    110:  * be null-terminated string. The object ID is returned in obj
                    111:  * on success.
                    112:  */
                    113: int
                    114: object_lookup(const char *name, object_t *objp)
                    115: {
                    116:        object_t obj;
                    117:        size_t len;
                    118:        char str[MAXOBJNAME];
                    119:
                    120:        if (umem_strnlen(name, MAXOBJNAME, &len))
                    121:                return EFAULT;
                    122:        if (len == 0 || len >= MAXOBJNAME)
                    123:                return ESRCH;
                    124:        if (umem_copyin((void *)name, str, len + 1))
                    125:                return EFAULT;
                    126:
                    127:        sched_lock();
                    128:        obj = object_find(str);
                    129:        sched_unlock();
                    130:
                    131:        if (obj == NULL)
                    132:                return ENOENT;
                    133:        if (umem_copyout(&obj, objp, sizeof(object_t)))
                    134:                return EFAULT;
                    135:        return 0;
                    136: }
                    137:
                    138: /*
                    139:  * Create a new object.
                    140:  *
                    141:  * The ID of the new object is stored in pobj on success.
                    142:  * The name of the object must be unique in the system. Or, the
                    143:  * object can be created without name by setting NULL as name
                    144:  * argument. This object can be used as a private object which
                    145:  * can be accessed only by threads in same task.
                    146:  */
                    147: int
                    148: object_create(const char *name, object_t *objp)
                    149: {
                    150:        object_t obj = 0;
                    151:        char str[MAXOBJNAME];
                    152:        size_t len;
                    153:
                    154:        if (name != NULL) {
                    155:                if (umem_strnlen(name, MAXOBJNAME, &len))
                    156:                        return EFAULT;
                    157:                if (len >= MAXOBJNAME)
                    158:                        return ENAMETOOLONG;
                    159:                if (umem_copyin((void *)name, str, len + 1))
                    160:                        return EFAULT;
                    161:                str[len] = '\0';
                    162:        }
                    163:        sched_lock();
                    164:
                    165:        /*
                    166:         * Check user buffer first. This can reduce the error
                    167:         * recovery for the subsequence resource allocations.
                    168:         */
                    169:        if (umem_copyout(&obj, objp, sizeof(object_t))) {
                    170:                sched_unlock();
                    171:                return EFAULT;
                    172:        }
                    173:        if (object_find(str) != NULL) {
                    174:                sched_unlock();
                    175:                return EEXIST;
                    176:        }
                    177:        if ((obj = kmem_alloc(sizeof(struct object))) == NULL) {
                    178:                sched_unlock();
                    179:                return ENOMEM;
                    180:        }
                    181:        if (name != NULL)
                    182:                strlcpy(obj->name, str, len + 1);
                    183:
                    184:        queue_init(&obj->sendq);
                    185:        queue_init(&obj->recvq);
                    186:        obj->owner = cur_task();
                    187:        obj->magic = OBJECT_MAGIC;
                    188:        list_insert(&obj_table[object_hash(name)], &obj->name_link);
                    189:        list_insert(&(cur_task()->objects), &obj->task_link);
                    190:
                    191:        umem_copyout(&obj, objp, sizeof(object_t));
                    192:        sched_unlock();
                    193:        return 0;
                    194: }
                    195:
                    196: /*
                    197:  * Destroy an object.
                    198:  *
                    199:  * A thread can delete the object only when the target object is
                    200:  * created by the thread of the same task.
                    201:  * All pending messages related to the deleted object are
                    202:  * automatically canceled.
                    203:  */
                    204: int
                    205: object_destroy(object_t obj)
                    206: {
                    207:        int err = 0;
                    208:
                    209:        sched_lock();
                    210:        if (!object_valid(obj)) {
                    211:                err = EINVAL;
                    212:        }
                    213:        else if (obj->owner != cur_task()) {
                    214:                err = EACCES;
                    215:        }
                    216:        else {
                    217:                obj->magic = 0;
                    218:                msg_cancel(obj);
                    219:                list_remove(&obj->task_link);
                    220:                list_remove(&obj->name_link);
                    221:                kmem_free(obj);
                    222:        }
                    223:        sched_unlock();
                    224:        return err;
                    225: }
                    226:
                    227: #if defined(DEBUG) && defined(CONFIG_KDUMP)
                    228: void
                    229: object_dump(void)
                    230: {
                    231:        int i;
                    232:        list_t head, n;
                    233:        object_t obj;
                    234:
                    235:        printk("Object dump:\n");
                    236:        printk(" object   owner task name\n");
                    237:        printk(" -------- ---------- ----------------\n");
                    238:
                    239:        for (i = 0; i < OBJ_MAXBUCKETS; i++) {
                    240:                head = &obj_table[i];
                    241:                for (n = list_first(head); n != head; n = list_next(n)) {
                    242:                        obj = list_entry(n, struct object, name_link);
                    243:                        printk(" %08x %08x   %s\n", obj, obj->owner,
                    244:                               (obj->name ? obj->name : "NoName"));
                    245:                }
                    246:        }
                    247: }
                    248: #endif
                    249:
                    250: void
                    251: object_init(void)
                    252: {
                    253:        int i;
                    254:
                    255:        for (i = 0; i < OBJ_MAXBUCKETS; i++)
                    256:                list_init(&obj_table[i]);
                    257: }

CVSweb