Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libpthread Rewrite to use our internal scheduling primit...



details:   https://anonhg.NetBSD.org/src/rev/6a376c5657a6
branches:  trunk
changeset: 542165:6a376c5657a6
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Jan 22 22:51:42 2003 +0000

description:
Rewrite to use our internal scheduling primitives.

diffstat:

 lib/libpthread/sem.c |  439 +++++++++++++++++++++++++++-----------------------
 1 files changed, 240 insertions(+), 199 deletions(-)

diffs (truncated from 589 to 300 lines):

diff -r 1fb2d2628977 -r 6a376c5657a6 lib/libpthread/sem.c
--- a/lib/libpthread/sem.c      Wed Jan 22 22:20:23 2003 +0000
+++ b/lib/libpthread/sem.c      Wed Jan 22 22:51:42 2003 +0000
@@ -1,4 +1,40 @@
-/* $NetBSD: sem.c,v 1.2 2003/01/20 20:52:24 christos Exp $ */
+/*     $NetBSD: sem.c,v 1.3 2003/01/22 22:51:42 thorpej Exp $  */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
 
 /*
  * Copyright (C) 2000 Jason Evans <jasone%freebsd.org@localhost>.
@@ -27,47 +63,37 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc/sys/sem.c,v 1.3 2003/01/14 03:36:45 tjr Exp $
  */
 
+#include <sys/types.h>
+#include <sys/ksem.h>
+#include <sys/queue.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <semaphore.h>
 #include <stdarg.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <sys/queue.h>
-#include <sys/ksem.h>
 
+#include "pthread.h"
+#include "pthread_int.h"
 
-/*
- * Semaphore definitions.
- */
 struct _sem_st {
-#define SEM_MAGIC       ((u_int32_t) 0x09fa4012)
-        u_int32_t       magic;
-        pthread_mutex_t lock;
-        pthread_cond_t  gtzero;
-        u_int32_t       count;
-        u_int32_t       nwaiters;
-#define SEM_USER        (NULL)
-        semid_t         semid;  /* semaphore id if kernel (shared) semaphore */
-        int             syssem; /* 1 if kernel (shared) semaphore */
-        LIST_ENTRY(_sem_st) entry;
-        struct _sem_st  **backpointer;
+       unsigned int    usem_magic;
+#define        USEM_MAGIC      0x09fa4012
+
+       LIST_ENTRY(_sem_st) usem_list;
+       semid_t         usem_semid;     /* 0 -> user (non-shared) */
+#define        USEM_USER       0               /* assumes kernel does not use NULL */
+       sem_t           *usem_identity;
+
+       /* Protects data below. */
+       pthread_spin_t  usem_interlock;
+
+       struct pthread_queue_t usem_waiters;
+       unsigned int    usem_count;
 };
 
-
-#define _SEM_CHECK_VALIDITY(sem)               \
-       if ((*(sem))->magic != SEM_MAGIC) {     \
-               errno = EINVAL;                 \
-               retval = -1;                    \
-               goto RETURN;                    \
-       }
-
-static sem_t sem_alloc(unsigned int value, semid_t semid, int system_sem);
+static int sem_alloc(unsigned int value, semid_t semid, sem_t *semp);
 static void sem_free(sem_t sem);
 
 static LIST_HEAD(, _sem_st) named_sems = LIST_HEAD_INITIALIZER(&named_sems);
@@ -77,173 +103,143 @@
 sem_free(sem_t sem)
 {
 
-       pthread_mutex_destroy(&sem->lock);
-       pthread_cond_destroy(&sem->gtzero);
-       sem->magic = 0;
+       sem->usem_magic = 0;
        free(sem);
 }
 
-static sem_t
-sem_alloc(unsigned int value, semid_t semid, int system_sem)
+static int
+sem_alloc(unsigned int value, semid_t semid, sem_t *semp)
 {
        sem_t sem;
 
-       if (value > SEM_VALUE_MAX) {
-               errno = EINVAL;
-               return (NULL);
-       }
+       if (value > SEM_VALUE_MAX)
+               return (EINVAL);
 
-       sem = (sem_t)malloc(sizeof(struct _sem_st));
-       if (sem == NULL) {
-               errno = ENOSPC;
-               return (NULL);
-       }
+       if ((sem = malloc(sizeof(struct _sem_st))) == NULL)
+               return (ENOSPC);
 
-       /*
-        * Initialize the semaphore.
-        */
-       if (pthread_mutex_init(&sem->lock, NULL) != 0) {
-               free(sem);
-               errno = ENOSPC;
-               return (NULL);
-       }
+       sem->usem_magic = USEM_MAGIC;
+       pthread_lockinit(&sem->usem_interlock);
+       PTQ_INIT(&sem->usem_waiters);
+       sem->usem_count = value;
+       sem->usem_semid = semid;
 
-       if (pthread_cond_init(&sem->gtzero, NULL) != 0) {
-               pthread_mutex_destroy(&sem->lock);
-               free(sem);
-               errno = ENOSPC;
-               return (NULL);
-       }
-       
-       sem->count = (u_int32_t)value;
-       sem->nwaiters = 0;
-       sem->magic = SEM_MAGIC;
-       sem->semid = semid;
-       sem->syssem = system_sem;
-       return (sem);
+       *semp = sem;
+       return (0);
 }
 
 int
 sem_init(sem_t *sem, int pshared, unsigned int value)
 {
-       int     retval, got_system_sem;
        semid_t semid;
+       int error;
+
+       semid = USEM_USER;
 
-       got_system_sem = 0;
-       semid = SEM_USER;
-       /*
-        * Range check the arguments.
-        */
-       if (pshared != 0) {
-               retval = _ksem_init(value, &semid);
-               if (retval == -1)
-                       goto RETURN;
-               got_system_sem = 1;
+       if (pshared && _ksem_init(value, &semid) == -1)
+               return (-1);
+
+       if ((error = sem_alloc(value, semid, sem)) != 0) {
+               _ksem_destroy(semid);
+               errno = error;
+               return (-1);
        }
 
-       (*sem) = sem_alloc(value, semid, got_system_sem);
-       if ((*sem) == NULL)
-               retval = -1;
-       else
-               retval = 0;
-  RETURN:
-       if (retval != 0 && got_system_sem)
-               _ksem_destroy(semid);
-       return retval;
+       return (0);
 }
 
 int
 sem_destroy(sem_t *sem)
 {
-       int     retval;
-       
-       _SEM_CHECK_VALIDITY(sem);
+       pthread_t self;
+
+#ifdef ERRORCHECK
+       if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) {
+               errno = EINVAL;
+               return (-1);
+       }
+#endif
 
-       pthread_mutex_lock(&(*sem)->lock);
-       /*
-        * If this is a system semaphore let the kernel track it otherwise
-        * make sure there are no waiters.
-        */
-       if ((*sem)->syssem != 0) {
-               retval = _ksem_destroy((*sem)->semid);
-               if (retval == -1) {
-                       pthread_mutex_unlock(&(*sem)->lock);
-                       goto RETURN;
+       if ((*sem)->usem_semid != USEM_USER) {
+               if (_ksem_destroy((*sem)->usem_semid))
+                       return (-1);
+       } else {
+               self = pthread__self();
+               pthread_spinlock(self, &(*sem)->usem_interlock);
+               if (!PTQ_EMPTY(&(*sem)->usem_waiters)) {
+                       pthread_spinunlock(self, &(*sem)->usem_interlock);
+                       errno = EBUSY;
+                       return (-1);
                }
-       } else if ((*sem)->nwaiters > 0) {
-               pthread_mutex_unlock(&(*sem)->lock);
-               errno = EBUSY;
-               retval = -1;
-               goto RETURN;
+               pthread_spinunlock(self, &(*sem)->usem_interlock);
        }
-       pthread_mutex_unlock(&(*sem)->lock);
-
-       sem_free(*sem); 
 
-       retval = 0;
-  RETURN:
-       return retval;
+       sem_free(*sem);
+
+       return (0);
 }
 
 sem_t *
 sem_open(const char *name, int oflag, ...)
 {
-       sem_t *sem;
-       sem_t s;
+       sem_t *sem, s;
        semid_t semid;
        mode_t mode;
        unsigned int value;
+       int error;
+       va_list ap;
 
        mode = 0;
        value = 0;
 
-       if ((oflag & O_CREAT) != 0) {
-               va_list ap;
-
+       if (oflag & O_CREAT) {
                va_start(ap, oflag);
                mode = va_arg(ap, int);
                value = va_arg(ap, unsigned int);
                va_end(ap);
        }
+
        /*
-        * we can be lazy and let the kernel handle the "oflag",
+        * We can be lazy and let the kernel handle the oflag,
         * we'll just merge duplicate IDs into our list.



Home | Main Index | Thread Index | Old Index