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 */ 24struct 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 33static inline struct rob_ring * 34rob_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; 47end: 48 return retval; 49} 50 51static inline void 52rob_ring_free(struct rob_ring *r) 53{ 54 rte_free(r); 55} 56 57static __rte_always_inline unsigned int 58rob_ring_count(const struct rob_ring *r) 59{ 60 return r->write_idx - r->read_idx; 61} 62 63static __rte_always_inline unsigned int 64rob_ring_free_count(const struct rob_ring *r) 65{ 66 return r->size - rob_ring_count(r); 67} 68 69static __rte_always_inline unsigned int 70rob_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 84static __rte_always_inline unsigned int 85rob_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 99

