Line data Source code
1 0 : /* 2 : * Copyright (c) 2021 Intel Corporation 3 : * SPDX-License-Identifier: Apache-2.0 4 : */ 5 : #ifndef ZEPHYR_INCLUDE_SYS_WINSTREAM_H_ 6 : #define ZEPHYR_INCLUDE_SYS_WINSTREAM_H_ 7 : 8 : #include <stdint.h> 9 : 10 : /** @brief Lockless shared memory byte stream IPC 11 : * 12 : * The sys_winstream utility implements a unidirectional byte stream 13 : * with simple read/write semantics on top of a memory region shared 14 : * by the writer and reader. It requires no locking or 15 : * synchronization mechanisms beyond reliable ordering of memory 16 : * operations, and so is a good fit for use with heterogeneous shared 17 : * memory environments (for example, where Zephyr needs to talk to 18 : * other CPUs in the system running their own software). 19 : * 20 : * This object does not keep track of the last sequence number read: the 21 : * reader must keep that state and provide it on every read 22 : * operation. After reaching "steady state", 'end' and 'start' are one 23 : * byte apart because the buffer is always full. 24 : */ 25 1 : struct sys_winstream { 26 0 : uint32_t len; /* Length of data[] in bytes */ 27 0 : uint32_t start; /* Index of first valid byte in data[] */ 28 0 : uint32_t end; /* Index of next byte in data[] to write */ 29 0 : uint32_t seq; /* Mod-2^32 index of 'end' since stream init */ 30 0 : uint8_t data[]; 31 : }; 32 : 33 : /** @brief Construct a sys_winstream from a region of memory 34 : * 35 : * This function initializes a sys_winstream in an arbitrarily-sized 36 : * region of memory, returning the resulting object (which is 37 : * guaranteed to be at the same address as the buffer). The memory 38 : * must (obviously) be shared between the reader and writer, and all 39 : * operations to it must be coherent and consistently ordered. 40 : * 41 : * @param buf Pointer to a region of memory to contain the stream 42 : * @param buflen Length of the buffer, must be large enough to contain 43 : * the struct sys_winstream and at least one byte of 44 : * data. 45 : * @return A pointer to an initialized sys_winstream (same address as 46 : * the buf parameter). 47 : */ 48 1 : static inline struct sys_winstream *sys_winstream_init(void *buf, int buflen) 49 : { 50 : struct sys_winstream *ws = buf, tmp = { .len = buflen - sizeof(*ws) }; 51 : 52 : *ws = tmp; 53 : return ws; 54 : } 55 : 56 : /** @brief Write bytes to a sys_winstream 57 : * 58 : * This function writes the specified number of bytes into the stream. 59 : * It will always return synchronously, it does not block or engage in 60 : * any kind of synchronization beyond memory write ordering. Any 61 : * bytes passed beyond what can be stored in the buffer will be 62 : * silently dropped, but readers can detect their presence via the 63 : * sequence number. 64 : * 65 : * @param ws A sys_winstream to which to write 66 : * @param data Pointer to bytes to be written 67 : * @param len Number of bytes to write 68 : */ 69 1 : void sys_winstream_write(struct sys_winstream *ws, 70 : const char *data, uint32_t len); 71 : 72 : /** @brief Read bytes from a sys_winstream 73 : * 74 : * This function will read bytes from a sys_winstream into a specified 75 : * buffer. It will always return in constant time, it does not block 76 : * or engage in any kind of synchronization beyond memory ordering. 77 : * The number of bytes read into the buffer will be returned, but note 78 : * that it is possible that an underflow can occur if the writer gets 79 : * ahead of our context. That situation can be detected via the 80 : * sequence number returned via a pointer (i.e. if "*seq != old_seq + 81 : * return_value", an underflow occurred and bytes were dropped). 82 : * 83 : * @param ws A sys_winstream from which to read 84 : * @param seq A pointer to an integer containing the last sequence 85 : * number read from the stream, or zero to indicate "start 86 : * of stream". It is updated in place and returned for 87 : * future calls and for detecting underflows. 88 : * @param buf A buffer into which to store the data read 89 : * @param buflen The length of buf in bytes 90 : * @return The number of bytes written into the buffer 91 : */ 92 1 : uint32_t sys_winstream_read(struct sys_winstream *ws, 93 : uint32_t *seq, char *buf, uint32_t buflen); 94 : 95 : #endif /* ZEPHYR_INCLUDE_SYS_WINSTREAM_H_ */