All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core] [RESEND][PATCH] Refactor xnintr query
@ 2008-08-26 20:50 Jan Kiszka
  2008-08-27  9:34 ` Philippe Gerum
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Kiszka @ 2008-08-26 20:50 UTC (permalink / raw)
  To: xenomai-core

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

[ Trying the keep my queue short... ]

This version, posted earlier already, should address all remarks brought
up. OK to commit?

---
 include/nucleus/intr.h |   25 +++++++++++-----
 ksrc/nucleus/intr.c    |   76 +++++++++++++++++++++++++++++++------------------
 ksrc/nucleus/module.c  |   47 ++++++++++--------------------
 3 files changed, 84 insertions(+), 64 deletions(-)

Index: b/include/nucleus/intr.h
===================================================================
--- a/include/nucleus/intr.h
+++ b/include/nucleus/intr.h
@@ -69,11 +69,23 @@ typedef struct xnintr {
 
 } xnintr_t;
 
+typedef struct xnintr_iterator {
+
+    int cpu;		/* !< Current CPU in iteration. */
+
+    unsigned long hits;	/* !< Current hit counter. */
+
+    xnticks_t exectime;	/* !< Used CPU time in current accounting period. */
+
+    xnticks_t account_period; /* !< Length of accounting period. */
+
+    int list_rev;	/* !< System-wide xnintr list revision (internal use). */
+
+    xnintr_t *prev;	/* !< Previously visited xnintr object (internal use). */
+
+} xnintr_iterator_t;
+
 extern xnintr_t nkclock;
-#ifdef CONFIG_XENO_OPT_STATS
-extern int xnintr_count;
-extern int xnintr_list_rev;
-#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -108,9 +120,8 @@ int xnintr_disable(xnintr_t *intr);
 xnarch_cpumask_t xnintr_affinity(xnintr_t *intr,
                                  xnarch_cpumask_t cpumask);
 
-int xnintr_query(int irq, int *cpu, xnintr_t **prev, int revision, char *name,
-		 unsigned long *hits, xnticks_t *exectime,
-		 xnticks_t *account_period);
+int xnintr_query_init(xnintr_iterator_t *iterator);
+int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf);
 
 #ifdef __cplusplus
 }
Index: b/ksrc/nucleus/intr.c
===================================================================
--- a/ksrc/nucleus/intr.c
+++ b/ksrc/nucleus/intr.c
@@ -42,9 +42,9 @@
 DEFINE_PRIVATE_XNLOCK(intrlock);
 
 #ifdef CONFIG_XENO_OPT_STATS
-xnintr_t nkclock;	/* Only for statistics */
-int xnintr_count = 1;	/* Number of attached xnintr objects + nkclock */
-int xnintr_list_rev;	/* Modification counter of xnintr list */
+xnintr_t nkclock;	     /* Only for statistics */
+static int xnintr_count = 1; /* Number of attached xnintr objects + nkclock */
+static int xnintr_list_rev;  /* Modification counter of xnintr list */
 
 /* Both functions update xnintr_list_rev at the very end.
  * This guarantees that module.c::stat_seq_open() won't get
@@ -899,55 +899,77 @@ int xnintr_irq_proc(unsigned int irq, ch
 #endif /* CONFIG_PROC_FS */
 
 #ifdef CONFIG_XENO_OPT_STATS
-int xnintr_query(int irq, int *cpu, xnintr_t **prev, int revision, char *name,
-		 unsigned long *hits, xnticks_t *exectime,
-		 xnticks_t *account_period)
+int xnintr_query_init(xnintr_iterator_t *iterator)
+{
+	iterator->cpu = -1;
+	iterator->prev = NULL;
+
+	/* The order is important here: first xnintr_list_rev then
+	 * xnintr_count.  On the other hand, xnintr_attach/detach()
+	 * update xnintr_count first and then xnintr_list_rev.  This
+	 * should guarantee that we can't get an up-to-date
+	 * xnintr_list_rev and old xnintr_count here. The other way
+	 * around is not a problem as xnintr_query() will notice this
+	 * fact later.  Should xnintr_list_rev change later,
+	 * xnintr_query() will trigger an appropriate error below. */
+
+	iterator->list_rev = xnintr_list_rev;
+	xnarch_memory_barrier();
+
+	return xnintr_count;
+}
+
+int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf)
 {
 	xnintr_t *intr;
 	xnticks_t last_switch;
-	int head;
-	int cpu_no = *cpu;
+	int cpu_no = iterator->cpu + 1;
 	int err = 0;
 	spl_t s;
 
+	if (cpu_no == xnarch_num_online_cpus())
+		cpu_no = 0;
+	iterator->cpu = cpu_no;
+
 	xnlock_get_irqsave(&intrlock, s);
 
-	if (revision != xnintr_list_rev) {
+	if (iterator->list_rev != xnintr_list_rev) {
 		err = -EAGAIN;
 		goto unlock_and_exit;
 	}
 
-	if (*prev)
-		intr = xnintr_shirq_next(*prev);
-	else if (irq == XNARCH_TIMER_IRQ)
-		intr = &nkclock;
-	else
-		intr = xnintr_shirq_first(irq);
+	if (!iterator->prev) {
+		if (irq == XNARCH_TIMER_IRQ)
+			intr = &nkclock;
+		else
+			intr = xnintr_shirq_first(irq);
+	} else
+		intr = xnintr_shirq_next(iterator->prev);
 
 	if (!intr) {
+		cpu_no = -1;
+		iterator->prev = NULL;
 		err = -ENODEV;
 		goto unlock_and_exit;
 	}
 
-	head = snprintf(name, XNOBJECT_NAME_LEN, "IRQ%d: ", irq);
-	name += head;
-	strncpy(name, intr->name, XNOBJECT_NAME_LEN-head);
+	snprintf(name_buf, XNOBJECT_NAME_LEN, "IRQ%d: %s", irq, intr->name);
 
-	*hits = xnstat_counter_get(&intr->stat[cpu_no].hits);
+	iterator->hits = xnstat_counter_get(&intr->stat[cpu_no].hits);
 
 	last_switch = xnpod_sched_slot(cpu_no)->last_account_switch;
 
-	*exectime       = intr->stat[cpu_no].account.total;
-	*account_period = last_switch - intr->stat[cpu_no].account.start;
+	iterator->exectime = intr->stat[cpu_no].account.total;
+	iterator->account_period =
+		last_switch - intr->stat[cpu_no].account.start;
 
-	intr->stat[cpu_no].account.total  = 0;
+	intr->stat[cpu_no].account.total = 0;
 	intr->stat[cpu_no].account.start = last_switch;
 
-	if (++cpu_no == xnarch_num_online_cpus()) {
-		cpu_no = 0;
-		*prev  = intr;
-	}
-	*cpu = cpu_no;
+	/* Proceed to next entry in shared IRQ chain when all CPUs
+	 * have been visited for this one. */
+	if (cpu_no + 1 == xnarch_num_online_cpus())
+		iterator->prev = intr;
 
      unlock_and_exit:
 	xnlock_put_irqrestore(&intrlock, s);
Index: b/ksrc/nucleus/module.c
===================================================================
--- a/ksrc/nucleus/module.c
+++ b/ksrc/nucleus/module.c
@@ -352,7 +352,9 @@ static int stat_seq_open(struct inode *i
 	struct seq_file *seq;
 	xnholder_t *holder;
 	struct stat_seq_info *stat_info;
-	int err, count, thrq_rev, intr_rev, irq;
+	xnintr_iterator_t intr_iter;
+	int err, count, thrq_rev, irq;
+	int intr_count;
 	spl_t s;
 
 	if (!xnpod_active_p())
@@ -368,18 +370,8 @@ static int stat_seq_open(struct inode *i
 
 	xnlock_put_irqrestore(&nklock, s);
 
-	/* The order is important here: first xnintr_list_rev then
-	 * xnintr_count.  On the other hand, xnintr_attach/detach()
-	 * update xnintr_count first and then xnintr_list_rev.  This
-	 * should guarantee that we can't get an up-to-date
-	 * xnintr_list_rev and old xnintr_count here. The other way
-	 * around is not a problem as xnintr_query() will notice this
-	 * fact later.  Should xnintr_list_rev change later,
-	 * xnintr_query() will trigger an appropriate error below. */
-
-	intr_rev = xnintr_list_rev;
-	xnarch_memory_barrier();
-	count += xnintr_count * RTHAL_NR_CPUS;
+	intr_count = xnintr_query_init(&intr_iter);
+	count += intr_count * RTHAL_NR_CPUS;
 
 	if (iter)
 		kfree(iter);
@@ -442,35 +434,30 @@ static int stat_seq_open(struct inode *i
 	}
 
 	/* Iterate over all IRQ numbers, ... */
-	for (irq = 0; irq < XNARCH_NR_IRQS; irq++) {
-		xnintr_t *prev = NULL;
-		int cpu = 0, _cpu;
-		int err;
-
+	for (irq = 0; irq < XNARCH_NR_IRQS; irq++)
 		/* ...over all shared IRQs on all CPUs */
 		while (1) {
 			stat_info = &iter->stat_info[iter->nentries];
-			_cpu = cpu;
 
-			err = xnintr_query(irq, &cpu, &prev, intr_rev,
-					   stat_info->name,
-					   &stat_info->csw,
-					   &stat_info->exectime,
-					   &stat_info->account_period);
-			if (err == -EAGAIN)
-				goto restart_unlocked;
-			if (err)
+			err = xnintr_query_next(irq, &intr_iter,
+						stat_info->name);
+			if (err) {
+				if (err == -EAGAIN)
+					goto restart_unlocked;
 				break; /* line unused or end of chain */
+			}
 
-			stat_info->cpu = _cpu;
+			stat_info->cpu = intr_iter.cpu;
+			stat_info->csw = intr_iter.hits;
+			stat_info->exectime = intr_iter.exectime;
+			stat_info->account_period = intr_iter.account_period;
 			stat_info->pid = 0;
 			stat_info->state =  0;
 			stat_info->ssw = 0;
 			stat_info->pf = 0;
 
 			iter->nentries++;
-		};
-	}
+		}
 
 	seq = file->private_data;
 	seq->private = iter;


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

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

* Re: [Xenomai-core] [RESEND][PATCH] Refactor xnintr query
  2008-08-26 20:50 [Xenomai-core] [RESEND][PATCH] Refactor xnintr query Jan Kiszka
@ 2008-08-27  9:34 ` Philippe Gerum
  0 siblings, 0 replies; 2+ messages in thread
From: Philippe Gerum @ 2008-08-27  9:34 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: xenomai-core

Jan Kiszka wrote:
> [ Trying the keep my queue short... ]
> 
> This version, posted earlier already, should address all remarks brought
> up. OK to commit?
>

Fine with me.

> ---
>  include/nucleus/intr.h |   25 +++++++++++-----
>  ksrc/nucleus/intr.c    |   76 +++++++++++++++++++++++++++++++------------------
>  ksrc/nucleus/module.c  |   47 ++++++++++--------------------
>  3 files changed, 84 insertions(+), 64 deletions(-)
> 
> Index: b/include/nucleus/intr.h
> ===================================================================
> --- a/include/nucleus/intr.h
> +++ b/include/nucleus/intr.h
> @@ -69,11 +69,23 @@ typedef struct xnintr {
>  
>  } xnintr_t;
>  
> +typedef struct xnintr_iterator {
> +
> +    int cpu;		/* !< Current CPU in iteration. */
> +
> +    unsigned long hits;	/* !< Current hit counter. */
> +
> +    xnticks_t exectime;	/* !< Used CPU time in current accounting period. */
> +
> +    xnticks_t account_period; /* !< Length of accounting period. */
> +
> +    int list_rev;	/* !< System-wide xnintr list revision (internal use). */
> +
> +    xnintr_t *prev;	/* !< Previously visited xnintr object (internal use). */
> +
> +} xnintr_iterator_t;
> +
>  extern xnintr_t nkclock;
> -#ifdef CONFIG_XENO_OPT_STATS
> -extern int xnintr_count;
> -extern int xnintr_list_rev;
> -#endif
>  
>  #ifdef __cplusplus
>  extern "C" {
> @@ -108,9 +120,8 @@ int xnintr_disable(xnintr_t *intr);
>  xnarch_cpumask_t xnintr_affinity(xnintr_t *intr,
>                                   xnarch_cpumask_t cpumask);
>  
> -int xnintr_query(int irq, int *cpu, xnintr_t **prev, int revision, char *name,
> -		 unsigned long *hits, xnticks_t *exectime,
> -		 xnticks_t *account_period);
> +int xnintr_query_init(xnintr_iterator_t *iterator);
> +int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf);
>  
>  #ifdef __cplusplus
>  }
> Index: b/ksrc/nucleus/intr.c
> ===================================================================
> --- a/ksrc/nucleus/intr.c
> +++ b/ksrc/nucleus/intr.c
> @@ -42,9 +42,9 @@
>  DEFINE_PRIVATE_XNLOCK(intrlock);
>  
>  #ifdef CONFIG_XENO_OPT_STATS
> -xnintr_t nkclock;	/* Only for statistics */
> -int xnintr_count = 1;	/* Number of attached xnintr objects + nkclock */
> -int xnintr_list_rev;	/* Modification counter of xnintr list */
> +xnintr_t nkclock;	     /* Only for statistics */
> +static int xnintr_count = 1; /* Number of attached xnintr objects + nkclock */
> +static int xnintr_list_rev;  /* Modification counter of xnintr list */
>  
>  /* Both functions update xnintr_list_rev at the very end.
>   * This guarantees that module.c::stat_seq_open() won't get
> @@ -899,55 +899,77 @@ int xnintr_irq_proc(unsigned int irq, ch
>  #endif /* CONFIG_PROC_FS */
>  
>  #ifdef CONFIG_XENO_OPT_STATS
> -int xnintr_query(int irq, int *cpu, xnintr_t **prev, int revision, char *name,
> -		 unsigned long *hits, xnticks_t *exectime,
> -		 xnticks_t *account_period)
> +int xnintr_query_init(xnintr_iterator_t *iterator)
> +{
> +	iterator->cpu = -1;
> +	iterator->prev = NULL;
> +
> +	/* The order is important here: first xnintr_list_rev then
> +	 * xnintr_count.  On the other hand, xnintr_attach/detach()
> +	 * update xnintr_count first and then xnintr_list_rev.  This
> +	 * should guarantee that we can't get an up-to-date
> +	 * xnintr_list_rev and old xnintr_count here. The other way
> +	 * around is not a problem as xnintr_query() will notice this
> +	 * fact later.  Should xnintr_list_rev change later,
> +	 * xnintr_query() will trigger an appropriate error below. */
> +
> +	iterator->list_rev = xnintr_list_rev;
> +	xnarch_memory_barrier();
> +
> +	return xnintr_count;
> +}
> +
> +int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf)
>  {
>  	xnintr_t *intr;
>  	xnticks_t last_switch;
> -	int head;
> -	int cpu_no = *cpu;
> +	int cpu_no = iterator->cpu + 1;
>  	int err = 0;
>  	spl_t s;
>  
> +	if (cpu_no == xnarch_num_online_cpus())
> +		cpu_no = 0;
> +	iterator->cpu = cpu_no;
> +
>  	xnlock_get_irqsave(&intrlock, s);
>  
> -	if (revision != xnintr_list_rev) {
> +	if (iterator->list_rev != xnintr_list_rev) {
>  		err = -EAGAIN;
>  		goto unlock_and_exit;
>  	}
>  
> -	if (*prev)
> -		intr = xnintr_shirq_next(*prev);
> -	else if (irq == XNARCH_TIMER_IRQ)
> -		intr = &nkclock;
> -	else
> -		intr = xnintr_shirq_first(irq);
> +	if (!iterator->prev) {
> +		if (irq == XNARCH_TIMER_IRQ)
> +			intr = &nkclock;
> +		else
> +			intr = xnintr_shirq_first(irq);
> +	} else
> +		intr = xnintr_shirq_next(iterator->prev);
>  
>  	if (!intr) {
> +		cpu_no = -1;
> +		iterator->prev = NULL;
>  		err = -ENODEV;
>  		goto unlock_and_exit;
>  	}
>  
> -	head = snprintf(name, XNOBJECT_NAME_LEN, "IRQ%d: ", irq);
> -	name += head;
> -	strncpy(name, intr->name, XNOBJECT_NAME_LEN-head);
> +	snprintf(name_buf, XNOBJECT_NAME_LEN, "IRQ%d: %s", irq, intr->name);
>  
> -	*hits = xnstat_counter_get(&intr->stat[cpu_no].hits);
> +	iterator->hits = xnstat_counter_get(&intr->stat[cpu_no].hits);
>  
>  	last_switch = xnpod_sched_slot(cpu_no)->last_account_switch;
>  
> -	*exectime       = intr->stat[cpu_no].account.total;
> -	*account_period = last_switch - intr->stat[cpu_no].account.start;
> +	iterator->exectime = intr->stat[cpu_no].account.total;
> +	iterator->account_period =
> +		last_switch - intr->stat[cpu_no].account.start;
>  
> -	intr->stat[cpu_no].account.total  = 0;
> +	intr->stat[cpu_no].account.total = 0;
>  	intr->stat[cpu_no].account.start = last_switch;
>  
> -	if (++cpu_no == xnarch_num_online_cpus()) {
> -		cpu_no = 0;
> -		*prev  = intr;
> -	}
> -	*cpu = cpu_no;
> +	/* Proceed to next entry in shared IRQ chain when all CPUs
> +	 * have been visited for this one. */
> +	if (cpu_no + 1 == xnarch_num_online_cpus())
> +		iterator->prev = intr;
>  
>       unlock_and_exit:
>  	xnlock_put_irqrestore(&intrlock, s);
> Index: b/ksrc/nucleus/module.c
> ===================================================================
> --- a/ksrc/nucleus/module.c
> +++ b/ksrc/nucleus/module.c
> @@ -352,7 +352,9 @@ static int stat_seq_open(struct inode *i
>  	struct seq_file *seq;
>  	xnholder_t *holder;
>  	struct stat_seq_info *stat_info;
> -	int err, count, thrq_rev, intr_rev, irq;
> +	xnintr_iterator_t intr_iter;
> +	int err, count, thrq_rev, irq;
> +	int intr_count;
>  	spl_t s;
>  
>  	if (!xnpod_active_p())
> @@ -368,18 +370,8 @@ static int stat_seq_open(struct inode *i
>  
>  	xnlock_put_irqrestore(&nklock, s);
>  
> -	/* The order is important here: first xnintr_list_rev then
> -	 * xnintr_count.  On the other hand, xnintr_attach/detach()
> -	 * update xnintr_count first and then xnintr_list_rev.  This
> -	 * should guarantee that we can't get an up-to-date
> -	 * xnintr_list_rev and old xnintr_count here. The other way
> -	 * around is not a problem as xnintr_query() will notice this
> -	 * fact later.  Should xnintr_list_rev change later,
> -	 * xnintr_query() will trigger an appropriate error below. */
> -
> -	intr_rev = xnintr_list_rev;
> -	xnarch_memory_barrier();
> -	count += xnintr_count * RTHAL_NR_CPUS;
> +	intr_count = xnintr_query_init(&intr_iter);
> +	count += intr_count * RTHAL_NR_CPUS;
>  
>  	if (iter)
>  		kfree(iter);
> @@ -442,35 +434,30 @@ static int stat_seq_open(struct inode *i
>  	}
>  
>  	/* Iterate over all IRQ numbers, ... */
> -	for (irq = 0; irq < XNARCH_NR_IRQS; irq++) {
> -		xnintr_t *prev = NULL;
> -		int cpu = 0, _cpu;
> -		int err;
> -
> +	for (irq = 0; irq < XNARCH_NR_IRQS; irq++)
>  		/* ...over all shared IRQs on all CPUs */
>  		while (1) {
>  			stat_info = &iter->stat_info[iter->nentries];
> -			_cpu = cpu;
>  
> -			err = xnintr_query(irq, &cpu, &prev, intr_rev,
> -					   stat_info->name,
> -					   &stat_info->csw,
> -					   &stat_info->exectime,
> -					   &stat_info->account_period);
> -			if (err == -EAGAIN)
> -				goto restart_unlocked;
> -			if (err)
> +			err = xnintr_query_next(irq, &intr_iter,
> +						stat_info->name);
> +			if (err) {
> +				if (err == -EAGAIN)
> +					goto restart_unlocked;
>  				break; /* line unused or end of chain */
> +			}
>  
> -			stat_info->cpu = _cpu;
> +			stat_info->cpu = intr_iter.cpu;
> +			stat_info->csw = intr_iter.hits;
> +			stat_info->exectime = intr_iter.exectime;
> +			stat_info->account_period = intr_iter.account_period;
>  			stat_info->pid = 0;
>  			stat_info->state =  0;
>  			stat_info->ssw = 0;
>  			stat_info->pf = 0;
>  
>  			iter->nentries++;
> -		};
> -	}
> +		}
>  
>  	seq = file->private_data;
>  	seq->private = iter;
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Xenomai-core mailing list
> Xenomai-core@domain.hid
> https://mail.gna.org/listinfo/xenomai-core


-- 
Philippe.


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

end of thread, other threads:[~2008-08-27  9:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-26 20:50 [Xenomai-core] [RESEND][PATCH] Refactor xnintr query Jan Kiszka
2008-08-27  9:34 ` Philippe Gerum

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.