public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH][RFC] kernel.h: provide array iterator
@ 2018-03-15 10:00 Kieran Bingham
  2018-03-16  4:21 ` Kees Cook
  2018-03-16 15:27 ` Rasmus Villemoes
  0 siblings, 2 replies; 9+ messages in thread
From: Kieran Bingham @ 2018-03-15 10:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: Laurent Pinchart, linux-media, Kieran Bingham, Andrew Morton,
	Ingo Molnar, Thomas Gleixner, Kees Cook, Herbert Xu,
	Masahiro Yamada, Greg Kroah-Hartman, Krzysztof Kozlowski,
	Randy Dunlap, Ian Abbott

Simplify array iteration with a helper to iterate each entry in an array.
Utilise the existing ARRAY_SIZE macro to identify the length of the array
and pointer arithmetic to process each item as a for loop.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 include/linux/kernel.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

The use of static arrays to store data is a common use case throughout the
kernel. Along with that is the obvious need to iterate that data.

In fact there are just shy of 5000 instances of iterating a static array:
	git grep "for .*ARRAY_SIZE" | wc -l
	4943

When working on the UVC driver - I found that I needed to split one such
iteration into two parts, and at the same time felt that this could be
refactored to be cleaner / easier to read. 

I do however worry that this simple short patch might not be desired or could
also be heavily bikeshedded due to it's potential wide spread use (though
perhaps that would be a good thing to have more users) ...  but here it is,
along with an example usage below which is part of a separate series.

The aim is to simplify iteration on static arrays, in the same way that we have
iterators for lists. The use of the ARRAY_SIZE macro, provides all the
protections given by "__must_be_array(arr)" to this macro too.

Regards

Kieran

=============================================================================
Example Usage from a pending UVC development:

+#define for_each_uvc_urb(uvc_urb, uvc_streaming) \
+       for_each_array_element(uvc_urb, uvc_streaming->uvc_urb)
 
 /*
  * Uninitialize isochronous/bulk URBs and free transfer buffers.
  */
 static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
 {
-       struct urb *urb;
-       unsigned int i;
+       struct uvc_urb *uvc_urb;

        uvc_video_stats_stop(stream);

-       for (i = 0; i < UVC_URBS; ++i) {
-               struct uvc_urb *uvc_urb = &stream->uvc_urb[i];
+       for_each_uvc_urb(uvc_urb, stream)
+               usb_kill_urb(uvc_urb->urb);

-               urb = uvc_urb->urb;
-               if (urb == NULL)
-                       continue;
+       flush_workqueue(stream->async_wq);

-               usb_kill_urb(urb);
-               usb_free_urb(urb);
+       for_each_uvc_urb(uvc_urb, stream) {
+               usb_free_urb(uvc_urb->urb);
                uvc_urb->urb = NULL;
        }

        if (free_buffers)
                uvc_free_urb_buffers(stream);
 }
=============================================================================




diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index ce51455e2adf..95d7dae248b7 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -70,6 +70,16 @@
  */
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
 
+/**
+ * for_each_array_element - Iterate all items in an array
+ * @elem: pointer of array type for iteration cursor
+ * @array: array to be iterated
+ */
+#define for_each_array_element(elem, array) \
+	for (elem = &(array)[0]; \
+	     elem < &(array)[ARRAY_SIZE(array)]; \
+	     ++elem)
+
 #define u64_to_user_ptr(x) (		\
 {					\
 	typecheck(u64, x);		\
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread
* Re: [PATCH][RFC] kernel.h: provide array iterator
@ 2018-03-16 19:40 Alexey Dobriyan
  0 siblings, 0 replies; 9+ messages in thread
From: Alexey Dobriyan @ 2018-03-16 19:40 UTC (permalink / raw)
  To: kieran.bingham; +Cc: rasmus.villemoes, linux-kernel

Proper form for iteration over an array is below:

	int a[] = {1, 2, 3, 5};
	for (int x: a) {
		...
	}

Your macro forces an iterator to be pointer which is uh-oh.

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

end of thread, other threads:[~2018-03-17 10:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-15 10:00 [PATCH][RFC] kernel.h: provide array iterator Kieran Bingham
2018-03-16  4:21 ` Kees Cook
2018-03-16  6:41   ` Julia Lawall
2018-03-16  7:31     ` Kieran Bingham
2018-03-16 15:27 ` Rasmus Villemoes
2018-03-16 18:45   ` Joe Perches
2018-03-17 10:12     ` Kieran Bingham
2018-03-17  9:32   ` Kieran Bingham
  -- strict thread matches above, loose matches on Subject: below --
2018-03-16 19:40 Alexey Dobriyan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox