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

Annotation of prex-old/sys/sync/cond.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:  * cond.c - condition variable object
                     32:  */
                     33:
                     34: #include <kernel.h>
                     35: #include <sched.h>
                     36: #include <kmem.h>
                     37: #include <thread.h>
                     38: #include <sync.h>
                     39:
                     40: /*
                     41:  * Create and initialize a condition variable (CV).
                     42:  *
                     43:  * If an initialized condition variable is reinitialized, undefined
                     44:  * behavior results.
                     45:  */
                     46: int
                     47: cond_init(cond_t *cond)
                     48: {
                     49:        cond_t c;
                     50:
                     51:        if ((c = kmem_alloc(sizeof(struct cond))) == NULL)
                     52:                return ENOMEM;
                     53:
                     54:        event_init(&c->event, "condition");
                     55:        c->task = cur_task();
                     56:        c->magic = COND_MAGIC;
                     57:
                     58:        if (umem_copyout(&c, cond, sizeof(cond_t))) {
                     59:                kmem_free(c);
                     60:                return EFAULT;
                     61:        }
                     62:        return 0;
                     63: }
                     64:
                     65: /*
                     66:  * cond_copyin - copy a condition variable from user space.
                     67:  * @uc: pointer to cv in user space.
                     68:  * @kc: pointer to cv in kernel space.
                     69:  *
                     70:  * It also checks if the passed CV is valid.
                     71:  */
                     72: static int
                     73: cond_copyin(cond_t *ucond, cond_t *kcond)
                     74: {
                     75:        cond_t c;
                     76:
                     77:        if (umem_copyin(ucond, &c, sizeof(cond_t)))
                     78:                return EFAULT;
                     79:        if (!cond_valid(c))
                     80:                return EINVAL;
                     81:        *kcond = c;
                     82:        return 0;
                     83: }
                     84:
                     85: /*
                     86:  * Destroy a condition variable.
                     87:  * If there are any blocked thread waiting for the specified CV,
                     88:  * it returns EBUSY.
                     89:  */
                     90: int
                     91: cond_destroy(cond_t *cond)
                     92: {
                     93:        cond_t c;
                     94:        int err;
                     95:
                     96:        sched_lock();
                     97:        if ((err = cond_copyin(cond, &c))) {
                     98:                sched_unlock();
                     99:                return err;
                    100:        }
                    101:        if (event_waiting(&c->event)) {
                    102:                sched_unlock();
                    103:                return EBUSY;
                    104:        }
                    105:        c->magic = 0;
                    106:        kmem_free(c);
                    107:        sched_unlock();
                    108:        return 0;
                    109: }
                    110:
                    111: /*
                    112:  * Wait on a condition.
                    113:  *
                    114:  * If the thread receives any exception while waiting CV, this
                    115:  * routine returns immediately with EINTR in order to invoke
                    116:  * exception handler. However, an application assumes this call
                    117:  * does NOT return with an error. So, the stub routine in a system
                    118:  * call library must call cond_wait() again if it gets EINTR as error.
                    119:  */
                    120: int
                    121: cond_wait(cond_t *cond, mutex_t *mtx)
                    122: {
                    123:        cond_t c;
                    124:        int err, rc;
                    125:
                    126:        if (umem_copyin(cond, &c, sizeof(cond_t)))
                    127:                return EFAULT;
                    128:
                    129:        sched_lock();
                    130:        if (c == COND_INITIALIZER) {
                    131:                if ((err = cond_init(cond))) {
                    132:                        sched_unlock();
                    133:                        return err;
                    134:                }
                    135:                umem_copyin(cond, &c, sizeof(cond_t));
                    136:        } else {
                    137:                if (!cond_valid(c)) {
                    138:                        sched_unlock();
                    139:                        return EINVAL;
                    140:                }
                    141:        }
                    142:        if ((err = mutex_unlock(mtx))) {
                    143:                sched_unlock();
                    144:                return err;
                    145:        }
                    146:
                    147:        rc = sched_sleep(&c->event);
                    148:        if (rc == SLP_INTR)
                    149:                err = EINTR;
                    150:        sched_unlock();
                    151:
                    152:        if (err == 0)
                    153:                err = mutex_lock(mtx);
                    154:        return err;
                    155: }
                    156:
                    157: /*
                    158:  * Unblock one thread that is blocked on the specified CV.
                    159:  * The thread which has highest priority will be unblocked.
                    160:  */
                    161: int
                    162: cond_signal(cond_t *cond)
                    163: {
                    164:        cond_t c;
                    165:        int err;
                    166:
                    167:        sched_lock();
                    168:        if ((err = cond_copyin(cond, &c)) == 0)
                    169:                sched_wakeone(&c->event);
                    170:        sched_unlock();
                    171:        return err;
                    172: }
                    173:
                    174: /*
                    175:  * Unblock all threads that are blocked on the specified CV.
                    176:  */
                    177: int
                    178: cond_broadcast(cond_t *cond)
                    179: {
                    180:        cond_t c;
                    181:        int err;
                    182:
                    183:        sched_lock();
                    184:        if ((err = cond_copyin(cond, &c)) == 0)
                    185:                sched_wakeup(&c->event);
                    186:        sched_unlock();
                    187:        return err;
                    188: }

CVSweb