This function supports iterating over a range of an array. Also add documentation links for xa_for_each_start().
Unified · Split
| @@ -82,10 +82,10 @@ at that index is ``NULL``, you can use xa_insert() which · 81 unmodified lines | |||
| 82 | returns ``-EBUSY`` if the entry is not empty. | 82 | returns ``-EBUSY`` if the entry is not empty. |
| 83 | 83 | ||
| 84 | You can copy entries out of the XArray into a plain array by calling | 84 | You can copy entries out of the XArray into a plain array by calling |
| 85 | xa_extract(). Or you can iterate over the present entries in | 85 | xa_extract(). Or you can iterate over the present entries in the XArray |
| 86 | the XArray by calling xa_for_each(). You may prefer to use | 86 | by calling xa_for_each(), xa_for_each_start() or xa_for_each_range(). |
| 87 | xa_find() or xa_find_after() to move to the next present | 87 | You may prefer to use xa_find() or xa_find_after() to move to the next |
| 88 | entry in the XArray. | 88 | present entry in the XArray. |
| 89 | 89 | ||
| 90 | Calling xa_store_range() stores the same entry in a range | 90 | Calling xa_store_range() stores the same entry in a range |
| 91 | of indices. If you do this, some of the other operations will behave | 91 | of indices. If you do this, some of the other operations will behave |
| @@ -193,6 +193,8 @@ No lock needed: · 101 unmodified lines | |||
| 193 | Takes RCU read lock: | 193 | Takes RCU read lock: |
| 194 | * xa_load() | 194 | * xa_load() |
| 195 | * xa_for_each() | 195 | * xa_for_each() |
| 196 | * xa_for_each_start() | ||
| 197 | * xa_for_each_range() | ||
| 196 | * xa_find() | 198 | * xa_find() |
| 197 | * xa_find_after() | 199 | * xa_find_after() |
| 198 | * xa_extract() | 200 | * xa_extract() |
| @@ -416,6 +416,36 @@ static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark) · 415 unmodified lines | |||
| 416 | return xa->xa_flags & XA_FLAGS_MARK(mark); | 416 | return xa->xa_flags & XA_FLAGS_MARK(mark); |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | /** | ||
| 420 | * xa_for_each_range() - Iterate over a portion of an XArray. | ||
| 421 | * @xa: XArray. | ||
| 422 | * @index: Index of @entry. | ||
| 423 | * @entry: Entry retrieved from array. | ||
| 424 | * @start: First index to retrieve from array. | ||
| 425 | * @last: Last index to retrieve from array. | ||
| 426 | * | ||
| 427 | * During the iteration, @entry will have the value of the entry stored | ||
| 428 | * in @xa at @index. You may modify @index during the iteration if you | ||
| 429 | * want to skip or reprocess indices. It is safe to modify the array | ||
| 430 | * during the iteration. At the end of the iteration, @entry will be set | ||
| 431 | * to NULL and @index will have a value less than or equal to max. | ||
| 432 | * | ||
| 433 | * xa_for_each_range() is O(n.log(n)) while xas_for_each() is O(n). You have | ||
| 434 | * to handle your own locking with xas_for_each(), and if you have to unlock | ||
| 435 | * after each iteration, it will also end up being O(n.log(n)). | ||
| 436 | * xa_for_each_range() will spin if it hits a retry entry; if you intend to | ||
| 437 | * see retry entries, you should use the xas_for_each() iterator instead. | ||
| 438 | * The xas_for_each() iterator will expand into more inline code than | ||
| 439 | * xa_for_each_range(). | ||
| 440 | * | ||
| 441 | * Context: Any context. Takes and releases the RCU lock. | ||
| 442 | */ | ||
| 443 | #define xa_for_each_range(xa, index, entry, start, last) \ | ||
| 444 | for (index = start, \ | ||
| 445 | entry = xa_find(xa, &index, last, XA_PRESENT); \ | ||
| 446 | entry; \ | ||
| 447 | entry = xa_find_after(xa, &index, last, XA_PRESENT)) | ||
| 448 | |||
| 419 | /** | 449 | /** |
| 420 | * xa_for_each_start() - Iterate over a portion of an XArray. | 450 | * xa_for_each_start() - Iterate over a portion of an XArray. |
| 421 | * @xa: XArray. | 451 | * @xa: XArray. |
| @@ -439,11 +469,8 @@ static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark) · 17 unmodified lines | |||
| 439 | * | 469 | * |
| 440 | * Context: Any context. Takes and releases the RCU lock. | 470 | * Context: Any context. Takes and releases the RCU lock. |
| 441 | */ | 471 | */ |
| 442 | #define xa_for_each_start(xa, index, entry, start) \ | 472 | #define xa_for_each_start(xa, index, entry, start) \ |
| 443 | for (index = start, \ | 473 | xa_for_each_range(xa, index, entry, start, ULONG_MAX) |
| 444 | entry = xa_find(xa, &index, ULONG_MAX, XA_PRESENT); \ | ||
| 445 | entry; \ | ||
| 446 | entry = xa_find_after(xa, &index, ULONG_MAX, XA_PRESENT)) | ||
| 447 | 474 | ||
| 448 | /** | 475 | /** |
| 449 | * xa_for_each() - Iterate over present entries in an XArray. | 476 | * xa_for_each() - Iterate over present entries in an XArray. |