shell bypass 403
/** @file @brief 'ring' or 'circular' buffer @details Copyright (c) 2021 Acronis International GmbH @author Mikhail Krivtsov ([email protected]) @since $Id: $ */ #pragma once #include <linux/atomic.h> #include <linux/types.h> // bool, [u]int(8|16|32|64)_t, pid_t, size_t #ifdef KERNEL_MOCK #include <mock/mock.h> #endif typedef struct { void *buffer; size_t item_size; int capacity; // 'count' is marked as atomic because it might be called from 'wait_event*' call without taking a spinlock atomic_t count; int count_max; int producer_index; int consumer_index; } ring_t; static inline void ring_init(ring_t *ring, void *buffer, size_t buffer_size, size_t item_size) { ring->buffer = buffer; ring->item_size = item_size; ring->capacity = buffer_size / item_size; atomic_set(&ring->count, 0); ring->count_max = 0; ring->producer_index = 0; ring->consumer_index = 0; } static inline void *ring_buffer(ring_t *ring) { return ring->buffer; } static inline int ring_capacity(ring_t *ring) { return ring->capacity; } static inline void ring_producer_index_move(ring_t *ring, int items) { int count; ring->producer_index = (ring->producer_index + items) % ring->capacity; count = atomic_add_return(items, &ring->count); if (ring->count_max < count) { ring->count_max = count; } } static inline void ring_producer_index_move_one(ring_t *ring) { ring_producer_index_move(ring, 1); } static inline void *ring_producer_ptr(ring_t *ring) { return (void *) (ring->producer_index * ring->item_size + (char *)ring->buffer); } static inline void ring_consumer_index_move(ring_t *ring, int items) { ring->consumer_index = (ring->consumer_index + items) % ring->capacity; atomic_sub(items, &ring->count); } static inline void ring_consumer_index_move_one(ring_t *ring) { ring_consumer_index_move(ring, 1); } static inline void *ring_consumer_ptr(ring_t *ring) { return (void *) (ring->consumer_index * ring->item_size + (char *)ring->buffer); } static inline int ring_items_count(ring_t *ring) { return atomic_read(&ring->count); } static inline int ring_items_count_max(ring_t *ring) { return ring->count_max; } static inline bool ring_is_empty(ring_t *ring) { return !ring_items_count(ring); } static inline bool ring_is_full(ring_t *ring) { return ring_items_count(ring) >= ring->capacity; }