aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/mpmc_ptr_ring.h
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-06-18 15:07:47 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-06-18 15:08:56 +0200
commit95660e9b9bce18e0a1abcf49118f7f65b196cd9c (patch)
tree2a95e395aa1037f9432d7e003805eb3c86e0ea7e /src/mpmc_ptr_ring.h
parentmpmc_ptr_ring: nits (diff)
downloadwireguard-monolithic-historical-95660e9b9bce18e0a1abcf49118f7f65b196cd9c.tar.xz
wireguard-monolithic-historical-95660e9b9bce18e0a1abcf49118f7f65b196cd9c.zip
mpmc_ptr_ring: disable preemption
Diffstat (limited to 'src/mpmc_ptr_ring.h')
-rw-r--r--src/mpmc_ptr_ring.h21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/mpmc_ptr_ring.h b/src/mpmc_ptr_ring.h
index fc139d2..8e7aa49 100644
--- a/src/mpmc_ptr_ring.h
+++ b/src/mpmc_ptr_ring.h
@@ -81,6 +81,8 @@ static inline int mpmc_ptr_ring_produce(struct mpmc_ptr_ring *r, void *ptr)
int p, c;
unsigned int mask = r->mask;
+ preempt_disable();
+
p = atomic_read(&r->producer_head);
for (;;) {
@@ -104,8 +106,10 @@ static inline int mpmc_ptr_ring_produce(struct mpmc_ptr_ring *r, void *ptr)
smp_rmb();
new_p = atomic_read(&r->producer_head);
- if (new_p == p)
+ if (new_p == p) {
+ preempt_enable();
return -ENOSPC;
+ }
p = new_p;
}
@@ -124,6 +128,7 @@ static inline int mpmc_ptr_ring_produce(struct mpmc_ptr_ring *r, void *ptr)
smp_wmb();
atomic_set(&r->producer_tail, p + 1);
+ preempt_enable();
return 0;
}
@@ -133,6 +138,8 @@ static inline void *mpmc_ptr_ring_consume(struct mpmc_ptr_ring *r)
unsigned int mask = r->mask;
void *element;
+ preempt_disable();
+
c = atomic_read(&r->consumer_head);
do {
@@ -142,8 +149,10 @@ static inline void *mpmc_ptr_ring_consume(struct mpmc_ptr_ring *r)
p = atomic_read(&r->producer_tail);
/* Is the ring empty? */
- if (unlikely(p == c))
+ if (unlikely(p == c)) {
+ preempt_enable();
return NULL;
+ }
element = READ_ONCE(r->queue[c & mask]);
@@ -153,6 +162,7 @@ static inline void *mpmc_ptr_ring_consume(struct mpmc_ptr_ring *r)
*/
} while (!atomic_try_cmpxchg_release(&r->consumer_head, &c, c + 1));
+ preempt_enable();
return element;
}
@@ -199,6 +209,8 @@ static inline void *__mpmc_ptr_ring_peek(struct mpmc_ptr_ring *r)
unsigned int mask = r->mask;
void *element;
+ preempt_disable();
+
c = atomic_read(&r->consumer_head);
/* Fetch consumer_head first */
@@ -206,14 +218,17 @@ static inline void *__mpmc_ptr_ring_peek(struct mpmc_ptr_ring *r)
p = atomic_read(&r->producer_tail);
- if (c == p)
+ if (c == p) {
+ preempt_enable();
return NULL;
+ }
/* TODO */
smp_rmb();
element = READ_ONCE(r->queue[c & mask]);
+ preempt_enable();
return element;
}