diff options
Diffstat (limited to 'firmware/include')
-rw-r--r-- | firmware/include/buflib.h | 26 | ||||
-rw-r--r-- | firmware/include/buflib_malloc.h | 12 | ||||
-rw-r--r-- | firmware/include/buflib_mempool.h | 35 |
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 | */ | ||
332 | static 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 | */ | ||
343 | static 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 | ||
53 | static 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 | |||
59 | void _buflib_malloc_put_data_pinned(struct buflib_context *ctx, void *data); | ||
60 | static 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] */ | ||
36 | enum { | ||
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 | |||
33 | union buflib_data | 44 | union 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 |
58 | static inline void *buflib_get_data(struct buflib_context *ctx, int handle) | 69 | 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) | |||
61 | } | 72 | } |
62 | #endif | 73 | #endif |
63 | 74 | ||
75 | static 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 | |||
81 | static 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 | |||
90 | static 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_ */ |