New upstream version 16.11.9
[deb_dpdk.git] / lib / librte_eal / linuxapp / kni / kni_fifo.h
1 /*-
2  * GPL LICENSE SUMMARY
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of version 2 of the GNU General Public License as
8  *   published by the Free Software Foundation.
9  *
10  *   This program is distributed in the hope that it will be useful, but
11  *   WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *   General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18  *   The full GNU General Public License is included in this distribution
19  *   in the file called LICENSE.GPL.
20  *
21  *   Contact Information:
22  *   Intel Corporation
23  */
24
25 #ifndef _KNI_FIFO_H_
26 #define _KNI_FIFO_H_
27
28 #include <exec-env/rte_kni_common.h>
29
30 /* Skip some memory barriers on Linux < 3.14 */
31 #ifndef smp_load_acquire
32 #define smp_load_acquire(a) (*(a))
33 #endif
34 #ifndef smp_store_release
35 #define smp_store_release(a, b) *(a) = (b)
36 #endif
37
38 /**
39  * Adds num elements into the fifo. Return the number actually written
40  */
41 static inline uint32_t
42 kni_fifo_put(struct rte_kni_fifo *fifo, void **data, uint32_t num)
43 {
44         uint32_t i = 0;
45         uint32_t fifo_write = fifo->write;
46         uint32_t fifo_read = smp_load_acquire(&fifo->read);
47         uint32_t new_write = fifo_write;
48
49         for (i = 0; i < num; i++) {
50                 new_write = (new_write + 1) & (fifo->len - 1);
51
52                 if (new_write == fifo_read)
53                         break;
54                 fifo->buffer[fifo_write] = data[i];
55                 fifo_write = new_write;
56         }
57         smp_store_release(&fifo->write, fifo_write);
58
59         return i;
60 }
61
62 /**
63  * Get up to num elements from the fifo. Return the number actully read
64  */
65 static inline uint32_t
66 kni_fifo_get(struct rte_kni_fifo *fifo, void **data, uint32_t num)
67 {
68         uint32_t i = 0;
69         uint32_t new_read = fifo->read;
70         uint32_t fifo_write = smp_load_acquire(&fifo->write);
71
72         for (i = 0; i < num; i++) {
73                 if (new_read == fifo_write)
74                         break;
75
76                 data[i] = fifo->buffer[new_read];
77                 new_read = (new_read + 1) & (fifo->len - 1);
78         }
79         smp_store_release(&fifo->read, new_read);
80
81         return i;
82 }
83
84 /**
85  * Get the num of elements in the fifo
86  */
87 static inline uint32_t
88 kni_fifo_count(struct rte_kni_fifo *fifo)
89 {
90         uint32_t fifo_write = smp_load_acquire(&fifo->write);
91         uint32_t fifo_read = smp_load_acquire(&fifo->read);
92         return (fifo->len + fifo_write - fifo_read) & (fifo->len - 1);
93 }
94
95 /**
96  * Get the num of available elements in the fifo
97  */
98 static inline uint32_t
99 kni_fifo_free_count(struct rte_kni_fifo *fifo)
100 {
101         uint32_t fifo_write = smp_load_acquire(&fifo->write);
102         uint32_t fifo_read = smp_load_acquire(&fifo->read);
103         return (fifo_read - fifo_write - 1) & (fifo->len - 1);
104 }
105
106 #ifdef RTE_KNI_VHOST
107 /**
108  * Initializes the kni fifo structure
109  */
110 static inline void
111 kni_fifo_init(struct rte_kni_fifo *fifo, uint32_t size)
112 {
113         fifo->write = 0;
114         fifo->read = 0;
115         fifo->len = size;
116         fifo->elem_size = sizeof(void *);
117 }
118 #endif
119
120 #endif /* _KNI_FIFO_H_ */