summaryrefslogtreecommitdiff
path: root/firmware/include
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/include')
-rw-r--r--firmware/include/buflib.h26
-rw-r--r--firmware/include/buflib_malloc.h12
-rw-r--r--firmware/include/buflib_mempool.h35
3 files changed, 72 insertions, 1 deletions
diff --git a/firmware/include/buflib.h b/firmware/include/buflib.h
index c4865b6d9b..3fe8ac1430 100644
--- a/firmware/include/buflib.h
+++ b/firmware/include/buflib.h
@@ -317,6 +317,32 @@ static inline void *buflib_get_data(struct buflib_context *ctx, int handle);
317#endif 317#endif
318 318
319/** 319/**
320 * \brief Get a pinned pointer to a buflib allocation
321 * \param ctx Buflib context of the allocation
322 * \param handle Handle identifying the allocation
323 * \return Pointer to the allocation's memory.
324 *
325 * Functionally equivalent to buflib_pin() followed by buflib_get_data(),
326 * but this call is more efficient and should be preferred over separate
327 * calls.
328 *
329 * To unpin the data, call buflib_put_data_pinned() and pass the pointer
330 * returned by this function.
331 */
332static inline void *buflib_get_data_pinned(struct buflib_context *ctx, int handle);
333
334/**
335 * \brief Release a pinned pointer to a buflib allocation
336 * \param ctx Buflib context of the allocation
337 * \param data Pointer returned by buflib_get_data()
338 *
339 * Decrements the pin count, allowing the buffer to be moved once the
340 * pin count drops to zero. This is more efficient than buflib_unpin()
341 * and should be preferred when you have a pointer to the buflib data.
342 */
343static inline void buflib_put_data_pinned(struct buflib_context *ctx, void *data);
344
345/**
320 * \brief Shift allocations up to free space at the start of the pool 346 * \brief Shift allocations up to free space at the start of the pool
321 * \param ctx Context to operate on 347 * \param ctx Context to operate on
322 * \param size Indicates number of bytes to free up, or 0 to free 348 * \param size Indicates number of bytes to free up, or 0 to free
diff --git a/firmware/include/buflib_malloc.h b/firmware/include/buflib_malloc.h
index 32c837e7b7..a17c75c29a 100644
--- a/firmware/include/buflib_malloc.h
+++ b/firmware/include/buflib_malloc.h
@@ -50,4 +50,16 @@ static inline void *buflib_get_data(struct buflib_context *ctx, int handle)
50} 50}
51#endif 51#endif
52 52
53static inline void *buflib_get_data_pinned(struct buflib_context *ctx, int handle)
54{
55 buflib_pin(ctx, handle);
56 return buflib_get_data(ctx, handle);
57}
58
59void _buflib_malloc_put_data_pinned(struct buflib_context *ctx, void *data);
60static inline void buflib_put_data_pinned(struct buflib_context *ctx, void *data)
61{
62 _buflib_malloc_put_data_pinned(ctx, data);
63}
64
53#endif /* _BUFLIB_MALLOC_H_ */ 65#endif /* _BUFLIB_MALLOC_H_ */
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 @@
30# error "include buflib.h instead" 30# error "include buflib.h instead"
31#endif 31#endif
32 32
33#include "system.h"
34
35/* Indices used to access block fields as block[BUFLIB_IDX_XXX] */
36enum {
37 BUFLIB_IDX_LEN, /* length of the block, must come first */
38 BUFLIB_IDX_HANDLE, /* pointer to entry in the handle table */
39 BUFLIB_IDX_OPS, /* pointer to an ops struct */
40 BUFLIB_IDX_PIN, /* pin count */
41 BUFLIB_NUM_FIELDS,
42};
43
33union buflib_data 44union buflib_data
34{ 45{
35 intptr_t val; /* length of the block in n*sizeof(union buflib_data). 46 intptr_t val; /* length of the block in n*sizeof(union buflib_data).
@@ -52,7 +63,7 @@ struct buflib_context
52 bool compact; 63 bool compact;
53}; 64};
54 65
55#define BUFLIB_ALLOC_OVERHEAD (4 * sizeof(union buflib_data)) 66#define BUFLIB_ALLOC_OVERHEAD (BUFLIB_NUM_FIELDS * sizeof(union buflib_data))
56 67
57#ifndef BUFLIB_DEBUG_GET_DATA 68#ifndef BUFLIB_DEBUG_GET_DATA
58static inline void *buflib_get_data(struct buflib_context *ctx, int handle) 69static 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)
61} 72}
62#endif 73#endif
63 74
75static inline union buflib_data *_buflib_get_block_header(void *data)
76{
77 union buflib_data *bd = ALIGN_DOWN(data, sizeof(*bd));
78 return bd - BUFLIB_NUM_FIELDS;
79}
80
81static inline void *buflib_get_data_pinned(struct buflib_context *ctx, int handle)
82{
83 void *data = buflib_get_data(ctx, handle);
84 union buflib_data *bd = _buflib_get_block_header(data);
85
86 bd[BUFLIB_IDX_PIN].pincount++;
87 return data;
88}
89
90static inline void buflib_put_data_pinned(struct buflib_context *ctx, void *data)
91{
92 (void)ctx;
93 union buflib_data *bd = _buflib_get_block_header(data);
94 bd[BUFLIB_IDX_PIN].pincount--;
95}
96
64#endif /* _BUFLIB_MEMPOOL_H_ */ 97#endif /* _BUFLIB_MEMPOOL_H_ */