|
1 | 1 | #pragma once
|
2 | 2 |
|
| 3 | +/* Inter-task Communication Pipes |
| 4 | + * |
| 5 | + * Pipes provide a unidirectional FIFO communication channel between tasks. |
| 6 | + * They support both blocking and non-blocking I/O operations with automatic |
| 7 | + * buffer management using power-of-2 sizing for efficient masking operations. |
| 8 | + */ |
| 9 | + |
| 10 | +#include <types.h> |
| 11 | + |
| 12 | +/* Magic number for pipe validation and corruption detection */ |
| 13 | +#define PIPE_MAGIC 0x50495045 /* "PIPE" */ |
| 14 | + |
3 | 15 | /* Pipe descriptor
|
4 | 16 | *
|
5 |
| - * The buffer size is forced to the next power-of-two so we can mask |
6 |
| - * the head/tail indices instead of performing expensive modulus. |
| 17 | + * The circular buffer uses head/tail indices with power-of-2 masking |
| 18 | + * for efficient wraparound. The 'used' counter provides O(1) empty/full |
| 19 | + * detection and accurate size reporting without head/tail comparison issues. |
7 | 20 | */
|
8 | 21 | typedef struct {
|
9 |
| - char *buf; /* data buffer */ |
10 |
| - uint16_t mask; /* capacity-1 (size is power of 2) */ |
11 |
| - volatile uint16_t head; /* read index */ |
12 |
| - volatile uint16_t tail; /* write index */ |
13 |
| - volatile uint16_t used; /* bytes currently stored */ |
| 22 | + char *buf; /* Data buffer (power-of-2 size) */ |
| 23 | + uint16_t mask; /* Capacity - 1 */ |
| 24 | + volatile uint16_t head; /* Read index (consumer position) */ |
| 25 | + volatile uint16_t tail; /* Write index (producer position) */ |
| 26 | + volatile uint16_t used; /* Bytes currently stored (0 to capacity) */ |
| 27 | + uint32_t magic; /* Magic number for validation */ |
14 | 28 | } pipe_t;
|
15 | 29 |
|
16 | 30 | /* Constructor / destructor */
|
| 31 | + |
| 32 | +/* Create a new pipe with specified buffer size. |
| 33 | + * @size: Desired buffer size (will be rounded up to next power-of-2) |
| 34 | + * |
| 35 | + * Returns Pointer to new pipe on success, NULL on failure |
| 36 | + * Note: Minimum size is 2 bytes, maximum is 32768 bytes |
| 37 | + */ |
17 | 38 | pipe_t *mo_pipe_create(uint16_t size);
|
| 39 | + |
| 40 | +/* Destroy a pipe and free its resources. |
| 41 | + * @pipe: Pointer to pipe structure (NULL is safe no-op) |
| 42 | + * |
| 43 | + * Returns ERR_OK on success, ERR_FAIL if pipe is invalid |
| 44 | + */ |
18 | 45 | int32_t mo_pipe_destroy(pipe_t *pipe);
|
19 | 46 |
|
| 47 | +/* Pipe operations */ |
| 48 | + |
| 49 | +/* Flush all data from the pipe (reset to empty state). |
| 50 | + * @pipe: Pointer to pipe structure (must be valid) |
| 51 | + */ |
20 | 52 | void mo_pipe_flush(pipe_t *pipe);
|
21 |
| -/* bytes currently in pipe */ |
| 53 | + |
| 54 | +/* Get the number of bytes currently stored in the pipe. |
| 55 | + * @pipe: Pointer to pipe structure |
| 56 | + * |
| 57 | + * Returns Number of bytes available for reading, or -1 if pipe is invalid |
| 58 | + */ |
22 | 59 | int32_t mo_pipe_size(pipe_t *pipe);
|
23 | 60 |
|
24 |
| -/* Blocking I/O (runs in task context) */ |
| 61 | +/* Get the total capacity of the pipe. |
| 62 | + * @pipe: Pointer to pipe structure |
| 63 | + * |
| 64 | + * Returns Total buffer size in bytes, or -1 if pipe is invalid |
| 65 | + */ |
| 66 | +int32_t mo_pipe_capacity(pipe_t *pipe); |
| 67 | + |
| 68 | +/* Get the number of free bytes in the pipe. |
| 69 | + * @pipe: Pointer to pipe structure |
| 70 | + * |
| 71 | + * Returns Number of bytes available for writing, or -1 if pipe is invalid |
| 72 | + */ |
| 73 | +int32_t mo_pipe_free_space(pipe_t *pipe); |
| 74 | + |
| 75 | +/* Blocking I/O (runs in task context only) */ |
| 76 | + |
| 77 | +/* Read data from pipe, blocking until all requested bytes are available. |
| 78 | + * @pipe: Pointer to pipe structure (must be valid) |
| 79 | + * @data: Buffer to store read data (must be non-NULL) |
| 80 | + * @size: Number of bytes to read (must be > 0) |
| 81 | + * |
| 82 | + * Returns Number of bytes read (equals size on success), negative on error |
| 83 | + */ |
25 | 84 | int32_t mo_pipe_read(pipe_t *pipe, char *data, uint16_t size);
|
| 85 | + |
| 86 | +/* Write data to pipe, blocking until all data is written. |
| 87 | + * @pipe: Pointer to pipe structure (must be valid) |
| 88 | + * @data: Data to write (must be non-NULL) |
| 89 | + * @size: Number of bytes to write (must be > 0) |
| 90 | + * |
| 91 | + * Returns Number of bytes written (equals size on success), negative on error |
| 92 | + * Note: This function will block until all data can be written |
| 93 | + */ |
26 | 94 | int32_t mo_pipe_write(pipe_t *pipe, const char *data, uint16_t size);
|
27 | 95 |
|
28 |
| -/* Non-blocking I/O (returns partial count on short read/write) */ |
| 96 | +/* Non-blocking I/O (returns immediately with partial results) */ |
| 97 | + |
| 98 | +/* Read available data from pipe without blocking. |
| 99 | + * @pipe: Pointer to pipe structure (must be valid) |
| 100 | + * @data: Buffer to store read data (must be non-NULL) |
| 101 | + * @size: Maximum number of bytes to read |
| 102 | + * |
| 103 | + * Returnsd: Number of bytes actually read (0 to size), negative on error |
| 104 | + * Note: Returns immediately even if no data is available |
| 105 | + */ |
29 | 106 | int32_t mo_pipe_nbread(pipe_t *pipe, char *data, uint16_t size);
|
| 107 | + |
| 108 | +/* Write data to pipe without blocking. |
| 109 | + * @pipe: Pointer to pipe structure (must be valid) |
| 110 | + * @data: Data to write (must be non-NULL) |
| 111 | + * @size: Number of bytes to write |
| 112 | + * |
| 113 | + * Returns Number of bytes actually written (0 to size), negative on error |
| 114 | + * Note: Returns immediately even if no space is available |
| 115 | + */ |
30 | 116 | int32_t mo_pipe_nbwrite(pipe_t *pipe, const char *data, uint16_t size);
|
0 commit comments