All of lore.kernel.org
 help / color / mirror / Atom feed
From: Norbert Lange <nolange79@gmail.com>
To: xenomai@xenomai.org
Subject: [PATCH 3/5] libcobalt: improve condvar autoinit support
Date: Thu,  7 Mar 2019 14:21:57 +0100	[thread overview]
Message-ID: <20190307132159.31206-3-norbert.lange@andritz.com> (raw)
In-Reply-To: <20190307132159.31206-1-norbert.lange@andritz.com>

contrary to some comments, condvars are automatically
initialised on signal/wait.
Correct the destroy method to not report an
error on such condvars.

Check whether the condition variable has the
static initializer is now more strict.

Signed-off-by: Norbert Lange <norbert.lange@andritz.com>
---
 lib/cobalt/cond.c | 93 ++++++++++++++++++++++++++---------------------
 1 file changed, 51 insertions(+), 42 deletions(-)

diff --git a/lib/cobalt/cond.c b/lib/cobalt/cond.c
index 00a201855..92eb230ff 100644
--- a/lib/cobalt/cond.c
+++ b/lib/cobalt/cond.c
@@ -142,6 +142,42 @@ COBALT_IMPL(int, pthread_cond_init, (pthread_cond_t *cond,
 	return 0;
 }
 
+static int __attribute__((cold)) _cobalt_cond_autoinit_type(const pthread_cond_t *cond)
+{
+	static const pthread_cond_t cond_initializers[] = {
+		PTHREAD_COND_INITIALIZER
+	};
+	static const int cond_types[] =
+	{
+		0
+	};
+
+	unsigned i = sizeof(cond_types) / sizeof(cond_types[0]);
+	while (i-- > 0)
+	{
+		if (memcmp(cond, &cond_initializers[i], sizeof(cond_initializers[0])) == 0)
+			return cond_types[i];
+	}
+	return -1;
+}
+
+static int __attribute__((cold)) _cobalt_cond_doautoinit(union cobalt_cond_union *ucond)
+{
+	int type;
+	type = _cobalt_cond_autoinit_type(&ucond->native_cond);
+	if (type < 0)
+		return EINVAL;
+
+	return __COBALT(pthread_cond_init(&ucond->native_cond, NULL));
+}
+
+static inline int _cobalt_cond_autoinit(union cobalt_cond_union *ucond)
+{
+	if (unlikely(ucond->shadow_cond.magic != COBALT_COND_MAGIC))
+		return _cobalt_cond_doautoinit(ucond);
+	return 0;
+}
+
 /**
  * @fn int pthread_cond_destroy(pthread_cond_t *cond)
  * @brief Destroy a condition variable
@@ -170,6 +206,9 @@ COBALT_IMPL(int, pthread_cond_destroy, (pthread_cond_t *cond))
 {
 	struct cobalt_cond_shadow *_cond = &((union cobalt_cond_union *)cond)->shadow_cond;
 
+	if (unlikely(_cond->magic != COBALT_COND_MAGIC))
+		return (_cobalt_cond_autoinit_type(cond) < 0) ? EINVAL : 0;
+
 	return -XENOMAI_SYSCALL1( sc_cobalt_cond_destroy, _cond);
 }
 
@@ -193,12 +232,6 @@ static void __pthread_cond_cleanup(void *data)
 	c->mutex->lockcnt = c->count;
 }
 
-static int __attribute__((cold)) cobalt_cond_autoinit(pthread_cond_t *cond)
-{
-	return __COBALT(pthread_cond_init(cond, NULL));
-}
-
-
 /**
  * Wait on a condition variable.
  *
@@ -262,10 +295,10 @@ COBALT_IMPL(int, pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mute
 	if (_mx->magic != COBALT_MUTEX_MAGIC)
 		return EINVAL;
 
-	if (_cnd->magic != COBALT_COND_MAGIC)
-		goto autoinit;
+	err = _cobalt_cond_autoinit((union cobalt_cond_union *)cond);
+	if (err)
+		return err;
 
-  cont:
 	if (_mx->attr.type == PTHREAD_MUTEX_ERRORCHECK) {
 		xnhandle_t cur = cobalt_get_current();
 
@@ -297,12 +330,6 @@ 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;
 }
 
 /**
@@ -357,10 +384,10 @@ COBALT_IMPL(int, pthread_cond_timedwait, (pthread_cond_t *cond,
 	if (_mx->magic != COBALT_MUTEX_MAGIC)
 		return EINVAL;
 
-	if (_cnd->magic != COBALT_COND_MAGIC)
-		goto autoinit;
+	err = _cobalt_cond_autoinit((union cobalt_cond_union *)cond);
+	if (err)
+		return err;
 
-  cont:
 	if (_mx->attr.type == PTHREAD_MUTEX_ERRORCHECK) {
 		xnhandle_t cur = cobalt_get_current();
 
@@ -391,12 +418,6 @@ 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;
 }
 
 /**
@@ -431,10 +452,10 @@ COBALT_IMPL(int, pthread_cond_signal, (pthread_cond_t *cond))
 	__u32 flags;
 	int err;
 
-	if (_cnd->magic != COBALT_COND_MAGIC)
-		goto autoinit;
+	err = _cobalt_cond_autoinit((union cobalt_cond_union *)cond);
+	if (err)
+		return err;
 
-  cont:
 	mutex_state = get_mutex_state(_cnd);
 	if (mutex_state == NULL)
 		return 0;	/* Fast path, no waiter. */
@@ -455,12 +476,6 @@ 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;
 }
 
 /**
@@ -491,10 +506,10 @@ COBALT_IMPL(int, pthread_cond_broadcast, (pthread_cond_t *cond))
 	__u32 flags;
 	int err;
 
-	if (_cnd->magic != COBALT_COND_MAGIC)
-		goto autoinit;
+	err = _cobalt_cond_autoinit((union cobalt_cond_union *)cond);
+	if (err)
+		return err;
 
-  cont:
 	mutex_state = get_mutex_state(_cnd);
 	if (mutex_state == NULL)
 		return 0;
@@ -513,12 +528,6 @@ 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;
 }
 
 /**
-- 
2.20.1



  parent reply	other threads:[~2019-03-07 13:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-07 13:21 [PATCH 1/5] libcobalt: improve mutex autoinit support Norbert Lange
2019-03-07 13:21 ` [PATCH 2/5] libcobalt: improve documentation regarding mutex initializers Norbert Lange
2019-04-01 17:20   ` Jan Kiszka
2019-03-07 13:21 ` Norbert Lange [this message]
2019-04-01 17:27   ` [PATCH 3/5] libcobalt: improve condvar autoinit support Jan Kiszka
2019-03-07 13:21 ` [PATCH 4/5] libcobalt: improve documentation regarding condvar initializers Norbert Lange
2019-04-01 17:27   ` Jan Kiszka
2019-03-07 13:21 ` [PATCH 5/5] smokey: add tests for mutex/condvar autoinit Norbert Lange
2019-04-01 17:32   ` Jan Kiszka
2019-04-01 17:19 ` [PATCH 1/5] libcobalt: improve mutex autoinit support Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190307132159.31206-3-norbert.lange@andritz.com \
    --to=nolange79@gmail.com \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.