History

ptr_ring: move free-space check into separate helper

This patch moves the check for available free space for a new entry into a separate function. Existing callers that only check for a non-zero return value are unaffected. __ptr_ring_produce() now returns -EINVAL for a zero-size ring and -ENOSPC when full, whereas before both cases returned -ENOSPC. The new helper allows callers to determine in advance whether a single subsequent __ptr_ring_produce() call will succeed. This information can, for example, be used to temporarily stop producing until __ptr_ring_check_produce() indicates that space is available again. The return values are documented above the helper, as a caller that waits for space must distinguish the transient -ENOSPC from the permanent -EINVAL.

Simon Schippers committed 3 months ago

Commit 43be21e1 parent f65c1fb1 file · +24 −2Browse files

Showing the changes to include (1 of 1 file). Show all

Unified · Split

include/linux/ptr_ring.h+24−2
@@ -96,6 +96,26 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r) · 95 unmodified lines
96 return ret;96 return ret;
97}97}
98 98
99/* Report whether the next __ptr_ring_produce() has room for one entry:
100 * 0 means the single slot at r->queue[r->producer] is free, -ENOSPC means
101 * the ring is full, which is transient, and -EINVAL means r->size is 0,
102 * which is permanent. A caller that stops producing and waits for space
103 * must therefore do so only for -ENOSPC.
104 *
105 * Note: callers invoking this in a loop must use a compiler barrier,
106 * for example cpu_relax(). Callers must hold producer_lock.
107 */
108static inline int __ptr_ring_check_produce(struct ptr_ring *r)
109{
110 if (unlikely(!r->size))
111 return -EINVAL;
112
113 if (data_race(r->queue[r->producer]))
114 return -ENOSPC;
115
116 return 0;
117}
118
99/* Note: callers invoking this in a loop must use a compiler barrier,119/* Note: callers invoking this in a loop must use a compiler barrier,
100 * for example cpu_relax(). Callers must hold producer_lock.120 * for example cpu_relax(). Callers must hold producer_lock.
101 * Callers are responsible for making sure pointer that is being queued121 * Callers are responsible for making sure pointer that is being queued
@@ -103,8 +123,10 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r) · 1 unmodified line
103 */123 */
104static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)124static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)
105{125{
106 if (unlikely(!r->size) || data_race(r->queue[r->producer]))126 int ret = __ptr_ring_check_produce(r);
107 return -ENOSPC;127
128 if (ret)
129 return ret;
108 130
109 /* Make sure the pointer we are storing points to a valid data. */131 /* Make sure the pointer we are storing points to a valid data. */
110 /* Pairs with the dependency ordering in __ptr_ring_consume. */132 /* Pairs with the dependency ordering in __ptr_ring_consume. */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t