eventdev: express DLB/DLB2 PMD constraints
[dpdk.git] / drivers / event / sw / event_ring.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016-2017 Intel Corporation
3  */
4
5 /*
6  * Generic ring structure for passing events from one core to another.
7  *
8  * Used by the software scheduler for the producer and consumer rings for
9  * each port, i.e. for passing events from worker cores to scheduler and
10  * vice-versa. Designed for single-producer, single-consumer use with two
11  * cores working on each ring.
12  */
13
14 #ifndef _EVENT_RING_
15 #define _EVENT_RING_
16
17 #include <stdint.h>
18
19 #include <rte_common.h>
20 #include <rte_memory.h>
21 #include <rte_malloc.h>
22
23 /* Custom single threaded ring implementation used for ROB */
24 struct rob_ring {
25         uint32_t ring_size;
26         uint32_t mask;
27         uint32_t size;
28         uint32_t write_idx;
29         uint32_t read_idx;
30         void *ring[0] __rte_cache_aligned;
31 };
32
33 static inline struct rob_ring *
34 rob_ring_create(unsigned int size, unsigned int socket_id)
35 {
36         struct rob_ring *retval;
37         const uint32_t ring_size = rte_align32pow2(size + 1);
38         size_t memsize = sizeof(*retval) +
39                         (ring_size * sizeof(retval->ring[0]));
40
41         retval = rte_zmalloc_socket(NULL, memsize, 0, socket_id);
42         if (retval == NULL)
43                 goto end;
44         retval->ring_size = ring_size;
45         retval->mask = ring_size - 1;
46         retval->size = size;
47 end:
48         return retval;
49 }
50
51 static inline void
52 rob_ring_free(struct rob_ring *r)
53 {
54         rte_free(r);
55 }
56
57 static __rte_always_inline unsigned int
58 rob_ring_count(const struct rob_ring *r)
59 {
60         return r->write_idx - r->read_idx;
61 }
62
63 static __rte_always_inline unsigned int
64 rob_ring_free_count(const struct rob_ring *r)
65 {
66         return r->size - rob_ring_count(r);
67 }
68
69 static __rte_always_inline unsigned int
70 rob_ring_enqueue(struct rob_ring *r, void *re)
71 {
72         const uint32_t size = r->size;
73         const uint32_t mask = r->mask;
74         const uint32_t read = r->read_idx;
75         uint32_t write = r->write_idx;
76         const uint32_t space = read + size - write;
77         if (space < 1)
78                 return 0;
79         r->ring[write & mask] = re;
80         r->write_idx++;
81         return 1;
82 }
83
84 static __rte_always_inline unsigned int
85 rob_ring_dequeue(struct rob_ring *r, void **re)
86 {
87         const uint32_t mask = r->mask;
88         uint32_t read = r->read_idx;
89         const uint32_t write = r->write_idx;
90         const uint32_t items = write - read;
91         if (items < 1)
92                 return 0;
93         *re = r->ring[read & mask];
94         r->read_idx++;
95         return 1;
96 }
97
98 #endif