summaryrefslogtreecommitdiffstats
path: root/firmware/include/buflib_mempool.h
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2023-01-14 18:20:59 +0000
committerAidan MacDonald <amachronic@protonmail.com>2023-01-15 11:06:27 +0000
commit800bc000a08b37e22d2b36d32fd448624712a881 (patch)
tree87149cae9acb83db4a98a873b81515a99200d790 /firmware/include/buflib_mempool.h
parent92565e9246f3a47b90fea4a436ecfd8e7a1198b8 (diff)
downloadrockbox-800bc000a0.tar.gz
rockbox-800bc000a0.zip
buflib: Add pinned get/put data functions
These are more efficient than separate pin/unpin calls because pin count increment and decrement can be done cheaply when the data pointer is known. Secondly, pinned access can be made safe against preemption by hardware interrupts or other CPU cores; buflib_get_data() can't. This makes it more useful under different threading models and for SMP targets; both of which are not particularly relevant to Rockbox now, but might be in the future. Change-Id: I09284251b83bbbc59ef88a494c8fda26a7f7ef26
Diffstat (limited to 'firmware/include/buflib_mempool.h')
-rw-r--r--firmware/include/buflib_mempool.h35
1 files changed, 34 insertions, 1 deletions
diff --git a/firmware/include/buflib_mempool.h b/firmware/include/buflib_mempool.h
index 4b01b629c3..448e40963a 100644
--- a/firmware/include/buflib_mempool.h
+++ b/firmware/include/buflib_mempool.h
@@ -30,6 +30,17 @@
# error "include buflib.h instead"
#endif
+#include "system.h"
+
+/* Indices used to access block fields as block[BUFLIB_IDX_XXX] */
+enum {
+ BUFLIB_IDX_LEN, /* length of the block, must come first */
+ BUFLIB_IDX_HANDLE, /* pointer to entry in the handle table */
+ BUFLIB_IDX_OPS, /* pointer to an ops struct */
+ BUFLIB_IDX_PIN, /* pin count */
+ BUFLIB_NUM_FIELDS,
+};
+
union buflib_data
{
intptr_t val; /* length of the block in n*sizeof(union buflib_data).
@@ -52,7 +63,7 @@ struct buflib_context
bool compact;
};
-#define BUFLIB_ALLOC_OVERHEAD (4 * sizeof(union buflib_data))
+#define BUFLIB_ALLOC_OVERHEAD (BUFLIB_NUM_FIELDS * sizeof(union buflib_data))
#ifndef BUFLIB_DEBUG_GET_DATA
static inline void *buflib_get_data(struct buflib_context *ctx, int handle)
@@ -61,4 +72,26 @@ static inline void *buflib_get_data(struct buflib_context *ctx, int handle)
}
#endif
+static inline union buflib_data *_buflib_get_block_header(void *data)
+{
+ union buflib_data *bd = ALIGN_DOWN(data, sizeof(*bd));
+ return bd - BUFLIB_NUM_FIELDS;
+}
+
+static inline void *buflib_get_data_pinned(struct buflib_context *ctx, int handle)
+{
+ void *data = buflib_get_data(ctx, handle);
+ union buflib_data *bd = _buflib_get_block_header(data);
+
+ bd[BUFLIB_IDX_PIN].pincount++;
+ return data;
+}
+
+static inline void buflib_put_data_pinned(struct buflib_context *ctx, void *data)
+{
+ (void)ctx;
+ union buflib_data *bd = _buflib_get_block_header(data);
+ bd[BUFLIB_IDX_PIN].pincount--;
+}
+
#endif /* _BUFLIB_MEMPOOL_H_ */