Annotation of sbbs/xpdev/xpsem.c, revision 1.1.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.