Module: xenomai-3
Branch: master
Commit: 77a0e7eb6cb7573bd5baf253429346595a797b86
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=77a0e7eb6cb7573bd5baf253429346595a797b86

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Tue Mar 24 20:40:13 2015 +0100

cobalt/mutex,cond: allow static initializer

By initializing the mutex or condvar on first access

---

 lib/cobalt/cond.c  |   58 +++++++++++++++++++++++++++++++++++++++++++-----
 lib/cobalt/mutex.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 109 insertions(+), 11 deletions(-)

diff --git a/lib/cobalt/cond.c b/lib/cobalt/cond.c
index 70a97fd..ba1fada 100644
--- a/lib/cobalt/cond.c
+++ b/lib/cobalt/cond.c
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include <errno.h>
+#include <string.h>
 #include <pthread.h>
 #include <asm/xenomai/syscall.h>
 #include "current.h"
@@ -189,6 +190,17 @@ static void __pthread_cond_cleanup(void *data)
        c->mutex->lockcnt = c->count;
 }
 
+static int __attribute__((cold)) cobalt_cond_autoinit(pthread_cond_t *cond)
+{
+       static pthread_cond_t uninit_cond = PTHREAD_COND_INITIALIZER;
+
+       if (memcmp(cond, &uninit_cond, sizeof(*cond)))
+               return EINVAL;
+
+       return __COBALT(pthread_cond_init(cond, NULL));
+}
+
+
 /**
  * Wait on a condition variable.
  *
@@ -248,10 +260,13 @@ COBALT_IMPL(int, pthread_cond_wait, (pthread_cond_t 
*cond, pthread_mutex_t *mute
        int err, oldtype;
        unsigned count;
 
-       if (_mx->magic != COBALT_MUTEX_MAGIC
-           || _cnd->magic != COBALT_COND_MAGIC)
+       if (_mx->magic != COBALT_MUTEX_MAGIC)
                return EINVAL;
 
+       if (_cnd->magic != COBALT_COND_MAGIC)
+               goto autoinit;
+
+  cont:
        if (_mx->attr.type == PTHREAD_MUTEX_ERRORCHECK) {
                xnhandle_t cur = cobalt_get_current();
 
@@ -283,6 +298,12 @@ COBALT_IMPL(int, pthread_cond_wait, (pthread_cond_t *cond, 
pthread_mutex_t *mute
        pthread_testcancel();
 
        return -err ?: -c.err;
+
+  autoinit:
+       err = cobalt_cond_autoinit(cond);
+       if (err)
+               return err;
+       goto cont;
 }
 
 /**
@@ -333,10 +354,13 @@ COBALT_IMPL(int, pthread_cond_timedwait, (pthread_cond_t 
*cond,
        int err, oldtype;
        unsigned count;
 
-       if (_mx->magic != COBALT_MUTEX_MAGIC
-           || _cnd->magic != COBALT_COND_MAGIC)
+       if (_mx->magic != COBALT_MUTEX_MAGIC)
                return EINVAL;
 
+       if (_cnd->magic != COBALT_COND_MAGIC)
+               goto autoinit;
+
+  cont:
        if (_mx->attr.type == PTHREAD_MUTEX_ERRORCHECK) {
                xnhandle_t cur = cobalt_get_current();
 
@@ -367,6 +391,12 @@ COBALT_IMPL(int, pthread_cond_timedwait, (pthread_cond_t 
*cond,
        pthread_testcancel();
 
        return -err ?: -c.err;
+
+  autoinit:
+       err = cobalt_cond_autoinit(cond);
+       if (err)
+               return err;
+       goto cont;
 }
 
 /**
@@ -398,10 +428,12 @@ COBALT_IMPL(int, pthread_cond_signal, (pthread_cond_t 
*cond))
        __u32 pending_signals;
        xnhandle_t cur;
        __u32 flags;
+       int err;
 
        if (_cnd->magic != COBALT_COND_MAGIC)
-               return EINVAL;
+               goto autoinit;
 
+  cont:
        mutex_state = get_mutex_state(_cnd);
        if (mutex_state == NULL)
                return 0;       /* Fast path, no waiter. */
@@ -422,6 +454,12 @@ COBALT_IMPL(int, pthread_cond_signal, (pthread_cond_t 
*cond))
                cond_state->pending_signals = pending_signals + 1;
 
        return 0;
+
+  autoinit:
+       err = cobalt_cond_autoinit(cond);
+       if (err)
+               return err;
+       goto cont;
 }
 
 /**
@@ -449,10 +487,12 @@ COBALT_IMPL(int, pthread_cond_broadcast, (pthread_cond_t 
*cond))
        struct cobalt_cond_state *cond_state;
        xnhandle_t cur;
        __u32 flags;
+       int err;
 
        if (_cnd->magic != COBALT_COND_MAGIC)
-               return EINVAL;
+               goto autoinit;
 
+  cont:
        mutex_state = get_mutex_state(_cnd);
        if (mutex_state == NULL)
                return 0;
@@ -471,6 +511,12 @@ COBALT_IMPL(int, pthread_cond_broadcast, (pthread_cond_t 
*cond))
        cond_state->pending_signals = ~0U;
 
        return 0;
+
+  autoinit:
+       err = cobalt_cond_autoinit(cond);
+       if (err)
+               return err;
+       goto cont;
 }
 
 /**
diff --git a/lib/cobalt/mutex.c b/lib/cobalt/mutex.c
index 93a9bbc..b84a582 100644
--- a/lib/cobalt/mutex.c
+++ b/lib/cobalt/mutex.c
@@ -16,8 +16,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include <errno.h>
-#include <pthread.h>
+#include <string.h>
 #include <limits.h>
+#include <pthread.h>
 #include <asm/xenomai/syscall.h>
 #include "current.h"
 #include "internal.h"
@@ -170,6 +171,29 @@ COBALT_IMPL(int, pthread_mutex_destroy, (pthread_mutex_t 
*mutex))
        return -err;
 }
 
+static int __attribute__((cold)) cobalt_mutex_autoinit(pthread_mutex_t *mutex)
+{
+       static pthread_mutex_t uninit_normal_mutex = PTHREAD_MUTEX_INITIALIZER;
+       static pthread_mutex_t uninit_recursive_mutex =
+               PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+       static pthread_mutex_t uninit_errorcheck_mutex =
+               PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+       pthread_mutexattr_t mattr;
+       int err;
+
+       if (memcmp(mutex, &uninit_normal_mutex, sizeof(*mutex))
+               && memcmp(mutex, &uninit_recursive_mutex, sizeof(*mutex))
+               && memcmp(mutex, &uninit_errorcheck_mutex, sizeof(*mutex)))
+               return EINVAL;
+
+       pthread_mutexattr_init(&mattr);
+       pthread_mutexattr_settype(&mattr, mutex->__data.__kind);
+       err = __COBALT(pthread_mutex_init(mutex, &mattr));
+       pthread_mutexattr_destroy(&mattr);
+
+       return err;
+}
+
 /**
  * Lock a mutex.
  *
@@ -214,13 +238,14 @@ COBALT_IMPL(int, pthread_mutex_lock, (pthread_mutex_t 
*mutex))
                return EPERM;
 
        if (_mutex->magic != COBALT_MUTEX_MAGIC)
-               return EINVAL;
+               goto autoinit;
 
        /*
         * We track resource ownership for non real-time shadows in
         * order to handle the auto-relax feature, so we must always
         * obtain them via a syscall.
         */
+  cont:
        status = cobalt_get_current_mode();
        if ((status & (XNRELAX|XNWEAK)) == 0) {
                ret = xnsynch_fast_acquire(mutex_get_ownerp(_mutex), cur);
@@ -257,6 +282,12 @@ COBALT_IMPL(int, pthread_mutex_lock, (pthread_mutex_t 
*mutex))
                _mutex->lockcnt = 1;
 
        return -ret;
+
+  autoinit:
+       ret = cobalt_mutex_autoinit(mutex);
+       if (ret)
+               return ret;
+       goto cont;
 }
 
 /**
@@ -302,9 +333,10 @@ COBALT_IMPL(int, pthread_mutex_timedlock, (pthread_mutex_t 
*mutex,
                return EPERM;
 
        if (_mutex->magic != COBALT_MUTEX_MAGIC)
-               return EINVAL;
+               goto autoinit;
 
        /* See __cobalt_pthread_mutex_lock() */
+  cont:
        status = cobalt_get_current_mode();
        if ((status & (XNRELAX|XNWEAK)) == 0) {
                ret = xnsynch_fast_acquire(mutex_get_ownerp(_mutex), cur);
@@ -341,6 +373,12 @@ COBALT_IMPL(int, pthread_mutex_timedlock, (pthread_mutex_t 
*mutex,
        if (ret == 0)
                _mutex->lockcnt = 1;
        return -ret;
+
+  autoinit:
+       ret = cobalt_mutex_autoinit(mutex);
+       if (ret)
+               return ret;
+       goto cont;
 }
 
 /**
@@ -379,8 +417,9 @@ COBALT_IMPL(int, pthread_mutex_trylock, (pthread_mutex_t 
*mutex))
                return EPERM;
 
        if (_mutex->magic != COBALT_MUTEX_MAGIC)
-               return EINVAL;
+               goto autoinit;
 
+  cont:
        status = cobalt_get_current_mode();
        if ((status & (XNRELAX|XNWEAK)) == 0) {
                err = xnsynch_fast_acquire(mutex_get_ownerp(_mutex), cur);
@@ -416,6 +455,12 @@ do_syscall:
                _mutex->lockcnt = 1;
 
        return -err;
+
+  autoinit:
+       err = cobalt_mutex_autoinit(mutex);
+       if (err)
+               return err;
+       goto cont;
 }
 
 /**
@@ -452,8 +497,9 @@ COBALT_IMPL(int, pthread_mutex_unlock, (pthread_mutex_t 
*mutex))
        int err;
 
        if (_mutex->magic != COBALT_MUTEX_MAGIC)
-               return EINVAL;
+               goto autoinit;
 
+  cont:
        cur = cobalt_get_current();
        if (cur == XN_NO_HANDLE)
                return EPERM;
@@ -482,6 +528,12 @@ do_syscall:
        } while (err == -EINTR);
 
        return -err;
+
+  autoinit:
+       err = cobalt_mutex_autoinit(mutex);
+       if (err)
+               return err;
+       goto cont;
 }
 
 /**


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to