dpdk/drivers/event/sw/event_ring.h
<<
>>
Prefs
   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