New upstream version 17.11
[deb_dpdk.git] / drivers / event / sw / iq_ring.h
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Intel Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /*
34  * Ring structure definitions used for the internal ring buffers of the
35  * SW eventdev implementation. These are designed for single-core use only.
36  */
37 #ifndef _IQ_RING_
38 #define _IQ_RING_
39
40 #include <stdint.h>
41
42 #include <rte_common.h>
43 #include <rte_memory.h>
44 #include <rte_malloc.h>
45 #include <rte_eventdev.h>
46
47 #define IQ_RING_NAMESIZE 12
48 #define QID_IQ_DEPTH 512
49 #define QID_IQ_MASK (uint16_t)(QID_IQ_DEPTH - 1)
50
51 struct iq_ring {
52         char name[IQ_RING_NAMESIZE] __rte_cache_aligned;
53         uint16_t write_idx;
54         uint16_t read_idx;
55
56         struct rte_event ring[QID_IQ_DEPTH];
57 };
58
59 static inline struct iq_ring *
60 iq_ring_create(const char *name, unsigned int socket_id)
61 {
62         struct iq_ring *retval;
63
64         retval = rte_malloc_socket(NULL, sizeof(*retval), 0, socket_id);
65         if (retval == NULL)
66                 goto end;
67
68         snprintf(retval->name, sizeof(retval->name), "%s", name);
69         retval->write_idx = retval->read_idx = 0;
70 end:
71         return retval;
72 }
73
74 static inline void
75 iq_ring_destroy(struct iq_ring *r)
76 {
77         rte_free(r);
78 }
79
80 static __rte_always_inline uint16_t
81 iq_ring_count(const struct iq_ring *r)
82 {
83         return r->write_idx - r->read_idx;
84 }
85
86 static __rte_always_inline uint16_t
87 iq_ring_free_count(const struct iq_ring *r)
88 {
89         return QID_IQ_MASK - iq_ring_count(r);
90 }
91
92 static __rte_always_inline uint16_t
93 iq_ring_enqueue_burst(struct iq_ring *r, struct rte_event *qes, uint16_t nb_qes)
94 {
95         const uint16_t read = r->read_idx;
96         uint16_t write = r->write_idx;
97         const uint16_t space = read + QID_IQ_MASK - write;
98         uint16_t i;
99
100         if (space < nb_qes)
101                 nb_qes = space;
102
103         for (i = 0; i < nb_qes; i++, write++)
104                 r->ring[write & QID_IQ_MASK] = qes[i];
105
106         r->write_idx = write;
107
108         return nb_qes;
109 }
110
111 static __rte_always_inline uint16_t
112 iq_ring_dequeue_burst(struct iq_ring *r, struct rte_event *qes, uint16_t nb_qes)
113 {
114         uint16_t read = r->read_idx;
115         const uint16_t write = r->write_idx;
116         const uint16_t items = write - read;
117         uint16_t i;
118
119         for (i = 0; i < nb_qes; i++, read++)
120                 qes[i] = r->ring[read & QID_IQ_MASK];
121
122         if (items < nb_qes)
123                 nb_qes = items;
124
125         r->read_idx += nb_qes;
126
127         return nb_qes;
128 }
129
130 /* assumes there is space, from a previous dequeue_burst */
131 static __rte_always_inline uint16_t
132 iq_ring_put_back(struct iq_ring *r, struct rte_event *qes, uint16_t nb_qes)
133 {
134         uint16_t i, read = r->read_idx;
135
136         for (i = nb_qes; i-- > 0; )
137                 r->ring[--read & QID_IQ_MASK] = qes[i];
138
139         r->read_idx = read;
140         return nb_qes;
141 }
142
143 static __rte_always_inline const struct rte_event *
144 iq_ring_peek(const struct iq_ring *r)
145 {
146         return &r->ring[r->read_idx & QID_IQ_MASK];
147 }
148
149 static __rte_always_inline void
150 iq_ring_pop(struct iq_ring *r)
151 {
152         r->read_idx++;
153 }
154
155 static __rte_always_inline int
156 iq_ring_enqueue(struct iq_ring *r, const struct rte_event *qe)
157 {
158         const uint16_t read = r->read_idx;
159         const uint16_t write = r->write_idx;
160         const uint16_t space = read + QID_IQ_MASK - write;
161
162         if (space == 0)
163                 return -1;
164
165         r->ring[write & QID_IQ_MASK] = *qe;
166
167         r->write_idx = write + 1;
168
169         return 0;
170 }
171
172 #endif