Annotation of sbbs/xpdev/xpsem.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * $Id: xpsem.c,v 1.6 2003/05/08 18:17:49 deuce Exp $
        !             3:  *
        !             4:  * Copyright (C) 2000 Jason Evans <[email protected]>.
        !             5:  * All rights reserved.
        !             6:  * 
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice(s), this list of conditions and the following disclaimer as
        !            12:  *    the first lines of this file unmodified other than the possible
        !            13:  *    addition of one or more copyright notices.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice(s), this list of conditions and the following disclaimer in
        !            16:  *    the documentation and/or other materials provided with the
        !            17:  *    distribution.
        !            18:  * 
        !            19:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
        !            20:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
        !            23:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
        !            26:  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
        !            27:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
        !            28:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
        !            29:  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            30:  *
        !            31:  * $FreeBSD: src/lib/libc_r/uthread/uthread_sem.c,v 1.3.2.1 2000/07/18 02:05:57 jasone Exp $
        !            32:  */
        !            33: 
        !            34: #include <errno.h>
        !            35: #include "xpsem.h"
        !            36: #include <pthread.h>
        !            37: #include <sys/time.h>
        !            38: #include <stdlib.h>
        !            39: 
        !            40: int
        !            41: xp_sem_init(xp_sem_t *sem, int pshared, unsigned int value)
        !            42: {
        !            43:        int     retval;
        !            44: 
        !            45:        /*
        !            46:         * Range check the arguments.
        !            47:         */
        !            48:        if (pshared != 0) {
        !            49:                /*
        !            50:                 * The user wants a semaphore that can be shared among
        !            51:                 * processes, which this implementation can't do.  Sounds like a
        !            52:                 * permissions problem to me (yeah right).
        !            53:                 */
        !            54:                errno = EPERM;
        !            55:                retval = -1;
        !            56:                goto RETURN;
        !            57:        }
        !            58: 
        !            59:        if (value > SEM_VALUE_MAX) {
        !            60:                errno = EINVAL;
        !            61:                retval = -1;
        !            62:                goto RETURN;
        !            63:        }
        !            64: 
        !            65:        *sem = (xp_sem_t)malloc(sizeof(struct xp_sem));
        !            66:        if (*sem == NULL) {
        !            67:                errno = ENOSPC;
        !            68:                retval = -1;
        !            69:                goto RETURN;
        !            70:        }
        !            71: 
        !            72:        /*
        !            73:         * Initialize the semaphore.
        !            74:         */
        !            75:        if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) {
        !            76:                free(*sem);
        !            77:                errno = ENOSPC;
        !            78:                retval = -1;
        !            79:                goto RETURN;
        !            80:        }
        !            81: 
        !            82:        if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) {
        !            83:                pthread_mutex_destroy(&(*sem)->lock);
        !            84:                free(*sem);
        !            85:                errno = ENOSPC;
        !            86:                retval = -1;
        !            87:                goto RETURN;
        !            88:        }
        !            89:        
        !            90:        (*sem)->count = (u_int32_t)value;
        !            91:        (*sem)->nwaiters = 0;
        !            92:        (*sem)->magic = SEM_MAGIC;
        !            93: 
        !            94:        retval = 0;
        !            95:   RETURN:
        !            96:        return retval;
        !            97: }
        !            98: 
        !            99: int
        !           100: xp_sem_destroy(xp_sem_t *sem)
        !           101: {
        !           102:        int     retval;
        !           103:        
        !           104:        _SEM_CHECK_VALIDITY(sem);
        !           105: 
        !           106:        /* Make sure there are no waiters. */
        !           107:        pthread_mutex_lock(&(*sem)->lock);
        !           108:        if ((*sem)->nwaiters > 0) {
        !           109:                pthread_mutex_unlock(&(*sem)->lock);
        !           110:                errno = EBUSY;
        !           111:                retval = -1;
        !           112:                goto RETURN;
        !           113:        }
        !           114:        pthread_mutex_unlock(&(*sem)->lock);
        !           115:        
        !           116:        pthread_mutex_destroy(&(*sem)->lock);
        !           117:        pthread_cond_destroy(&(*sem)->gtzero);
        !           118:        (*sem)->magic = 0;
        !           119: 
        !           120:        free(*sem);
        !           121: 
        !           122:        retval = 0;
        !           123:   RETURN:
        !           124:        return retval;
        !           125: }
        !           126: 
        !           127: xp_sem_t *
        !           128: xp_sem_open(const char *name, int oflag, ...)
        !           129: {
        !           130:        errno = ENOSYS;
        !           131:        return SEM_FAILED;
        !           132: }
        !           133: 
        !           134: int
        !           135: xp_sem_close(xp_sem_t *sem)
        !           136: {
        !           137:        errno = ENOSYS;
        !           138:        return -1;
        !           139: }
        !           140: 
        !           141: int
        !           142: xp_sem_unlink(const char *name)
        !           143: {
        !           144:        errno = ENOSYS;
        !           145:        return -1;
        !           146: }
        !           147: 
        !           148: int
        !           149: xp_sem_wait(xp_sem_t *sem)
        !           150: {
        !           151:        int     retval;
        !           152: 
        !           153:        pthread_testcancel();
        !           154:        
        !           155:        _SEM_CHECK_VALIDITY(sem);
        !           156: 
        !           157:        pthread_mutex_lock(&(*sem)->lock);
        !           158: 
        !           159:        while ((*sem)->count == 0) {
        !           160:                (*sem)->nwaiters++;
        !           161:                pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
        !           162:                (*sem)->nwaiters--;
        !           163:        }
        !           164:        (*sem)->count--;
        !           165: 
        !           166:        pthread_mutex_unlock(&(*sem)->lock);
        !           167: 
        !           168:        retval = 0;
        !           169:   RETURN:
        !           170: 
        !           171:        pthread_testcancel();
        !           172:        return retval;
        !           173: }
        !           174: 
        !           175: int
        !           176: xp_sem_trywait(xp_sem_t *sem)
        !           177: {
        !           178:        int     retval;
        !           179: 
        !           180:        _SEM_CHECK_VALIDITY(sem);
        !           181: 
        !           182:        pthread_mutex_lock(&(*sem)->lock);
        !           183: 
        !           184:        if ((*sem)->count > 0) {
        !           185:                (*sem)->count--;
        !           186:                retval = 0;
        !           187:        } else {
        !           188:                errno = EAGAIN;
        !           189:                retval = -1;
        !           190:        }
        !           191:        
        !           192:        pthread_mutex_unlock(&(*sem)->lock);
        !           193: 
        !           194:   RETURN:
        !           195:        return retval;
        !           196: }
        !           197: 
        !           198: int
        !           199: xp_sem_post(xp_sem_t *sem)
        !           200: {
        !           201:        int     retval;
        !           202: 
        !           203:        _SEM_CHECK_VALIDITY(sem);
        !           204: 
        !           205:        pthread_mutex_lock(&(*sem)->lock);
        !           206: 
        !           207:        (*sem)->count++;
        !           208:        if ((*sem)->nwaiters > 0) {
        !           209:                /*
        !           210:                 * We must use pthread_cond_broadcast() rather than
        !           211:                 * pthread_cond_signal() in order to assure that the highest
        !           212:                 * priority thread is run by the scheduler, since
        !           213:                 * pthread_cond_signal() signals waiting threads in FIFO order.
        !           214:                 */
        !           215:                pthread_cond_broadcast(&(*sem)->gtzero);
        !           216:        }
        !           217: 
        !           218:        pthread_mutex_unlock(&(*sem)->lock);
        !           219: 
        !           220:        retval = 0;
        !           221:   RETURN:
        !           222:        return retval;
        !           223: }
        !           224: 
        !           225: int
        !           226: xp_sem_getvalue(xp_sem_t *sem, int *sval)
        !           227: {
        !           228:        int     retval;
        !           229: 
        !           230:        _SEM_CHECK_VALIDITY(sem);
        !           231: 
        !           232:        pthread_mutex_lock(&(*sem)->lock);
        !           233:        *sval = (int)(*sem)->count;
        !           234:        pthread_mutex_unlock(&(*sem)->lock);
        !           235: 
        !           236:        retval = 0;
        !           237:   RETURN:
        !           238:        return retval;
        !           239: }
        !           240: 
        !           241: int
        !           242: xp_sem_timedwait(xp_sem_t *sem, const struct timespec *abs_timeout)
        !           243: {
        !           244:        int     retval=0;
        !           245: 
        !           246:        pthread_testcancel();
        !           247:        
        !           248:        _SEM_CHECK_VALIDITY(sem);
        !           249: 
        !           250:        pthread_mutex_lock(&(*sem)->lock);
        !           251: 
        !           252:        while ((*sem)->count == 0) {
        !           253:                (*sem)->nwaiters++;
        !           254:                retval=pthread_cond_timedwait(&(*sem)->gtzero, &(*sem)->lock, abs_timeout);
        !           255:                (*sem)->nwaiters--;
        !           256:                if(retval)  {
        !           257:                        errno=retval;
        !           258:                        retval=-1;
        !           259:                        break;
        !           260:                }
        !           261:        }
        !           262:        if(retval==0)
        !           263:                (*sem)->count--;
        !           264: 
        !           265:        pthread_mutex_unlock(&(*sem)->lock);
        !           266: 
        !           267:   RETURN:
        !           268: 
        !           269:        pthread_testcancel();
        !           270:        return retval;
        !           271: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.