> In article <20030518182010$0541@gated-at.bofh.it> you wrote:
> > On Sun, 18 May 2003, Peter T. Breuer wrote:
> >> Here's a before-breakfast implementation of a recursive spinlock. That
>
> > A looong time ago I gave to someone a recursive spinlock implementation
> > that they integrated in the USB code. I don't see it in the latest
> > kernels, so I have to guess that they found a better solution to do their
> > things. I'm biased to say that it must not be necessary to have the thing
> > if you structure your code correctly.
>
> Well, you can get rid of anything that way. The question is if the
> interface is an appropriate one to use or not - i.e. if it makes for
> better code in general, or if it make errors of programming less
> likely.
>
> I would argue that the latter is undoubtedly true - merely that
> userspace flock/fcntl works that way would argue for it, but there
> are a couple of other reasons too.
>
> Going against is the point that it may be slower. Can you dig out your
> implementation and show me it? I wasn't going for assembler in my hasty
> example. I just wanted to establish that it's easy, so that it becomes
> known that its easy, and folks therefore aren't afraid of it. That both
> you and I have had to write it implies that it's not obvious code to
> everyone.
It was something like this. The real code should be in 2.2.x I believe.
The problem at the time was nested ( recursive ) spinlocks.
typedef struct s_nestlock {
spinlock_t lock;
void *uniq;
atomic_t count;
} nestlock_t;
#define nestlock_init(snl) \
do { \
spin_lock_init(&(snl)->lock); \
(snl)->uniq = NULL; \
atomic_set(&(snl)->count, 0); \
} while (0)
#define nestlock_irqlock(snl, flags) \
do { \
if ((snl)->uniq == current) { \
atomic_inc(&(snl)->count); \
flags = 0; /* No warnings */ \
} else { \
spin_lock_irqsave(&(snl)->lock, flags); \
atomic_inc(&(snl)->count); \
(snl)->uniq = current; \
} \
} while (0)
#define nestlock_irqunlock(snl, flags) \
do { \
if (atomic_dec_and_test(&(snl)->count)) { \
(snl)->uniq = NULL; \
spin_unlock_irqrestore(&(snl)->lock, flags); \
} \
} while (0)
#define nestlock_lock(snl) \
do { \
if ((snl)->uniq == current) { \
atomic_inc(&(snl)->count); \
} else { \
spin_lock(&(snl)->lock); \
atomic_inc(&(snl)->count); \
(snl)->uniq = current; \
} \
} while (0)
#define nestlock_unlock(snl) \
do { \
if (atomic_dec_and_test(&(snl)->count)) { \
(snl)->uniq = NULL; \
spin_unlock(&(snl)->lock); \
} \
} while (0)
- Davide
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/