DPDK  19.02.0
rte_kni_fifo.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 
6 
18 #ifdef RTE_USE_C11_MEM_MODEL
19 #define __KNI_LOAD_ACQUIRE(src) ({ \
20  __atomic_load_n((src), __ATOMIC_ACQUIRE); \
21  })
22 #define __KNI_STORE_RELEASE(dst, value) do { \
23  __atomic_store_n((dst), value, __ATOMIC_RELEASE); \
24  } while(0)
25 #else
26 #define __KNI_LOAD_ACQUIRE(src) ({ \
27  typeof (*(src)) val = *(src); \
28  rte_smp_rmb(); \
29  val; \
30  })
31 #define __KNI_STORE_RELEASE(dst, value) do { \
32  *(dst) = value; \
33  rte_smp_wmb(); \
34  } while(0)
35 #endif
36 
40 static void
41 kni_fifo_init(struct rte_kni_fifo *fifo, unsigned size)
42 {
43  /* Ensure size is power of 2 */
44  if (size & (size - 1))
45  rte_panic("KNI fifo size must be power of 2\n");
46 
47  fifo->write = 0;
48  fifo->read = 0;
49  fifo->len = size;
50  fifo->elem_size = sizeof(void *);
51 }
52 
56 static inline unsigned
57 kni_fifo_put(struct rte_kni_fifo *fifo, void **data, unsigned num)
58 {
59  unsigned i = 0;
60  unsigned fifo_write = fifo->write;
61  unsigned new_write = fifo_write;
62  unsigned fifo_read = __KNI_LOAD_ACQUIRE(&fifo->read);
63 
64  for (i = 0; i < num; i++) {
65  new_write = (new_write + 1) & (fifo->len - 1);
66 
67  if (new_write == fifo_read)
68  break;
69  fifo->buffer[fifo_write] = data[i];
70  fifo_write = new_write;
71  }
72  __KNI_STORE_RELEASE(&fifo->write, fifo_write);
73  return i;
74 }
75 
79 static inline unsigned
80 kni_fifo_get(struct rte_kni_fifo *fifo, void **data, unsigned num)
81 {
82  unsigned i = 0;
83  unsigned new_read = fifo->read;
84  unsigned fifo_write = __KNI_LOAD_ACQUIRE(&fifo->write);
85 
86  for (i = 0; i < num; i++) {
87  if (new_read == fifo_write)
88  break;
89 
90  data[i] = fifo->buffer[new_read];
91  new_read = (new_read + 1) & (fifo->len - 1);
92  }
93  __KNI_STORE_RELEASE(&fifo->read, new_read);
94  return i;
95 }
96 
100 static inline uint32_t
101 kni_fifo_count(struct rte_kni_fifo *fifo)
102 {
103  unsigned fifo_write = __KNI_LOAD_ACQUIRE(&fifo->write);
104  unsigned fifo_read = __KNI_LOAD_ACQUIRE(&fifo->read);
105  return (fifo->len + fifo_write - fifo_read) & (fifo->len - 1);
106 }