Annotation of sbbs/src/xpdev/xpsem.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * $Id: xpsem.c,v 1.12 2005/10/21 21:44:23 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: #include "gen_defs.h"
                     40: #include "genwrap.h"
                     41: 
                     42: int
                     43: xp_sem_init(xp_sem_t *sem, int pshared, unsigned int value)
                     44: {
                     45:        int     retval;
                     46: 
                     47:        /*
                     48:         * Range check the arguments.
                     49:         */
                     50:        if (pshared != 0) {
                     51:                /*
                     52:                 * The user wants a semaphore that can be shared among
                     53:                 * processes, which this implementation can't do.  Sounds like a
                     54:                 * permissions problem to me (yeah right).
                     55:                 */
                     56:                errno = EPERM;
                     57:                retval = -1;
                     58:                goto RETURN;
                     59:        }
                     60: 
                     61:        if (value > XP_SEM_VALUE_MAX) {
                     62:                errno = EINVAL;
                     63:                retval = -1;
                     64:                goto RETURN;
                     65:        }
                     66: 
                     67:        *sem = (xp_sem_t)malloc(sizeof(struct xp_sem));
                     68:        if (*sem == NULL) {
                     69:                errno = ENOSPC;
                     70:                retval = -1;
                     71:                goto RETURN;
                     72:        }
                     73: 
                     74:        /*
                     75:         * Initialize the semaphore.
                     76:         */
                     77:        if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) {
                     78:                free(*sem);
                     79:                errno = ENOSPC;
                     80:                retval = -1;
                     81:                goto RETURN;
                     82:        }
                     83: 
                     84:        if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) {
                     85:                while(pthread_mutex_destroy(&(*sem)->lock)==EBUSY)
                     86:                        SLEEP(1);
                     87:                free(*sem);
                     88:                errno = ENOSPC;
                     89:                retval = -1;
                     90:                goto RETURN;
                     91:        }
                     92:        
                     93:        (*sem)->count = (u_int32_t)value;
                     94:        (*sem)->nwaiters = 0;
                     95:        (*sem)->magic = XP_SEM_MAGIC;
                     96: 
                     97:        retval = 0;
                     98:   RETURN:
                     99:        return retval;
                    100: }
                    101: 
                    102: int
                    103: xp_sem_destroy(xp_sem_t *sem)
                    104: {
                    105:        int     retval;
                    106:        
                    107:        _SEM_CHECK_VALIDITY(sem);
                    108: 
                    109:        /* Make sure there are no waiters. */
                    110:        pthread_mutex_lock(&(*sem)->lock);
                    111:        if ((*sem)->nwaiters > 0) {
                    112:                pthread_mutex_unlock(&(*sem)->lock);
                    113:                errno = EBUSY;
                    114:                retval = -1;
                    115:                goto RETURN;
                    116:        }
                    117:        pthread_mutex_unlock(&(*sem)->lock);
                    118:        
                    119:        while(pthread_mutex_destroy(&(*sem)->lock)==EBUSY)
                    120:                SLEEP(1);
                    121:        while(pthread_cond_destroy(&(*sem)->gtzero)==EBUSY)
                    122:                SLEEP(1);
                    123:        (*sem)->magic = 0;
                    124: 
                    125:        free(*sem);
                    126: 
                    127:        retval = 0;
                    128:   RETURN:
                    129:        return retval;
                    130: }
                    131: 
                    132: xp_sem_t *
                    133: xp_sem_open(const char *name, int oflag, ...)
                    134: {
                    135:        errno = ENOSYS;
                    136:        return XP_SEM_FAILED;
                    137: }
                    138: 
                    139: int
                    140: xp_sem_close(xp_sem_t *sem)
                    141: {
                    142:        errno = ENOSYS;
                    143:        return -1;
                    144: }
                    145: 
                    146: int
                    147: xp_sem_unlink(const char *name)
                    148: {
                    149:        errno = ENOSYS;
                    150:        return -1;
                    151: }
                    152: 
                    153: int
                    154: xp_sem_wait(xp_sem_t *sem)
                    155: {
                    156:        int     retval;
                    157: 
                    158:        _SEM_CHECK_VALIDITY(sem);
                    159: 
                    160:        pthread_mutex_lock(&(*sem)->lock);
                    161: 
                    162:        while ((*sem)->count == 0) {
                    163:                (*sem)->nwaiters++;
                    164:                pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
                    165:                (*sem)->nwaiters--;
                    166:        }
                    167:        (*sem)->count--;
                    168: 
                    169:        pthread_mutex_unlock(&(*sem)->lock);
                    170: 
                    171:        retval = 0;
                    172:   RETURN:
                    173: 
                    174:        return retval;
                    175: }
                    176: 
                    177: int
                    178: xp_sem_trywait(xp_sem_t *sem)
                    179: {
                    180:        int     retval;
                    181: 
                    182:        _SEM_CHECK_VALIDITY(sem);
                    183: 
                    184:        pthread_mutex_lock(&(*sem)->lock);
                    185: 
                    186:        if ((*sem)->count > 0) {
                    187:                (*sem)->count--;
                    188:                retval = 0;
                    189:        } else {
                    190:                errno = EAGAIN;
                    191:                retval = -1;
                    192:        }
                    193:        
                    194:        pthread_mutex_unlock(&(*sem)->lock);
                    195: 
                    196:   RETURN:
                    197:        return retval;
                    198: }
                    199: 
                    200: int
                    201: xp_sem_post(xp_sem_t *sem)
                    202: {
                    203:        int     retval;
                    204: 
                    205:        _SEM_CHECK_VALIDITY(sem);
                    206: 
                    207:        pthread_mutex_lock(&(*sem)->lock);
                    208: 
                    209:        (*sem)->count++;
                    210:        if ((*sem)->nwaiters > 0) {
                    211:                /*
                    212:                 * We must use pthread_cond_broadcast() rather than
                    213:                 * pthread_cond_signal() in order to assure that the highest
                    214:                 * priority thread is run by the scheduler, since
                    215:                 * pthread_cond_signal() signals waiting threads in FIFO order.
                    216:                 */
                    217:                pthread_cond_broadcast(&(*sem)->gtzero);
                    218:        }
                    219: 
                    220:        pthread_mutex_unlock(&(*sem)->lock);
                    221: 
                    222:        retval = 0;
                    223:   RETURN:
                    224:        return retval;
                    225: }
                    226: 
                    227: int
                    228: xp_sem_getvalue(xp_sem_t *sem, int *sval)
                    229: {
                    230:        int     retval;
                    231: 
                    232:        _SEM_CHECK_VALIDITY(sem);
                    233: 
                    234:        pthread_mutex_lock(&(*sem)->lock);
                    235:        *sval = (int)(*sem)->count;
                    236:        pthread_mutex_unlock(&(*sem)->lock);
                    237: 
                    238:        retval = 0;
                    239:   RETURN:
                    240:        return retval;
                    241: }
                    242: 
                    243: int
                    244: xp_sem_setvalue(xp_sem_t *sem, int sval)
                    245: {
                    246:        int     retval;
                    247: 
                    248:        _SEM_CHECK_VALIDITY(sem);
                    249: 
                    250:        pthread_mutex_lock(&(*sem)->lock);
                    251:        (*sem)->count=(u_int32_t)sval;
                    252:        if (((*sem)->nwaiters > 0) && sval) {
                    253:                /*
                    254:                 * We must use pthread_cond_broadcast() rather than
                    255:                 * pthread_cond_signal() in order to assure that the highest
                    256:                 * priority thread is run by the scheduler, since
                    257:                 * pthread_cond_signal() signals waiting threads in FIFO order.
                    258:                 */
                    259:                pthread_cond_broadcast(&(*sem)->gtzero);
                    260:        }
                    261:        pthread_mutex_unlock(&(*sem)->lock);
                    262: 
                    263:        retval = 0;
                    264:   RETURN:
                    265:        return retval;
                    266: }
                    267: 
                    268: int
                    269: xp_sem_timedwait(xp_sem_t *sem, const struct timespec *abs_timeout)
                    270: {
                    271:        int     retval=0;
                    272: 
                    273:        _SEM_CHECK_VALIDITY(sem);
                    274: 
                    275:        pthread_mutex_lock(&(*sem)->lock);
                    276: 
                    277:        while ((*sem)->count == 0) {
                    278:                (*sem)->nwaiters++;
                    279:                retval=pthread_cond_timedwait(&(*sem)->gtzero, &(*sem)->lock, abs_timeout);
                    280:                (*sem)->nwaiters--;
                    281:                if(retval)  {
                    282:                        errno=retval;
                    283:                        retval=-1;
                    284:                        break;
                    285:                }
                    286:        }
                    287:        if(retval==0)
                    288:                (*sem)->count--;
                    289: 
                    290:        pthread_mutex_unlock(&(*sem)->lock);
                    291: 
                    292:   RETURN:
                    293: 
                    294:        return retval;
                    295: }

unix.superglobalmegacorp.com

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