static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit)
{
void *entry = NULL;
- struct maple_enode *prev_node;
struct maple_node *node;
- unsigned char offset;
unsigned long last;
enum maple_type mt;
- if (mas->index > limit) {
- mas->index = mas->last = limit;
- mas_pause(mas);
- return NULL;
- }
+ if (mas->index > limit)
+ goto limit_reached;
+
last = mas->last;
retry:
- offset = mas->offset;
- prev_node = mas->node;
node = mas_mn(mas);
mt = mte_node_type(mas->node);
mas->offset++;
return entry;
if (unlikely((mas->index > limit)))
- break;
+ goto limit_reached;
next_node:
- prev_node = mas->node;
- offset = mas->offset;
if (unlikely(mas_next_node(mas, node, limit))) {
mas_rewalk(mas, last);
goto retry;
mt = mte_node_type(mas->node);
}
+limit_reached:
+ mas->node = MAS_NONE;
mas->index = mas->last = limit;
- mas->offset = offset;
- mas->node = prev_node;
return NULL;
}
mas->index = 1;
mas->last = ULONG_MAX;
}
+ mas->node = MAS_NONE;
return NULL;
}
- if (mas->last == ULONG_MAX)
+ if (mas->last >= max)
return NULL;
/* Retries on dead nodes handled by mas_next_entry */
*/
void *mas_find(struct ma_state *mas, unsigned long max)
{
+ if (unlikely(mas_is_none(mas))) {
+ if (mas->last >= max)
+ goto none;
+
+ mas->index = mas->last;
+ mas->node = MAS_PAUSE;
+ }
+
if (unlikely(mas_is_paused(mas))) {
- if (unlikely(mas->last == ULONG_MAX)) {
+ if (unlikely(mas->last >= max)) {
mas->node = MAS_NONE;
return NULL;
}
mas->index = ++mas->last;
}
- if (unlikely(mas_is_none(mas)))
- mas->node = MAS_START;
+
+ if (unlikely(mas_is_ptr(mas))) {
+ mas->index = 1;
+ mas->last = ULONG_MAX;
+ goto none;
+ }
if (unlikely(mas_is_start(mas))) {
/* First run or continue */
}
if (unlikely(!mas_searchable(mas)))
- return NULL;
+ goto none;
+
+ if (mas->index == max)
+ goto none;
/* Retries on dead nodes handled by mas_next_entry */
return mas_next_entry(mas, max);
+
+none:
+ mas->node = MAS_NONE;
+ return NULL;
}
EXPORT_SYMBOL_GPL(mas_find);