From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
To: xenomai@xenomai.org
Subject: [Xenomai-core] [7/9] Poor man's object control block read-write lock
Date: Thu, 24 Apr 2008 08:30:22 +0200 [thread overview]
Message-ID: <18448.10494.796374.943152@domain.hid> (raw)
In-Reply-To: <18448.10337.610639.200224@domain.hid>
This patch adds the file ksrc/skins/posix/cb_lock.h, a header used in kernel and
user-space to protect access to mutex control blocks. It implements a kind of
read-write lock without rescheduling, a failure meaning a programming error.
pthread_mutex_lock and pthread_mutex_unlock are considered readers, several of
them are allowed to enter the lock section, they will be serialized by cmpxchg
in user-space or the nklock in the syscalls anyway, pthread_mutex_init and
pthread_mutex_destroy, however, are considered writers, only one of them may
enter the lock section, and trying to call them at the same time as a call to
pthread_mutex_lock or pthread_mutex_unlock is a programming error which is
detected and reported.
These locks boil down to locking the nklock in kernel-space when atomic_cmpxchg
is not available in user-space. But this will be removed when all architectures
define XNARCH_HAVE_US_ATOMIC_CMPXCHG.
I intend to generalize the use of this mechanism to all posix skin objects,
because they allow shorter nklock sections in kernel space: access to the object
members are protected by this read-write lock mechanism, and no longer by the
nklock with interrupts off. It also solves an issue that was opened when getting
the posix skin copy_from/to_user calls out of nklock sections.
---
cb_lock.h | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
Index: ksrc/skins/posix/cb_lock.h
===================================================================
--- ksrc/skins/posix/cb_lock.h (revision 0)
+++ ksrc/skins/posix/cb_lock.h (revision 0)
@@ -0,0 +1,84 @@
+#ifndef CB_LOCK_H
+#define CB_LOCK_H
+
+#include <asm/xenomai/atomic.h>
+
+#ifndef __KERNEL__
+typedef void xnthread_t;
+#endif /* __KERNEL__ */
+
+#ifdef XNARCH_HAVE_US_ATOMIC_CMPXCHG
+
+#define test_claimed(owner) ((long) (owner) & 1)
+#define clear_claimed(owner) ((xnthread_t *) ((long) (owner) & ~1))
+#define set_claimed(owner, bit) \
+ ((xnthread_t *) ((long) clear_claimed(owner) | !!(bit)))
+
+static __inline__ int __cb_try_read_lock(atomic_t *lock)
+{
+ unsigned val = atomic_read(lock);
+ while (likely(val != -1)) {
+ unsigned old = atomic_cmpxchg(lock, val, val + 1);
+ if (likely(old == val))
+ return 0;
+ val = old;
+ }
+ return -EBUSY;
+}
+
+static __inline__ void __cb_read_unlock(atomic_t *lock)
+{
+ unsigned old, val = atomic_read(lock);
+ while (likely(val != -1)) {
+ old = atomic_cmpxchg(lock, val, val - 1);
+ if (likely(old == val))
+ return;
+ val = old;
+ }
+}
+
+static __inline__ int __cb_try_write_lock(atomic_t *lock)
+{
+ unsigned old = atomic_cmpxchg(lock, 0, -1);
+ if (unlikely(old))
+ return -EBUSY;
+ return 0;
+}
+
+static __inline__ void __cb_force_write_lock(atomic_t *lock)
+{
+ atomic_set(lock, -1);
+}
+
+static __inline__ void __cb_write_unlock(atomic_t *lock)
+{
+ atomic_set(lock, 0);
+}
+#define DECLARE_CB_LOCK_FLAGS(name) struct { } name __attribute__((unused))
+#define cb_try_read_lock(lock, flags) __cb_try_read_lock(lock)
+#define cb_read_unlock(lock, flags) __cb_read_unlock(lock)
+#define cb_try_write_lock(lock, flags) __cb_try_write_lock(lock)
+#define cb_force_write_lock(lock, flags) __cb_force_write_lock(lock)
+#define cb_write_unlock(lock, flags) __cb_write_unlock(lock)
+#else /* !XNARCH_HAVE_US_ATOMIC_CMPXCHG */
+#ifdef __KERNEL__
+#define DECLARE_CB_LOCK_FLAGS(name) spl_t name
+#define cb_try_read_lock(lock, flags) \
+ ({ xnlock_get_irqsave(&nklock, flags); 0 })
+#define cb_read_unlock(lock, flags) xnlock_put_irqrestore(&nklock, flags)
+#define cb_try_write_lock(lock, flags) \
+ ({ xnlock_get_irqsave(&nklock, flags); 0 })
+#define cb_force_write_lock(lock, flags) \
+ ({ xnlock_get_irqsave(&nklock, flags); 0 })
+#define cb_write_unlock(lock, flags) xnlock_put_irqrestore(&nklock, flags)
+#else /* !__KERNEL__ */
+#define DECLARE_CB_LOCK_FLAGS(name)
+#define cb_try_read_lock(lock, flags) (0)
+#define cb_read_unlock(lock, flags) do { } while (0)
+#define cb_try_write_lock(lock, flags) (0)
+#define cb_force_write_lock(lock, flags) do { } while (0)
+#define cb_write_unlock(lock, flags) do { } while (0)
+#endif /* !__KERNEL__ */
+#endif /* !XNARCH_HAVE_US_ATOMIC_CMPXCHG */
+
+#endif /* CB_LOCK_H */
--
Gilles.
next prev parent reply other threads:[~2008-04-24 6:30 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-24 6:16 [Xenomai-core] [0/9] Posix skin user-space mutexes Gilles Chanteperdrix
2008-04-24 6:20 ` [Xenomai-core] [1/9] Support for non cached memory mappings Gilles Chanteperdrix
2008-04-24 6:21 ` [Xenomai-core] [2/9] Define XNARCH_SHARED_HEAP_FLAGS Gilles Chanteperdrix
2008-04-24 6:22 ` [Xenomai-core] [3/9] Define more atomic operations in user-space Gilles Chanteperdrix
2008-04-24 6:24 ` [Xenomai-core] [4/9] Define ARM " Gilles Chanteperdrix
2008-04-24 6:25 ` [Xenomai-core] [5/9] Define new syscalls for the posix skin Gilles Chanteperdrix
2008-04-24 6:27 ` [Xenomai-core] [6/9] Rework posix skin shared heaps support, add per-process shared heap Gilles Chanteperdrix
2008-04-24 6:30 ` Gilles Chanteperdrix [this message]
2008-04-24 6:32 ` [Xenomai-core] [8/9] Re-implementation of mutexes, kernel-space support Gilles Chanteperdrix
2008-04-24 6:33 ` [Xenomai-core] [9/9] Re-implementation of mutex, user-space support Gilles Chanteperdrix
2008-04-25 8:03 ` [Xenomai-core] [6/9] Rework posix skin shared heaps support, add per-process shared heap Philippe Gerum
2008-04-25 7:59 ` [Xenomai-core] [5/9] Define new syscalls for the posix skin Philippe Gerum
2008-04-25 7:51 ` [Xenomai-core] [4/9] Define ARM atomic operations in user-space Philippe Gerum
2008-04-25 7:48 ` [Xenomai-core] [3/9] Define more " Philippe Gerum
2008-04-25 13:26 ` Gilles Chanteperdrix
2008-04-25 13:42 ` Philippe Gerum
2008-04-25 13:50 ` Gilles Chanteperdrix
2008-04-25 14:01 ` Philippe Gerum
2008-04-25 14:13 ` Gilles Chanteperdrix
2008-04-25 14:20 ` Philippe Gerum
2008-04-25 22:09 ` Gilles Chanteperdrix
2008-04-26 7:02 ` Philippe Gerum
2008-04-24 7:09 ` [Xenomai-core] [0/9] Posix skin user-space mutexes Jan Kiszka
2008-04-24 7:37 ` Gilles Chanteperdrix
2008-04-24 8:23 ` Gilles Chanteperdrix
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=18448.10494.796374.943152@domain.hid \
--to=gilles.chanteperdrix@xenomai.org \
--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.