commit-hurd
[Top][All Lists]
Advanced

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

[hurd] 01/04: Replace internal semaphore implementation with posix semap


From: Samuel Thibault
Subject: [hurd] 01/04: Replace internal semaphore implementation with posix semaphores
Date: Mon, 24 Oct 2016 00:16:41 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch dde
in repository hurd.

commit 7cdbac372625953228a363bd8a4a015c2b516a5b
Author: Samuel Thibault <address@hidden>
Date:   Wed Oct 12 02:53:49 2016 +0200

    Replace internal semaphore implementation with posix semaphores
    
    * libddekit/thread.c: Include <semaphore.h>, do not include "list.h"
    (struct _ddekit_private_data): Remove list and wakeupmsg fields.
    (struct ddekit_sem): Replace content with just one sem_t.
    (_thread_cleanup): Do not destroy wakeupmsg.msgh_remote_port.
    (_create_wakeupmsg): Remove function.
    (setup_thread): Do not initialize private_data->list, do not call
    _create_wakeupmsg.
    (_timedblock, _block, _thread_wakeup): Remove functions.
    (_sem_timedwait_internal): Reimplement function using sem_timedwait and
    sem_wait.
    (ddekit_sem_init): Reimplement function using sem_init.
    (ddekit_sem_deinit): Reimplement function using sem_destroy.
    (ddekit_sem_down_try): Reimplement function using sem_trywait.
    (ddekit_sem_up): Reimplement function using sem_post.
---
 libddekit/thread.c | 208 ++++++++---------------------------------------------
 1 file changed, 29 insertions(+), 179 deletions(-)

diff --git a/libddekit/thread.c b/libddekit/thread.c
index 8f7b3ed..17d553b 100644
--- a/libddekit/thread.c
+++ b/libddekit/thread.c
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <pthread.h>
+#include <semaphore.h>
 #include <time.h>
 #include <error.h>
 #include <mach.h>
@@ -11,7 +12,6 @@
 #include "ddekit/memory.h"
 #include "ddekit/semaphore.h"
 #include "ddekit/condvar.h"
-#include "list.h"
 #include "ddekit/thread.h"
 
 #define DDEKIT_THREAD_STACK_SIZE 0x2000 /* 8 KB */
@@ -19,11 +19,9 @@
 //static struct ddekit_slab *ddekit_stack_slab = NULL;
 
 struct _ddekit_private_data {
-       struct list list;
        ddekit_condvar_t *sleep_cond;
        /* point to the thread who has the private data. */
        struct ddekit_thread *thread;
-       mach_msg_header_t wakeupmsg;
 };
 
 struct ddekit_thread {
@@ -35,57 +33,20 @@ struct ddekit_thread {
 
 struct ddekit_sem
 {
-       pthread_spinlock_t lock;
-       /* A list of thread waiting for the semaphore. */
-       struct list head;
-       int value;
+       sem_t sem;
 };
 
 static __thread struct ddekit_thread *thread_self;
 
 static void _thread_cleanup ()
 {
-       mach_port_destroy (mach_task_self (),
-                          thread_self->private->wakeupmsg.msgh_remote_port);
        ddekit_condvar_deinit (thread_self->private->sleep_cond);
        ddekit_simple_free (thread_self->private);
        ddekit_simple_free (thread_self->name);
        ddekit_simple_free (thread_self);
 }
 
-/* Prepare a wakeup message.  */
-static error_t _create_wakeupmsg (struct _ddekit_private_data *data)
-{
-       kern_return_t err;
-
-       /* Build wakeup message.  */
-       data->wakeupmsg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
-       data->wakeupmsg.msgh_size = 0;
-
-       err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE,
-                                 &data->wakeupmsg.msgh_remote_port);
-       if (err)
-         return EAGAIN;
-
-       data->wakeupmsg.msgh_local_port = MACH_PORT_NULL;
-       data->wakeupmsg.msgh_seqno = 0;
-       data->wakeupmsg.msgh_id = 0;
-
-       err = mach_port_insert_right (mach_task_self (),
-                                     data->wakeupmsg.msgh_remote_port,
-                                     data->wakeupmsg.msgh_remote_port,
-                                     MACH_MSG_TYPE_MAKE_SEND);
-       if (err) {
-               mach_port_destroy (mach_task_self (),
-                                  data->wakeupmsg.msgh_remote_port);
-               return EAGAIN;
-       }
-
-       return 0;
-}
-
 static void setup_thread (struct ddekit_thread *t, const char *name) {
-       error_t err;
        struct _ddekit_private_data *private_data;
 
        if (name) {
@@ -104,14 +65,8 @@ static void setup_thread (struct ddekit_thread *t, const 
char *name) {
          ddekit_simple_malloc (sizeof (*private_data));
 
        private_data->sleep_cond = ddekit_condvar_init ();
-       private_data->list.prev = &private_data->list;
-       private_data->list.next = &private_data->list;
        private_data->thread = t;
 
-       err = _create_wakeupmsg (private_data);
-       if (err)
-         error (1, err, "_create_wakeupmsg");
-
        t->private = private_data;
 }
 
@@ -267,114 +222,45 @@ void ddekit_init_threads() {
  *                         semaphore
  **********************************************************************/
 
-/* Block THREAD.  */
-static error_t _timedblock (struct _ddekit_private_data *data,
-                           const int timeout)
-{
-       error_t err;
-       mach_msg_header_t msg;
-
-       assert (timeout > 0);
-
-       err = mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
-                       sizeof msg, data->wakeupmsg.msgh_remote_port,
-                       timeout, MACH_PORT_NULL);
-       if (err == EMACH_RCV_TIMED_OUT)
-               return ETIMEDOUT;
-
-       assert_perror (err);
-       return 0;
-}
-
-/* Block THREAD.  */
-static void _block (struct _ddekit_private_data *data)
+static int _sem_timedwait_internal (ddekit_sem_t *restrict sem, int timeout)
 {
-       mach_msg_header_t msg;
-       error_t err;
-
-       err = mach_msg (&msg, MACH_RCV_MSG, 0, sizeof msg,
-                       data->wakeupmsg.msgh_remote_port,
-                       MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-       assert_perror (err);
-}
-
-static int _sem_timedwait_internal (ddekit_sem_t *restrict sem,
-                                   const int timeout)
-{
-       pthread_spin_lock (&sem->lock);
-       if (sem->value > 0) {
-               /* Successful down.  */
-               sem->value --;
-               pthread_spin_unlock (&sem->lock);
-               return 0;
-       }
-
-       if (timeout < 0) {
-               pthread_spin_unlock (&sem->lock);
-               errno = EINVAL;
-               return -1;
-       }
-
-       /* Add ourselves to the queue.  */
-       add_entry_head (&sem->head, &thread_self->private->list);
-       pthread_spin_unlock (&sem->lock);
-
-       /* Block the thread.  */
-       if (timeout) {
-               error_t err;
-
-               err = _timedblock (thread_self->private, timeout);
-               if (err) {
-                 /* We timed out.  We may need to disconnect ourself from the
-                    waiter queue.
-
-                    FIXME: What do we do if we get a wakeup message before we
-                    disconnect ourself?  It may remain until the next time we
-                    block.  */
-                       assert (err == ETIMEDOUT);
-
-                       pthread_spin_lock (&sem->lock);
-                       remove_entry (&thread_self->private->list);
-                       pthread_spin_unlock (&sem->lock);
-
-                       errno = err;
-                       return -1;
+       int ret;
+       if (timeout)
+       {
+               struct timespec ts;
+               clock_gettime(CLOCK_REALTIME, &ts);
+
+               ts.tv_nsec += (timeout%1000) * 1000000;
+               if (ts.tv_nsec >= 1000000000) {
+                       ts.tv_nsec -= 1000000000;
+                       ts.tv_sec += 1;
                }
+               ts.tv_sec += timeout/1000;
+               do
+                       ret = sem_timedwait(&sem->sem, &ts);
+               while (ret == -1 && errno == EINTR);
+               return ret;
        }
        else
-               _block (thread_self->private);
-
-       return 0;
-}
-
-/* Wakeup THREAD.  */
-static void _thread_wakeup (struct _ddekit_private_data *data)
-{
-       error_t err;
-
-       err = mach_msg (&data->wakeupmsg, MACH_SEND_MSG,
-                       sizeof (data->wakeupmsg), 0, MACH_PORT_NULL,
-                       MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-       assert_perror (err);
+       {
+               do
+                       ret = sem_wait(&sem->sem);
+               while (ret == -1 && errno == EINTR);
+               return 0;
+       }
 }
 
 ddekit_sem_t *ddekit_sem_init(int value) {
        ddekit_sem_t *sem =
          (ddekit_sem_t *) ddekit_simple_malloc (sizeof (*sem));
 
-       sem->lock = PTHREAD_SPINLOCK_INITIALIZER;
-       sem->head.prev = &sem->head;
-       sem->head.next = &sem->head;
-       sem->value = value;
+       sem_init(&sem->sem, 0, value);
        return sem;
 }
 
 void ddekit_sem_deinit(ddekit_sem_t *sem) {
-       if (!EMPTY_LIST (&sem->head)) {
-               error (0, EBUSY, "ddekit_sem_deinit");
-       }
-       else
-               ddekit_simple_free(sem);
+       sem_destroy(&sem->sem);
+       ddekit_simple_free(sem);
 }
 
 void ddekit_sem_down(ddekit_sem_t *sem) {
@@ -383,16 +269,7 @@ void ddekit_sem_down(ddekit_sem_t *sem) {
 
 /* returns 0 on success, != 0 when it would block */
 int  ddekit_sem_down_try(ddekit_sem_t *sem) {
-       pthread_spin_lock (&sem->lock);
-       if (sem->value > 0) {
-               /* Successful down.  */
-               sem->value --;
-               pthread_spin_unlock (&sem->lock);
-               return 0;
-       }
-       pthread_spin_unlock (&sem->lock);
-
-       return -1;
+       return sem_trywait(&sem->sem);
 }
 
 /* returns 0 on success, != 0 on timeout */
@@ -402,33 +279,6 @@ int  ddekit_sem_down_timed(ddekit_sem_t *sem, int timo) {
 }
 
 void ddekit_sem_up(ddekit_sem_t *sem) {
-       struct _ddekit_private_data *wakeup;
-
-       pthread_spin_lock (&sem->lock);
-       if (sem->value > 0) {
-               /* Do a quick up.  */
-               assert (EMPTY_LIST (&sem->head));
-               sem->value ++;
-               pthread_spin_unlock (&sem->lock);
-               return;
-       }
-
-       if (EMPTY_LIST (&sem->head)) {
-               /* No one waiting.  */
-               sem->value = 1;
-               pthread_spin_unlock (&sem->lock);
-               return;
-       }
-
-       /* Wake someone up.  */
-
-       /* First dequeue someone.  */
-       wakeup = LIST_ENTRY (remove_entry_end (&sem->head),
-                            struct _ddekit_private_data, list);
-
-       /* Then drop the lock and transfer control.  */
-       pthread_spin_unlock (&sem->lock);
-       if (wakeup) 
-               _thread_wakeup (wakeup);
+       sem_post(&sem->sem);
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]