1a633eec7SKonstantin Ananyev/*
2a633eec7SKonstantin Ananyev * Copyright (c) 2016  Intel Corporation.
3a633eec7SKonstantin Ananyev * Licensed under the Apache License, Version 2.0 (the "License");
4a633eec7SKonstantin Ananyev * you may not use this file except in compliance with the License.
5a633eec7SKonstantin Ananyev * You may obtain a copy of the License at:
6a633eec7SKonstantin Ananyev *
7a633eec7SKonstantin Ananyev *     http://www.apache.org/licenses/LICENSE-2.0
8a633eec7SKonstantin Ananyev *
9a633eec7SKonstantin Ananyev * Unless required by applicable law or agreed to in writing, software
10a633eec7SKonstantin Ananyev * distributed under the License is distributed on an "AS IS" BASIS,
11a633eec7SKonstantin Ananyev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a633eec7SKonstantin Ananyev * See the License for the specific language governing permissions and
13a633eec7SKonstantin Ananyev * limitations under the License.
14a633eec7SKonstantin Ananyev */
15a633eec7SKonstantin Ananyev
16a633eec7SKonstantin Ananyev#include <string.h>
17a633eec7SKonstantin Ananyev#include <stdarg.h>
18a633eec7SKonstantin Ananyev#include <stdio.h>
19a633eec7SKonstantin Ananyev#include <stdlib.h>
20a633eec7SKonstantin Ananyev#include <stdint.h>
21a633eec7SKonstantin Ananyev#include <inttypes.h>
22a633eec7SKonstantin Ananyev#include <errno.h>
23a633eec7SKonstantin Ananyev
24a633eec7SKonstantin Ananyev#include <rte_common.h>
25a633eec7SKonstantin Ananyev#include <rte_log.h>
26a633eec7SKonstantin Ananyev#include <rte_errno.h>
27a633eec7SKonstantin Ananyev#include <rte_launch.h>
28a633eec7SKonstantin Ananyev#include <rte_cycles.h>
29a633eec7SKonstantin Ananyev#include <rte_eal.h>
30a633eec7SKonstantin Ananyev#include <rte_per_lcore.h>
31a633eec7SKonstantin Ananyev#include <rte_lcore.h>
32a633eec7SKonstantin Ananyev#include <rte_ring.h>
33a633eec7SKonstantin Ananyev#include <tle_dring.h>
34a633eec7SKonstantin Ananyev#include <rte_random.h>
35a633eec7SKonstantin Ananyev
36a633eec7SKonstantin Ananyev#define OBJ_NUM		UINT16_MAX
37a633eec7SKonstantin Ananyev#define ITER_NUM	(4 * OBJ_NUM)
38a633eec7SKonstantin Ananyev
39a633eec7SKonstantin Ananyevenum {
40a633eec7SKonstantin Ananyev	NONE,
41a633eec7SKonstantin Ananyev	SINGLE,
42a633eec7SKonstantin Ananyev	MULTI,
43a633eec7SKonstantin Ananyev};
44a633eec7SKonstantin Ananyev
45a633eec7SKonstantin Ananyevstruct dring_arg {
46a633eec7SKonstantin Ananyev	struct tle_dring *dr;
47a633eec7SKonstantin Ananyev	struct rte_ring *r;
48a633eec7SKonstantin Ananyev	uint32_t iter;
49a633eec7SKonstantin Ananyev	int32_t enq_type;
50a633eec7SKonstantin Ananyev	int32_t deq_type;
51a633eec7SKonstantin Ananyev	uint32_t enq;
52a633eec7SKonstantin Ananyev	uint32_t deq;
53a633eec7SKonstantin Ananyev};
54a633eec7SKonstantin Ananyev
55a633eec7SKonstantin Ananyev/*
56a633eec7SKonstantin Ananyev * free memory allocated for drbs and for the ring itself.
57a633eec7SKonstantin Ananyev */
58a633eec7SKonstantin Ananyevstatic void
59a633eec7SKonstantin Ananyevfini_drb_ring(struct rte_ring *r)
60a633eec7SKonstantin Ananyev{
61a633eec7SKonstantin Ananyev	struct tle_drb *drb;
62a633eec7SKonstantin Ananyev
63a633eec7SKonstantin Ananyev	/* free drbs. */
64a633eec7SKonstantin Ananyev	while (rte_ring_dequeue(r, (void **)&drb) == 0)
65a633eec7SKonstantin Ananyev		free(drb);
66a633eec7SKonstantin Ananyev
67a633eec7SKonstantin Ananyev	/* free ring. */
68a633eec7SKonstantin Ananyev	free(r);
69a633eec7SKonstantin Ananyev}
70a633eec7SKonstantin Ananyev
71a633eec7SKonstantin Ananyev/*
72a633eec7SKonstantin Ananyev * allocate drbs for specified number of objects, put them into the ring.
73a633eec7SKonstantin Ananyev */
74a633eec7SKonstantin Ananyevstatic struct rte_ring *
75a633eec7SKonstantin Ananyevinit_drb_ring(uint32_t num)
76a633eec7SKonstantin Ananyev{
77a633eec7SKonstantin Ananyev	uint32_t i, k, n;
78a633eec7SKonstantin Ananyev	size_t sz, tsz;
79a633eec7SKonstantin Ananyev	struct rte_ring *r;
80a633eec7SKonstantin Ananyev	struct tle_drb *drb;
81a633eec7SKonstantin Ananyev
82a633eec7SKonstantin Ananyev	/* allocate and initialise rte_ring. */
83a633eec7SKonstantin Ananyev
84a633eec7SKonstantin Ananyev	n = rte_align32pow2(num);
85fbba0a3bSMohammad Abdul Awal	sz =  rte_ring_get_memsize(n);
86a633eec7SKonstantin Ananyev
87a633eec7SKonstantin Ananyev	r = calloc(1, sz);
88a633eec7SKonstantin Ananyev	if (r == NULL) {
89a633eec7SKonstantin Ananyev		printf("%s:%d(%u) failed to allocate %zu bytes;\n",
90a633eec7SKonstantin Ananyev			__func__, __LINE__, num, sz);
91a633eec7SKonstantin Ananyev		return NULL;
92a633eec7SKonstantin Ananyev	}
93a633eec7SKonstantin Ananyev
94a633eec7SKonstantin Ananyev	rte_ring_init(r, __func__, n, 0);
95a633eec7SKonstantin Ananyev
96a633eec7SKonstantin Ananyev	/* allocate drbs and put them into the ring. */
97a633eec7SKonstantin Ananyev
98a633eec7SKonstantin Ananyev	tsz = sz;
99a633eec7SKonstantin Ananyev	for (i = 0; i != num; i += k) {
100a633eec7SKonstantin Ananyev		k =  rte_rand() % (UINT8_MAX + 1) + 1;
101a633eec7SKonstantin Ananyev		k = RTE_MIN(k, num - i);
102a633eec7SKonstantin Ananyev		sz = tle_drb_calc_size(k);
103a633eec7SKonstantin Ananyev		drb = calloc(1, sz);
104a633eec7SKonstantin Ananyev		if (drb == NULL) {
105a633eec7SKonstantin Ananyev			printf("%s:%d(%u) %u-th iteration: "
106a633eec7SKonstantin Ananyev				"failed to allocate %zu bytes;\n",
107a633eec7SKonstantin Ananyev				__func__, __LINE__, num, i, sz);
108a633eec7SKonstantin Ananyev			fini_drb_ring(r);
109a633eec7SKonstantin Ananyev			return NULL;
110a633eec7SKonstantin Ananyev		}
111a633eec7SKonstantin Ananyev		drb->size = k;
112a633eec7SKonstantin Ananyev		rte_ring_enqueue(r, drb);
113a633eec7SKonstantin Ananyev		tsz += sz;
114a633eec7SKonstantin Ananyev	}
115a633eec7SKonstantin Ananyev
116a633eec7SKonstantin Ananyev	printf("%s(%u) total %zu bytes allocated, number of drbs: %u;\n",
117a633eec7SKonstantin Ananyev		__func__, num, tsz, rte_ring_count(r));
118a633eec7SKonstantin Ananyev	return r;
119a633eec7SKonstantin Ananyev}
120a633eec7SKonstantin Ananyev
121a633eec7SKonstantin Ananyev/*
122a633eec7SKonstantin Ananyev * Each enqueued object will contain:
123a633eec7SKonstantin Ananyev * [2-3]B: it's own sequence number.
124a633eec7SKonstantin Ananyev * [0-1]B: next object sequence number, or UINT16_MAX.
125a633eec7SKonstantin Ananyev */
126a633eec7SKonstantin Ananyevstatic void
127a633eec7SKonstantin Ananyevtest_fill_obj(uintptr_t obj[], uint32_t num)
128a633eec7SKonstantin Ananyev{
129a633eec7SKonstantin Ananyev	uint32_t i;
130a633eec7SKonstantin Ananyev
131a633eec7SKonstantin Ananyev	for (i = 0; i != num - 1; i++)
132a633eec7SKonstantin Ananyev		obj[i] = i << 16 | (i + 1);
133a633eec7SKonstantin Ananyev
134a633eec7SKonstantin Ananyev	obj[i] = i << 16 | UINT16_MAX;
135a633eec7SKonstantin Ananyev}
136a633eec7SKonstantin Ananyev
137a633eec7SKonstantin Ananyevstatic uint32_t
138a633eec7SKonstantin Ananyevtest_check_obj(uintptr_t obj[], uint32_t num)
139a633eec7SKonstantin Ananyev{
140a633eec7SKonstantin Ananyev	uint32_t i, h, l, oh, ol;
141a633eec7SKonstantin Ananyev
142a633eec7SKonstantin Ananyev	h = obj[0] >> 16;
143a633eec7SKonstantin Ananyev	l = obj[0] & UINT16_MAX;
144a633eec7SKonstantin Ananyev
145a633eec7SKonstantin Ananyev	if (h + 1 != l && l != UINT16_MAX)
146a633eec7SKonstantin Ananyev		return 0;
147a633eec7SKonstantin Ananyev
148a633eec7SKonstantin Ananyev	if (l == UINT16_MAX)
149a633eec7SKonstantin Ananyev		l = 0;
150a633eec7SKonstantin Ananyev
151a633eec7SKonstantin Ananyev	for (i = 1; i != num; i++) {
152a633eec7SKonstantin Ananyev
153a633eec7SKonstantin Ananyev		oh = obj[i] >> 16;
154a633eec7SKonstantin Ananyev		ol = obj[i] & UINT16_MAX;
155a633eec7SKonstantin Ananyev
156a633eec7SKonstantin Ananyev		if (l != oh || (oh + 1 != ol && ol != UINT16_MAX))
157a633eec7SKonstantin Ananyev			return i;
158a633eec7SKonstantin Ananyev
159a633eec7SKonstantin Ananyev		l = ol;
160a633eec7SKonstantin Ananyev		if (l == UINT16_MAX)
161a633eec7SKonstantin Ananyev			l = 0;
162a633eec7SKonstantin Ananyev	}
163a633eec7SKonstantin Ananyev
164a633eec7SKonstantin Ananyev	return num;
165a633eec7SKonstantin Ananyev}
166a633eec7SKonstantin Ananyev
167a633eec7SKonstantin Ananyevstatic int
168a633eec7SKonstantin Ananyevtest_dring_dequeue(struct tle_dring *dr, struct rte_ring *r, uint32_t num,
169a633eec7SKonstantin Ananyev	int32_t type)
170a633eec7SKonstantin Ananyev{
171a633eec7SKonstantin Ananyev	uint32_t i, k, lc, n, t;
172a633eec7SKonstantin Ananyev	struct tle_drb *drb[num];
173a633eec7SKonstantin Ananyev	uintptr_t obj[num];
174a633eec7SKonstantin Ananyev
175a633eec7SKonstantin Ananyev	lc = rte_lcore_id();
176a633eec7SKonstantin Ananyev	k = num;
177a633eec7SKonstantin Ananyev
178a633eec7SKonstantin Ananyev	/* dequeue objects. */
179a633eec7SKonstantin Ananyev	if (type == SINGLE)
180a633eec7SKonstantin Ananyev		n = tle_dring_sc_dequeue(dr, (const void **)obj, num, drb, &k);
181a633eec7SKonstantin Ananyev	else if (type == MULTI)
182a633eec7SKonstantin Ananyev		n = tle_dring_mc_dequeue(dr, (const void **)obj, num, drb, &k);
183a633eec7SKonstantin Ananyev	else
184a633eec7SKonstantin Ananyev		return -EINVAL;
185a633eec7SKonstantin Ananyev
186a633eec7SKonstantin Ananyev	if (n == 0)
187a633eec7SKonstantin Ananyev		return 0;
188a633eec7SKonstantin Ananyev
189a633eec7SKonstantin Ananyev	/* check the data returned. */
190a633eec7SKonstantin Ananyev	t = test_check_obj(obj, n);
191a633eec7SKonstantin Ananyev	if (t != n) {
192a633eec7SKonstantin Ananyev		printf("%s:%d(%p, %u) at lcore %u: invalid dequeued object, "
193a633eec7SKonstantin Ananyev			"n=%u, idx=%u, obj=%#x, prev obj=%#x;\n",
194a633eec7SKonstantin Ananyev			__func__, __LINE__, dr, num, lc, n, t,
195a633eec7SKonstantin Ananyev			(uint32_t)obj[t], (t == 0) ? 0 : (uint32_t)obj[t - 1]);
196a633eec7SKonstantin Ananyev		return -EFAULT;
197a633eec7SKonstantin Ananyev	}
198a633eec7SKonstantin Ananyev
199a633eec7SKonstantin Ananyev	/* check and free drbs. */
200a633eec7SKonstantin Ananyev	for (i = 0; i != k; i++) {
201a633eec7SKonstantin Ananyev		/* udata value for drb in use shouldn't be zero. */
202a633eec7SKonstantin Ananyev		if (drb[i]->udata == NULL) {
203a633eec7SKonstantin Ananyev			printf("error @ %s:%d(%p, %u) at lcore %u: "
204a633eec7SKonstantin Ananyev				"erroneous drb@%p={udata=%p, size=%u,};\n",
205a633eec7SKonstantin Ananyev				__func__, __LINE__, dr, num, lc, drb[i],
206a633eec7SKonstantin Ananyev				drb[i]->udata, drb[i]->size);
207a633eec7SKonstantin Ananyev			return -EFAULT;
208a633eec7SKonstantin Ananyev		}
209a633eec7SKonstantin Ananyev		drb[i]->udata = NULL;
210a633eec7SKonstantin Ananyev		rte_ring_enqueue(r, drb[i]);
211a633eec7SKonstantin Ananyev	}
212a633eec7SKonstantin Ananyev
213a633eec7SKonstantin Ananyev	return n;
214a633eec7SKonstantin Ananyev}
215a633eec7SKonstantin Ananyev
216a633eec7SKonstantin Ananyevstatic int
217a633eec7SKonstantin Ananyevtest_dring_enqueue(struct tle_dring *dr, struct rte_ring *r, uint32_t num,
218a633eec7SKonstantin Ananyev	int32_t type)
219a633eec7SKonstantin Ananyev{
220a633eec7SKonstantin Ananyev	uint32_t i, j, k, lc, nb;
221a633eec7SKonstantin Ananyev	struct tle_drb *drb[num];
222a633eec7SKonstantin Ananyev	uintptr_t obj[num];
223a633eec7SKonstantin Ananyev
224a633eec7SKonstantin Ananyev	lc = rte_lcore_id();
225a633eec7SKonstantin Ananyev
226a633eec7SKonstantin Ananyev	/* prepare drbs to enqueue up to *num* objects. */
227a633eec7SKonstantin Ananyev	for (i = 0, j = 0; i != num; i += k, j++) {
228a633eec7SKonstantin Ananyev
229a633eec7SKonstantin Ananyev		if (rte_ring_dequeue(r, (void **)&drb[j]) != 0)
230a633eec7SKonstantin Ananyev			break;
231a633eec7SKonstantin Ananyev
232a633eec7SKonstantin Ananyev		/* udata value for unused drb should be zero. */
233a633eec7SKonstantin Ananyev		if (drb[j]->udata != NULL) {
234a633eec7SKonstantin Ananyev			printf("error @ %s:%d(%p, %u) at lcore %u: "
235a633eec7SKonstantin Ananyev				"erroneous drb@%p={udata=%p, size=%u,};\n",
236a633eec7SKonstantin Ananyev				__func__, __LINE__, dr, num, lc, drb[j],
237a633eec7SKonstantin Ananyev				drb[j]->udata, drb[j]->size);
238a633eec7SKonstantin Ananyev			return -EFAULT;
239a633eec7SKonstantin Ananyev		}
240a633eec7SKonstantin Ananyev
241a633eec7SKonstantin Ananyev		/* update udata value with current lcore id. */
242a633eec7SKonstantin Ananyev		drb[j]->udata = (void *)(uintptr_t)(lc + 1);
243a633eec7SKonstantin Ananyev		k = drb[j]->size;
244a633eec7SKonstantin Ananyev		k = RTE_MIN(k, num - i);
245a633eec7SKonstantin Ananyev	}
246a633eec7SKonstantin Ananyev
247a633eec7SKonstantin Ananyev	/* no free drbs left. */
248a633eec7SKonstantin Ananyev	if (i == 0)
249a633eec7SKonstantin Ananyev		return 0;
250a633eec7SKonstantin Ananyev
251a633eec7SKonstantin Ananyev	/* fill objects to enqueue. */
252a633eec7SKonstantin Ananyev	test_fill_obj(obj, i);
253a633eec7SKonstantin Ananyev
254a633eec7SKonstantin Ananyev	/* enqueue into the dring. */
255a633eec7SKonstantin Ananyev	nb = j;
256a633eec7SKonstantin Ananyev	if (type == SINGLE)
257a633eec7SKonstantin Ananyev		k = tle_dring_sp_enqueue(dr, (const void **)obj, i, drb, &nb);
258a633eec7SKonstantin Ananyev	else if (type == MULTI)
259a633eec7SKonstantin Ananyev		k = tle_dring_mp_enqueue(dr, (const void **)obj, i, drb, &nb);
260a633eec7SKonstantin Ananyev	else
261a633eec7SKonstantin Ananyev		return -EINVAL;
262a633eec7SKonstantin Ananyev
263a633eec7SKonstantin Ananyev	if (k != i) {
264a633eec7SKonstantin Ananyev		printf("%s:%d(%p, %p, %u): failed to enqueue %u objects;\n",
265a633eec7SKonstantin Ananyev			__func__, __LINE__, dr, r, num, i);
266a633eec7SKonstantin Ananyev	}
267a633eec7SKonstantin Ananyev
268a633eec7SKonstantin Ananyev	/* free unused drbs */
269a633eec7SKonstantin Ananyev	for (i = j - nb; i != j; i++) {
270a633eec7SKonstantin Ananyev		if ((uintptr_t)drb[i]->udata != lc + 1) {
271a633eec7SKonstantin Ananyev			printf("error @ %s:%d(%p, %u) at lcore %u: "
272a633eec7SKonstantin Ananyev				"erroneous drb@%p={udata=%p, size=%u,};\n",
273a633eec7SKonstantin Ananyev				__func__, __LINE__, dr, num, lc, drb[i],
274a633eec7SKonstantin Ananyev				drb[i]->udata, drb[i]->size);
275a633eec7SKonstantin Ananyev			return -EFAULT;
276a633eec7SKonstantin Ananyev		}
277a633eec7SKonstantin Ananyev		drb[i]->udata = NULL;
278a633eec7SKonstantin Ananyev		rte_ring_enqueue(r, drb[i]);
279a633eec7SKonstantin Ananyev	}
280a633eec7SKonstantin Ananyev
281a633eec7SKonstantin Ananyev	return k;
282a633eec7SKonstantin Ananyev}
283a633eec7SKonstantin Ananyev
284a633eec7SKonstantin Ananyevstatic int
285a633eec7SKonstantin Ananyevtest_dring_enq_deq(struct dring_arg *arg)
286a633eec7SKonstantin Ananyev{
287a633eec7SKonstantin Ananyev	int32_t rc;
288a633eec7SKonstantin Ananyev	uint32_t i, lc, n;
289a633eec7SKonstantin Ananyev
290a633eec7SKonstantin Ananyev	rc = 0;
291a633eec7SKonstantin Ananyev	arg->enq = 0;
292a633eec7SKonstantin Ananyev	arg->deq = 0;
293a633eec7SKonstantin Ananyev	lc = rte_lcore_id();
294a633eec7SKonstantin Ananyev
295a633eec7SKonstantin Ananyev	for (i = 0; i != arg->iter; i++) {
296a633eec7SKonstantin Ananyev
297a633eec7SKonstantin Ananyev		/* try to enqueue random number of objects. */
298a633eec7SKonstantin Ananyev		if (arg->enq_type != NONE) {
299a633eec7SKonstantin Ananyev			n = rte_rand() % (UINT8_MAX + 1);
300a633eec7SKonstantin Ananyev			rc = test_dring_enqueue(arg->dr, arg->r, n,
301a633eec7SKonstantin Ananyev				arg->enq_type);
302a633eec7SKonstantin Ananyev			if (rc < 0)
303a633eec7SKonstantin Ananyev				break;
304a633eec7SKonstantin Ananyev			arg->enq += rc;
305a633eec7SKonstantin Ananyev		}
306a633eec7SKonstantin Ananyev
307a633eec7SKonstantin Ananyev		/* try to dequeue random number of objects. */
308a633eec7SKonstantin Ananyev		if (arg->deq_type != NONE) {
309a633eec7SKonstantin Ananyev			n = rte_rand() % (UINT8_MAX + 1);
310a633eec7SKonstantin Ananyev			rc = test_dring_dequeue(arg->dr, arg->r, n,
311a633eec7SKonstantin Ananyev				arg->deq_type);
312a633eec7SKonstantin Ananyev			if (rc < 0)
313a633eec7SKonstantin Ananyev				break;
314a633eec7SKonstantin Ananyev			arg->deq += rc;
315a633eec7SKonstantin Ananyev		}
316a633eec7SKonstantin Ananyev	}
317a633eec7SKonstantin Ananyev
318a633eec7SKonstantin Ananyev	if (rc < 0)
319a633eec7SKonstantin Ananyev		return rc;
320a633eec7SKonstantin Ananyev
321a633eec7SKonstantin Ananyev	/* dequeue remaining objects. */
322a633eec7SKonstantin Ananyev	while (arg->deq_type != NONE && arg->enq != arg->deq) {
323a633eec7SKonstantin Ananyev
324a633eec7SKonstantin Ananyev		/* try to dequeue random number of objects. */
325a633eec7SKonstantin Ananyev		n = rte_rand() % (UINT8_MAX + 1) + 1;
326a633eec7SKonstantin Ananyev		rc = test_dring_dequeue(arg->dr, arg->r, n, arg->deq_type);
327a633eec7SKonstantin Ananyev		if (rc <= 0)
328a633eec7SKonstantin Ananyev			break;
329a633eec7SKonstantin Ananyev		arg->deq += rc;
330a633eec7SKonstantin Ananyev	}
331a633eec7SKonstantin Ananyev
332a633eec7SKonstantin Ananyev	printf("%s:%d(lcore=%u, enq_type=%d, deq_type=%d): "
333a633eec7SKonstantin Ananyev		"%u objects enqueued, %u objects dequeued\n",
334a633eec7SKonstantin Ananyev		__func__, __LINE__, lc, arg->enq_type, arg->deq_type,
335a633eec7SKonstantin Ananyev		arg->enq, arg->deq);
336a633eec7SKonstantin Ananyev	return 0;
337a633eec7SKonstantin Ananyev}
338a633eec7SKonstantin Ananyev
339a633eec7SKonstantin Ananyev/*
340a633eec7SKonstantin Ananyev * enqueue/dequeue by single thread.
341a633eec7SKonstantin Ananyev */
342a633eec7SKonstantin Ananyevstatic int
343a633eec7SKonstantin Ananyevtest_dring_st(void)
344a633eec7SKonstantin Ananyev{
345a633eec7SKonstantin Ananyev	int32_t rc;
346a633eec7SKonstantin Ananyev	struct rte_ring *r;
347a633eec7SKonstantin Ananyev	struct tle_dring dr;
348a633eec7SKonstantin Ananyev	struct dring_arg arg;
349a633eec7SKonstantin Ananyev
350a633eec7SKonstantin Ananyev	printf("%s started;\n", __func__);
351a633eec7SKonstantin Ananyev
3527e18fa1bSKonstantin Ananyev	tle_dring_reset(&dr, 0);
353a633eec7SKonstantin Ananyev	r = init_drb_ring(OBJ_NUM);
354a633eec7SKonstantin Ananyev	if (r == NULL)
355a633eec7SKonstantin Ananyev		return -ENOMEM;
356a633eec7SKonstantin Ananyev
357a633eec7SKonstantin Ananyev	tle_dring_dump(stdout, 1, &dr);
358a633eec7SKonstantin Ananyev
359a633eec7SKonstantin Ananyev	memset(&arg, 0, sizeof(arg));
360a633eec7SKonstantin Ananyev	arg.dr = &dr;
361a633eec7SKonstantin Ananyev	arg.r = r;
362a633eec7SKonstantin Ananyev	arg.iter = ITER_NUM;
363a633eec7SKonstantin Ananyev	arg.enq_type = SINGLE;
364a633eec7SKonstantin Ananyev	arg.deq_type = SINGLE;
365a633eec7SKonstantin Ananyev	rc = test_dring_enq_deq(&arg);
366a633eec7SKonstantin Ananyev
367a633eec7SKonstantin Ananyev	rc = (rc != 0) ? rc : (arg.enq != arg.deq);
368a633eec7SKonstantin Ananyev	printf("%s finished with status: %s(%d);\n",
369a633eec7SKonstantin Ananyev		__func__, strerror(-rc), rc);
370a633eec7SKonstantin Ananyev
371a633eec7SKonstantin Ananyev	tle_dring_dump(stdout, rc != 0, &dr);
372a633eec7SKonstantin Ananyev	fini_drb_ring(r);
373a633eec7SKonstantin Ananyev
374a633eec7SKonstantin Ananyev	return rc;
375a633eec7SKonstantin Ananyev}
376a633eec7SKonstantin Ananyev
377a633eec7SKonstantin Ananyevstatic int
378a633eec7SKonstantin Ananyevtest_dring_worker(void *arg)
379a633eec7SKonstantin Ananyev{
380a633eec7SKonstantin Ananyev	struct dring_arg *p;
381a633eec7SKonstantin Ananyev
382a633eec7SKonstantin Ananyev	p = (struct dring_arg *)arg;
383a633eec7SKonstantin Ananyev	return test_dring_enq_deq(p);
384a633eec7SKonstantin Ananyev}
385a633eec7SKonstantin Ananyev
386a633eec7SKonstantin Ananyev/*
387a633eec7SKonstantin Ananyev * enqueue/dequeue by multiple threads.
388a633eec7SKonstantin Ananyev */
389a633eec7SKonstantin Ananyevstatic int
390a633eec7SKonstantin Ananyevtest_dring_mt(int32_t master_enq_type, int32_t master_deq_type,
391a633eec7SKonstantin Ananyev	int32_t slave_enq_type, int32_t slave_deq_type)
392a633eec7SKonstantin Ananyev{
393a633eec7SKonstantin Ananyev	int32_t rc;
394a633eec7SKonstantin Ananyev	uint32_t lc;
395a633eec7SKonstantin Ananyev	uint64_t deq, enq;
396a633eec7SKonstantin Ananyev	struct rte_ring *r;
397a633eec7SKonstantin Ananyev	struct tle_dring dr;
398a633eec7SKonstantin Ananyev	struct dring_arg arg[RTE_MAX_LCORE];
399a633eec7SKonstantin Ananyev
4007e18fa1bSKonstantin Ananyev	tle_dring_reset(&dr, 0);
401a633eec7SKonstantin Ananyev	r = init_drb_ring(OBJ_NUM);
402a633eec7SKonstantin Ananyev	if (r == NULL)
403a633eec7SKonstantin Ananyev		return -ENOMEM;
404a633eec7SKonstantin Ananyev