All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core] [RFC][PATCH] shirq locking rework
@ 2007-06-19 18:40 Jan Kiszka
  2007-06-20 21:04 ` Dmitry Adamushko
  0 siblings, 1 reply; 17+ messages in thread
From: Jan Kiszka @ 2007-06-19 18:40 UTC (permalink / raw)
  To: Dmitry Adamushko; +Cc: xenomai-core

[-- Attachment #1: Type: text/plain, Size: 5875 bytes --]

Hi Dmitry,

I had a look at the shared IRQ thing /wrt to my idea of switching
between two list revisions. It turned out to be as nice as I expected
when marvelling at the new xnintr_edge_shirq_handler() -- but it became
horribly complex for setup/cleanup :(. So forget it, also the ring idea
which took quite some part in the complexity increase.

Looking at xnintr_shirq_lock again: We have an atomic op, we have a
memory barrier -- what do we actually gain by not using a usual xnlock
here? I mean one that is per-IRQ, embedded in xnintr_shirq_t?

Well, I hate nested locks when it comes to real-time, but in this case I
really found no simpler approach. There is the risk of deadlocks via

IRQ:		xnintr_shirq::lock -> handler -> nklock vs.
Application:	nklock -> xnintr_attach/detach -> xnintr_shirq::lock,

but we have no such case in-tree, nor should anyone try to do so
elsewhere I assume (restriction is documented now). Note that this code
is only compile-tested, and my brain still suffers from serious knots
due to the first approach, thus no guarantee that I didn't messed
things up.

Comments?

Jan


---
 ksrc/nucleus/intr.c |   70 +++++++++++++++-------------------------------------
 1 file changed, 21 insertions(+), 49 deletions(-)

Index: xenomai/ksrc/nucleus/intr.c
===================================================================
--- xenomai.orig/ksrc/nucleus/intr.c
+++ xenomai/ksrc/nucleus/intr.c
@@ -169,40 +169,12 @@ typedef struct xnintr_shirq {
 
 	xnintr_t *handlers;
 	int unhandled;
-#ifdef CONFIG_SMP
-	atomic_counter_t active;
-#endif
+	DECLARE_XNLOCK(lock);
 
 } xnintr_shirq_t;
 
 static xnintr_shirq_t xnshirqs[RTHAL_NR_IRQS];
 
-static inline void xnintr_shirq_lock(xnintr_shirq_t *shirq)
-{
-#ifdef CONFIG_SMP
-	xnarch_atomic_inc(&shirq->active);
-	xnarch_memory_barrier();
-#endif
-}
-
-static inline void xnintr_shirq_unlock(xnintr_shirq_t *shirq)
-{
-#ifdef CONFIG_SMP
-	xnarch_memory_barrier();
-	xnarch_atomic_dec(&shirq->active);
-#endif
-}
-
-void xnintr_synchronize(xnintr_t *intr)
-{
-#ifdef CONFIG_SMP
-	xnintr_shirq_t *shirq = &xnshirqs[intr->irq];
-
-	while (xnarch_atomic_get(&shirq->active))
-		cpu_relax();
-#endif
-}
-
 #if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL)
 /*
  * Low-level interrupt handler dispatching the user-defined ISRs for
@@ -226,7 +198,7 @@ static void xnintr_shirq_handler(unsigne
 
 	++sched->inesting;
 
-	xnintr_shirq_lock(shirq);
+	xnlock_get(&shirq->lock);
 	intr = shirq->handlers;
 
 	while (intr) {
@@ -247,7 +219,7 @@ static void xnintr_shirq_handler(unsigne
 		intr = intr->next;
 	}
 
-	xnintr_shirq_unlock(shirq);
+	xnlock_put(&shirq->lock);
 
 	if (unlikely(s == XN_ISR_NONE)) {
 		if (++shirq->unhandled == XNINTR_MAX_UNHANDLED) {
@@ -297,7 +269,7 @@ static void xnintr_edge_shirq_handler(un
 
 	++sched->inesting;
 
-	xnintr_shirq_lock(shirq);
+	xnlock_get(&shirq->lock);
 	intr = shirq->handlers;
 
 	while (intr != end) {
@@ -328,7 +300,7 @@ static void xnintr_edge_shirq_handler(un
 			intr = shirq->handlers;
 	}
 
-	xnintr_shirq_unlock(shirq);
+	xnlock_put(&shirq->lock);
 
 	if (counter > MAX_EDGEIRQ_COUNTER)
 		xnlogerr
@@ -411,9 +383,12 @@ static inline int xnintr_irq_attach(xnin
 
 	__setbits(intr->flags, XN_ISR_ATTACHED);
 
-	/* Add a given interrupt object. */
 	intr->next = NULL;
+
+	/* Add a given interrupt object. */
+	xnlock_get(&shirq->lock);
 	*p = intr;
+	xnlock_put(&shirq->lock);
 
 	return 0;
 }
@@ -434,8 +409,10 @@ static inline int xnintr_irq_detach(xnin
 
 	while ((e = *p) != NULL) {
 		if (e == intr) {
-			/* Remove a given interrupt object from the list. */
+			/* Remove the given interrupt object from the list. */
+			xnlock_get(&shirq->lock);
 			*p = e->next;
+			xnlock_put(&shirq->lock);
 
 			/* Release the IRQ line if this was the last user */
 			if (shirq->handlers == NULL)
@@ -454,12 +431,8 @@ static inline int xnintr_irq_detach(xnin
 int xnintr_mount(void)
 {
 	int i;
-	for (i = 0; i < RTHAL_NR_IRQS; ++i) {
-		xnshirqs[i].handlers = NULL;
-#ifdef CONFIG_SMP
-		xnarch_atomic_set(&xnshirqs[i].active, 0);
-#endif
-	}
+	for (i = 0; i < RTHAL_NR_IRQS; ++i)
+		xnlock_init(&xnshirqs[i].lock);
 	return 0;
 }
 
@@ -475,7 +448,6 @@ static inline int xnintr_irq_detach(xnin
 	return xnarch_release_irq(intr->irq);
 }
 
-void xnintr_synchronize(xnintr_t *intr) {}
 int xnintr_mount(void) { return 0; }
 
 #endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
@@ -651,6 +623,9 @@ int xnintr_destroy(xnintr_t *intr)
  * a low-level error occurred while attaching the interrupt. -EBUSY is
  * specifically returned if the interrupt object was already attached.
  *
+ * @note The caller <b>must not</b> hold nklock when invoking this service,
+ * this would cause deadlocks.
+ *
  * Environments:
  *
  * This service can be called from:
@@ -682,7 +657,7 @@ int xnintr_attach(xnintr_t *intr, void *
 
 	if (!err)
 		xnintr_stat_counter_inc();
-	
+
 	xnlock_put_irqrestore(&intrlock, s);
 
 	return err;
@@ -706,6 +681,9 @@ int xnintr_attach(xnintr_t *intr, void *
  * a non-attached interrupt object leads to a null-effect and returns
  * 0.
  *
+ * @note The caller <b>must not</b> hold nklock when invoking this service,
+ * this would cause deadlocks.
+ *
  * Environments:
  *
  * This service can be called from:
@@ -731,12 +709,6 @@ int xnintr_detach(xnintr_t *intr)
 
 	xnlock_put_irqrestore(&intrlock, s);
 
-	/* The idea here is to keep a detached interrupt object valid as long
-	   as the corresponding irq handler is running. This is one of the
-	   requirements to iterate over the xnintr_shirq_t::handlers list in
-	   xnintr_irq_handler() in a lockless way. */
-	xnintr_synchronize(intr);
-
 	return err;
 }
 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread
* Re: [Xenomai-core] [RFC][PATCH] shirq locking rework
@ 2007-06-25 19:11 Dmitry Adamushko
  2007-06-25 20:29 ` Jan Kiszka
  0 siblings, 1 reply; 17+ messages in thread
From: Dmitry Adamushko @ 2007-06-25 19:11 UTC (permalink / raw)
  To: jan.kiszka; +Cc: xenomai-core


Hello Jan,

well, take it with 2 huge grains of salt.. it's even not compile-tested :-)

I don't think I've got it really nicer than your first patch.. the only additional point is that
'prev = xnstat_get_current()' reference is also tracked as reference accounting becomes
a part of the xnstat interface (not sure we do need it though).

Well (#2), I have to say that the whole intr subsystem looks not that nice (maybe partly due
to being overloaded with xnstat details).. so I think, it'd require a closer look.

Anyway, here is what I've got out of your patch so far.. the main issue is whether we go this way
or it just makes things even more uglier.

(a side effect : I transformed xnstat_* macroses into 'static inline' function.. I guess, this way it's a bit nicer)

----------

diff -upr xenomai-orig/include/nucleus/stat.h xenomai-intr/include/nucleus/stat.h
--- xenomai-orig/include/nucleus/stat.h	2007-06-23 14:03:58.000000000 +0200
+++ xenomai-intr/include/nucleus/stat.h	2007-06-24 15:25:37.000000000 +0200
@@ -31,46 +31,72 @@ typedef struct xnstat_runtime {
 
 	xnticks_t total; /* Accumulated execution time */
 
+	atomic_counter_t refs;
+
 } xnstat_runtime_t;
 
 /* Return current date which can be passed to other xnstat services for
    immediate or lazy accounting. */
-#define xnstat_runtime_now() xnarch_get_cpu_tsc()
+static inline xnticks_t xnstat_runtime_now(void)
+{
+	return xnarch_get_cpu_tsc();
+}
 
 /* Accumulate runtime of the current account until the given date. */
-#define xnstat_runtime_update(sched, start) \
-do { \
-	(sched)->current_account->total += \
-		start - (sched)->last_account_switch; \
-	(sched)->last_account_switch = start; \
-} while (0)
+static inline void xnstat_runtime_update(xnsched_t *sched, xnticks_t start)
+{
+	sched->current_account->total += start - sched->last_account_switch;
+	sched->last_account_switch = start;
+}
 
 /* Update the current account reference, returning the previous one. */
-#define xnstat_runtime_set_current(sched, new_account) \
-({ \
-	xnstat_runtime_t *__prev; \
-	__prev = xnarch_atomic_xchg(&(sched)->current_account, (new_account)); \
-	__prev; \
-})
+static inline void xnstat_runtime_set_current(xnsched_t *sched, xnstat_runtime_t *new_account)
+{
+	xnstat_runtime_t *prev;
+
+	if (likely(new_account))
+		xnarch_atomic_inc(&new_account->refs);
+	prev = xnarch_atomic_xchg(&sched->current_account, new_account);
+	if (likely(prev))
+		xnarch_atomic_dec(&prev->refs);
+}
 
 /* Return the currently active accounting entity. */
-#define xnstat_runtime_get_current(sched) ((sched)->current_account)
+static inline xnstat_runtime_t * xnstat_runtime_get_current(xnsched_t *sched)
+{
+	xnstat_runtime_t *curr = sched->current_account;
+
+	if (likely(curr))
+		xnarch_atomic_inc(&curr->refs);
+}
+
+static inline void xnstat_runtime_put(xnstat_runtime_t *stat)
+{
+	if (likely(stat))
+		xnarch_atomic_dec(&stat->refs);
+}
 
 /* Finalize an account (no need to accumulate the runtime, just mark the
    switch date and set the new account). */
-#define xnstat_runtime_finalize(sched, new_account) \
-do { \
-	(sched)->last_account_switch = xnarch_get_cpu_tsc(); \
-	(sched)->current_account = (new_account); \
-} while (0)
+static inline void xnstat_runtime_finalize(xnsched_t *sched, xnstat_runtime_t *new_account)
+{
+	sched->last_account_switch = xnarch_get_cpu_tsc();
+	xnstat_runtime_set_current(sched, new_account);
+}
 
 /* Reset statistics from inside the accounted entity (e.g. after CPU
    migration). */
-#define xnstat_runtime_reset_stats(stat) \
-do { \
-	(stat)->total = 0; \
-	(stat)->start = xnarch_get_cpu_tsc(); \
-} while (0)
+static inline void xnstat_runtime_reset_stats(xnstat_runtime_t *stat)
+{
+	stat->total = 0;
+	stat->start = xnarch_get_cpu_tsc();
+}
+
+static void xnstat_runtime_sync(xnstat_runtime_t *stat)
+{
+	while (xnarch_atomic_get(&stat->refs))
+		cpu_relax();
+}
 
 
 typedef struct xnstat_counter {
@@ -101,10 +127,12 @@ typedef struct xnstat_runtime {
 
 #define xnstat_runtime_now()					({ 0; })
 #define xnstat_runtime_update(sched, start)			do { } while (0)
-#define xnstat_runtime_set_current(sched, new_account)	({ (void)sched; NULL; })
+#define xnstat_runtime_set_current(sched, new_account)		do { } while (0)
 #define xnstat_runtime_get_current(sched)			({ (void)sched; NULL; })
+#define xnstat_runtime_put(stat)				do { } while (0)
 #define xnstat_runtime_finalize(sched, new_account)		do { } while (0)
 #define xnstat_runtime_reset_stats(account)			do { } while (0)
+#define xnstat_runtime_sync(account)				do { } while (0)
 
 typedef struct xnstat_counter {
 #ifdef __XENO_SIM__
@@ -119,18 +147,20 @@ typedef struct xnstat_counter {
 
 /* Account the runtime of the current account until now, switch to
    new_account, and return the previous one. */
-#define xnstat_runtime_switch(sched, new_account) \
-({ \
-	xnstat_runtime_update(sched, xnstat_runtime_now()); \
-	xnstat_runtime_set_current(sched, new_account); \
-})
+static inline void
+xnstat_runtime_switch(xnsched_t *sched, xnstat_runtime_t *new_account)
+{
+	xnstat_runtime_update(sched, xnstat_runtime_now());
+	xnstat_runtime_set_current(sched, new_account);
+}
 
 /* Account the runtime of the current account until given start time, switch
    to new_account, and return the previous one. */
-#define xnstat_runtime_lazy_switch(sched, new_account, start) \
-({ \
-	xnstat_runtime_update(sched, start); \
-	xnstat_runtime_set_current(sched, new_account); \
-})
+static inline void
+xnstat_runtime_lazy_switch(xnsched_t *sched, xnstat_runtime_t *new_account, xnticks_t start)
+{
+	xnstat_runtime_update(sched, start);
+	xnstat_runtime_set_current(sched, new_account);
+}
 
 #endif /* !_XENO_NUCLEUS_STAT_H */
diff -upr xenomai-orig/ksrc/nucleus/intr.c xenomai-intr/ksrc/nucleus/intr.c
--- xenomai-orig/ksrc/nucleus/intr.c	2007-06-23 15:13:43.000000000 +0200
+++ xenomai-intr/ksrc/nucleus/intr.c	2007-06-24 15:47:58.000000000 +0200
@@ -41,6 +41,18 @@
 
 DEFINE_PRIVATE_XNLOCK(intrlock);
 
+typedef struct xnintr_irq {
+
+	DECLARE_XNLOCK(lock);
+
+#if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
+	xnintr_t *handlers;
+	int unhandled;
+#endif
+} ____cacheline_aligned_in_smp xnintr_irq_t;
+
+static xnintr_irq_t xnirqs[RTHAL_NR_IRQS];
+
 #ifdef CONFIG_XENO_OPT_STATS
 xnintr_t nkclock;	/* Only for statistics */
 int xnintr_count = 1;	/* Number of attached xnintr objects + nkclock */
@@ -63,9 +75,18 @@ static inline void xnintr_stat_counter_d
 	xnarch_memory_barrier();
 	xnintr_list_rev++;
 }
+
+static inline void xnintr_sync_stat_refs(xnintr_t *intr)
+{
+	int cpu;
+
+	for_each_online_cpu(cpu)
+		xnstat_runtime_sync(&intr->stat[cpu].account);
+}
 #else
 static inline void xnintr_stat_counter_inc(void) {}
 static inline void xnintr_stat_counter_dec(void) {}
+static inline void xnintr_sync_stat_refs(xnintr_t *intr) {}
 #endif /* CONFIG_XENO_OPT_STATS */
 
 /*
@@ -76,31 +97,44 @@ static inline void xnintr_stat_counter_d
 static void xnintr_irq_handler(unsigned irq, void *cookie)
 {
 	xnsched_t *sched = xnpod_current_sched();
-	xnintr_t *intr = (xnintr_t *)cookie;
+	xnintr_t *intr;
 	xnstat_runtime_t *prev;
 	xnticks_t start;
-	int s;
+	int s = 0;
 
 	prev  = xnstat_runtime_get_current(sched);
 	start = xnstat_runtime_now();
 	xnltt_log_event(xeno_ev_ienter, irq);
 
 	++sched->inesting;
-	s = intr->isr(intr);
 
-	if (unlikely(s == XN_ISR_NONE)) {
-		if (++intr->unhandled == XNINTR_MAX_UNHANDLED) {
-			xnlogerr("%s: IRQ%d not handled. Disabling IRQ "
-				 "line.\n", __FUNCTION__, irq);
-			s |= XN_ISR_NOENABLE;
+	xnlock_get(&xnirqs[irq].lock);
+
+#ifdef CONFIG_SMP
+	/* In SMP case, we have to reload the cookie under the per-IRQ lock
+	   to avoid racing with xnintr_detach. */
+	intr = rthal_irq_cookie(&rthal_domain, irq);
+#else
+	intr = cookie;
+#endif
+	if (likely(intr)) {
+		s = intr->isr(intr);
+
+		if (unlikely(s == XN_ISR_NONE)) {
+			if (++intr->unhandled == XNINTR_MAX_UNHANDLED) {
+				xnlogerr("%s: IRQ%d not handled. Disabling IRQ "
+					 "line.\n", __FUNCTION__, irq);
+				s |= XN_ISR_NOENABLE;
+			}
+		} else {
+			xnstat_counter_inc(&intr->stat[xnsched_cpu(sched)].hits);
+			xnstat_runtime_lazy_switch(sched,
+				&intr->stat[xnsched_cpu(sched)].account,
+				start);
+			intr->unhandled = 0;
 		}
-	} else {
-		xnstat_counter_inc(&intr->stat[xnsched_cpu(sched)].hits);
-		xnstat_runtime_lazy_switch(sched,
-			&intr->stat[xnsched_cpu(sched)].account,
-			start);
-		intr->unhandled = 0;
 	}
+	xnlock_put(&xnirqs[irq].lock);
 
 	if (s & XN_ISR_PROPAGATE)
 		xnarch_chain_irq(irq);
@@ -112,6 +146,7 @@ static void xnintr_irq_handler(unsigned 
 
 	xnltt_log_event(xeno_ev_iexit, irq);
 	xnstat_runtime_switch(sched, prev);
+	xnstat_runtime_put(prev);
 }
 
 /* Low-level clock irq handler. */
@@ -155,24 +190,13 @@ void xnintr_clock_handler(void)
 
 	xnltt_log_event(xeno_ev_iexit, XNARCH_TIMER_IRQ);
 	xnstat_runtime_switch(sched, prev);
+	xnstat_runtime_put(prev);
 }
 
 /* Optional support for shared interrupts. */
 
 #if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
 
-typedef struct xnintr_shirq {
-
-	xnintr_t *handlers;
-	int unhandled;
-#ifdef CONFIG_SMP
-	xnlock_t lock;
-#endif
-
-} xnintr_shirq_t;
-
-static xnintr_shirq_t xnshirqs[RTHAL_NR_IRQS];
-
 #if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL)
 /*
  * Low-level interrupt handler dispatching the user-defined ISRs for
@@ -184,7 +208,7 @@ static void xnintr_shirq_handler(unsigne
 	xnsched_t *sched = xnpod_current_sched();
 	xnstat_runtime_t *prev;
 	xnticks_t start;
-	xnintr_shirq_t *shirq = &xnshirqs[irq];
+	xnintr_irq_t *shirq = &xnirqs[irq];
 	xnintr_t *intr;
 	int s = 0;
 
@@ -236,6 +260,7 @@ static void xnintr_shirq_handler(unsigne
 
 	xnltt_log_event(xeno_ev_iexit, irq);
 	xnstat_runtime_switch(sched, prev);
+	xnstat_runtime_put(prev);
 }
 
 #endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL */
@@ -253,7 +278,7 @@ static void xnintr_edge_shirq_handler(un
 	xnsched_t *sched = xnpod_current_sched();
 	xnstat_runtime_t *prev;
 	xnticks_t start;
-	xnintr_shirq_t *shirq = &xnshirqs[irq];
+	xnintr_irq_t *shirq = &xnirqs[irq];
 	xnintr_t *intr, *end = NULL;
 	int s = 0, counter = 0;
 
@@ -277,15 +302,15 @@ static void xnintr_edge_shirq_handler(un
 		s |= ret;
 
 		if (code == XN_ISR_HANDLED) {
-			end = NULL;
+			if (!(end = (intr->next)))
+				end = shirq->handlers;
 			xnstat_counter_inc(
 				&intr->stat[xnsched_cpu(sched)].hits);
 			xnstat_runtime_lazy_switch(sched,
 				&intr->stat[xnsched_cpu(sched)].account,
 				start);
 			start = xnstat_runtime_now();
-		} else if (code == XN_ISR_NONE && end == NULL)
-			end = intr;
+		}
 
 		if (counter++ > MAX_EDGEIRQ_COUNTER)
 			break;
@@ -320,13 +345,14 @@ static void xnintr_edge_shirq_handler(un
 
 	xnltt_log_event(xeno_ev_iexit, irq);
 	xnstat_runtime_switch(sched, prev);
+	xnstat_runtime_put(prev);
 }
 
 #endif /* CONFIG_XENO_OPT_SHIRQ_EDGE */
 
 static inline int xnintr_irq_attach(xnintr_t *intr)
 {
-	xnintr_shirq_t *shirq = &xnshirqs[intr->irq];
+	xnintr_irq_t *shirq = &xnirqs[intr->irq];
 	xnintr_t *prev, **p = &shirq->handlers;
 	int err;
 
@@ -379,17 +405,16 @@ static inline int xnintr_irq_attach(xnin
 
 	intr->next = NULL;
 
-	/* Add a given interrupt object. */
-	xnlock_get(&shirq->lock);
+	/* Add the given interrupt object. No need to synchronise with the IRQ
+	   handler, we are only extending the chain. */
 	*p = intr;
-	xnlock_put(&shirq->lock);
 
 	return 0;
 }
 
 static inline int xnintr_irq_detach(xnintr_t *intr)
 {
-	xnintr_shirq_t *shirq = &xnshirqs[intr->irq];
+	xnintr_irq_t *shirq = &xnirqs[intr->irq];
 	xnintr_t *e, **p = &shirq->handlers;
 	int err = 0;
 
@@ -408,6 +433,8 @@ static inline int xnintr_irq_detach(xnin
 			*p = e->next;
 			xnlock_put(&shirq->lock);
 
+			xnintr_sync_stat_references(intr);
+
 			/* Release the IRQ line if this was the last user */
 			if (shirq->handlers == NULL)
 				err = xnarch_release_irq(intr->irq);
@@ -422,14 +449,6 @@ static inline int xnintr_irq_detach(xnin
 	return err;
 }
 
-int xnintr_mount(void)
-{
-	int i;
-	for (i = 0; i < RTHAL_NR_IRQS; ++i)
-		xnlock_init(&xnshirqs[i].lock);
-	return 0;
-}
-
 #else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL && !CONFIG_XENO_OPT_SHIRQ_EDGE */
 
 static inline int xnintr_irq_attach(xnintr_t *intr)
@@ -439,13 +458,30 @@ static inline int xnintr_irq_attach(xnin
 
 static inline int xnintr_irq_detach(xnintr_t *intr)
 {
-	return xnarch_release_irq(intr->irq);
-}
+	int irq = intr->irq;
+	int err;
+
+	xnlock_get(&xnirqs[irq].lock);
+
+	err = xnarch_release_irq(intr->irq);
 
-int xnintr_mount(void) { return 0; }
+	xnlock_put(&xnirqs[irq].lock);
+
+	xnintr_sync_stat_references(intr);
+
+	return err;
+}
 
 #endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
 
+int xnintr_mount(void)
+{
+	int i;
+	for (i = 0; i < RTHAL_NR_IRQS; ++i)
+		xnlock_init(&xnirqs[i].lock);
+	return 0;
+}
+
 /*!
  * \fn int xnintr_init (xnintr_t *intr,const char *name,unsigned irq,xnisr_t isr,xniack_t iack,xnflags_t flags)
  * \brief Initialize an interrupt object.
@@ -809,7 +845,7 @@ int xnintr_irq_proc(unsigned int irq, ch
 	xnlock_get_irqsave(&intrlock, s);
 
 #if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL) || defined(CONFIG_XENO_OPT_SHIRQ_EDGE)
-	intr = xnshirqs[irq].handlers;
+	intr = xnirqs[irq].handlers;
 	if (intr) {
 		strcpy(p, "        "); p += 8;
 
@@ -862,7 +898,7 @@ int xnintr_query(int irq, int *cpu, xnin
 	else if (irq == XNARCH_TIMER_IRQ)
 		intr = &nkclock;
 	else
-		intr = xnshirqs[irq].handlers;
+		intr = xnirqs[irq].handlers;
 #else /* !CONFIG_XENO_OPT_SHIRQ_LEVEL && !CONFIG_XENO_OPT_SHIRQ_EDGE */
 	if (*prev)
 		intr = NULL;


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2007-06-30  8:36 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-19 18:40 [Xenomai-core] [RFC][PATCH] shirq locking rework Jan Kiszka
2007-06-20 21:04 ` Dmitry Adamushko
2007-06-20 21:58   ` Jan Kiszka
2007-06-21  8:03     ` Dmitry Adamushko
2007-06-21  9:20       ` Jan Kiszka
2007-06-21  9:52         ` Dmitry Adamushko
2007-06-21 12:56           ` Jan Kiszka
2007-06-21 13:14             ` Dmitry Adamushko
2007-06-21 13:40               ` Jan Kiszka
2007-06-22 11:53                 ` Jan Kiszka
2007-06-22 12:17                   ` Dmitry Adamushko
2007-06-22 12:24                     ` Jan Kiszka
     [not found]         ` <467A5B85.9010103@domain.hid>
2007-06-21 17:24           ` Philippe Gerum
2007-06-21 17:46             ` Jan Kiszka
  -- strict thread matches above, loose matches on Subject: below --
2007-06-25 19:11 Dmitry Adamushko
2007-06-25 20:29 ` Jan Kiszka
2007-06-30  8:36   ` Dmitry Adamushko

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.