Skip to content

Commit 7bc2645

Browse files
author
Leonardo
committed
Merge branch 'develop'
2 parents 394af46 + 738f0eb commit 7bc2645

File tree

7 files changed

+138
-114
lines changed

7 files changed

+138
-114
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.26)
2-
project(naughty-buffers LANGUAGES C VERSION 1.0.0)
2+
project(naughty-buffers LANGUAGES C VERSION 1.1.0)
33
include(CTest)
44

55
set(CMAKE_C_STANDARD 99)

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ int main(void) {
5959
```c
6060
#include "naughty-buffers/buffer.h"
6161
62-
void * my_alloc(size_t memory_size, void * context);
63-
void my_release(void * ptr, void * context);
64-
void * my_realloc(void * ptr, size_t memory_size, void * context);
65-
void * my_copy(void * destination, const void * source, size_t size, void * context);
66-
void * my_move(void * destination, const void * source, size_t size, void * context);
62+
void * my_alloc(size_t memory_size, void * memory_context);
63+
void my_release(void * ptr, void * memory_context);
64+
void * my_realloc(void * ptr, size_t memory_size, void * memory_context);
65+
void * my_copy(void * destination, const void * source, size_t size, void * memory_context);
66+
void * my_move(void * destination, const void * source, size_t size, void * memory_context);
6767
void * memory_context;
6868
6969

include/naughty-buffers/array-generator.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,7 @@
8484
struct nb_buffer buffer; \
8585
}; \
8686
void __NB_ARRAY_TYPE__##_init(struct __NB_ARRAY_TYPE__ * array); \
87-
void __NB_ARRAY_TYPE__##_init_advanced( \
88-
struct __NB_ARRAY_TYPE__ * array, nb_alloc_fn alloc_fn, nb_realloc_fn realloc_fn, nb_free_fn free_fn, \
89-
nb_copy_fn copy_fn, nb_move_fn move_fn, void * memory_context \
90-
); \
87+
void __NB_ARRAY_TYPE__##_init_advanced(struct __NB_ARRAY_TYPE__ * array, struct nb_buffer_memory_context * ctx); \
9188
enum NB_PUSH_RESULT __NB_ARRAY_TYPE__##_push(struct __NB_ARRAY_TYPE__ * array, const __NB_ARRAY_BLOCK_TYPE__ item); \
9289
enum NB_PUSH_RESULT __NB_ARRAY_TYPE__##_push_ptr( \
9390
struct __NB_ARRAY_TYPE__ * array, const __NB_ARRAY_BLOCK_TYPE__ * item \
@@ -125,14 +122,8 @@
125122
void __NB_ARRAY_TYPE__##_init(struct __NB_ARRAY_TYPE__ * array) { \
126123
nb_init(&array->buffer, sizeof(__NB_ARRAY_BLOCK_TYPE__)); \
127124
} \
128-
void __NB_ARRAY_TYPE__##_init_advanced( \
129-
struct __NB_ARRAY_TYPE__ * array, nb_alloc_fn alloc_fn, nb_realloc_fn realloc_fn, nb_free_fn free_fn, \
130-
nb_copy_fn copy_fn, nb_move_fn move_fn, void * memory_context \
131-
) { \
132-
nb_init_advanced( \
133-
&array->buffer, sizeof(__NB_ARRAY_BLOCK_TYPE__), alloc_fn, realloc_fn, free_fn, copy_fn, move_fn, \
134-
memory_context \
135-
); \
125+
void __NB_ARRAY_TYPE__##_init_advanced(struct __NB_ARRAY_TYPE__ * array, struct nb_buffer_memory_context * ctx) { \
126+
nb_init_advanced(&array->buffer, sizeof(__NB_ARRAY_BLOCK_TYPE__), ctx); \
136127
} \
137128
enum NB_PUSH_RESULT __NB_ARRAY_TYPE__##_push(struct __NB_ARRAY_TYPE__ * array, const __NB_ARRAY_BLOCK_TYPE__ item) { \
138129
return nb_push(&array->buffer, (void *)&item); \

include/naughty-buffers/buffer.h

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,48 @@ typedef void (*nb_free_fn)(void * ptr, void * context);
8282
*/
8383
typedef int (*nb_compare_fn)(const void * ptr_a, const void * ptr_b);
8484

85+
/**
86+
* @brief A structure containing memory-related pointers
87+
*
88+
* This is only useful if you have your own allocator or custom memory management.
89+
*
90+
* @sa nb_init_advanced
91+
* @sa nb_alloc_fn
92+
* @sa nb_realloc_fn
93+
* @sa nb_free_fn
94+
* @sa nb_copy_fn
95+
* @sa nb_move_fn
96+
* @ingroup buffer
97+
*/
98+
struct nb_buffer_memory_context {
99+
/** A function to allocate a memory block. It needs to have the same semantics of `malloc` */
100+
nb_alloc_fn alloc_fn;
101+
102+
/** A function to reallocate a memory block. It needs to have the same semantics of `realloc` */
103+
nb_realloc_fn realloc_fn;
104+
105+
/**
106+
* A function to release a memory block allocated by `alloc_fn` or `realloc_fn`. Needs to have the same
107+
* semantics of `free`
108+
*/
109+
nb_free_fn free_fn;
110+
111+
/**
112+
* A function to copy non-overlapping data from a block to another. It needs to have the same semantics
113+
* of `memcpy`
114+
*/
115+
nb_copy_fn copy_fn;
116+
117+
/**
118+
* A function to copy possibly overlapping data from a block to another. It needs to have the same
119+
* semantics of `memmove`
120+
*/
121+
nb_move_fn move_fn;
122+
123+
/** A pointer to a user-data that will be passed in every memory-related call */
124+
void * context;
125+
};
126+
85127
/**
86128
* @brief a structure holding the buffer data and metadata about the blocks.
87129
*
@@ -99,12 +141,7 @@ struct nb_buffer {
99141
size_t block_count;
100142
size_t block_capacity;
101143

102-
nb_alloc_fn alloc_fn;
103-
nb_realloc_fn realloc_fn;
104-
nb_free_fn free_fn;
105-
nb_copy_fn copy_fn;
106-
nb_move_fn move_fn;
107-
void * memory_context;
144+
struct nb_buffer_memory_context * memory_context;
108145

109146
void * data;
110147
};
@@ -151,44 +188,40 @@ enum NB_INSERT_RESULT { NB_INSERT_OUT_OF_MEMORY, NB_INSERT_OK };
151188
NAUGHTY_BUFFERS_EXPORT void nb_init(struct nb_buffer * buffer, size_t block_size);
152189

153190
/**
154-
* @brief Initializes a ::nb_buffer struct with custom memory functions and context.
191+
* @brief Initializes a ::nb_buffer struct with custom memory functions and memory_context.
155192
*
156-
* You need to provide all custom memory functions and optionally a memory context.
193+
* You need to provide all custom memory functions and optionally a memory memory_context.
157194
*
158195
* It will allocate enough memory to contain two blocks with `alloc_fn`
159196
*
160197
* @param buffer A pointer to a ::nb_buffer struct to be initialized
161198
* @param block_size Size, in bytes, for each buffer block
162-
* @param alloc_fn A function to allocate a memory block. It needs to have the same semantics of `malloc`
163-
* @param realloc_fn A function to reallocate a memory block. It needs to have the same semantics of `realloc`
164-
* @param free_fn A function to release a memory block allocated by `alloc_fn` or `realloc_fn`. Needs to have the same
165-
* semantics of `free`
166-
* @param copy_fn A function to copy non-overlapping data from a block to another. It needs to have the same semantics
167-
* of `memcpy`
168-
* @param move_fn A function to copy possibly overlapping data from a block to another. It needs to have the same
169-
* semantics of `memmove`
170-
* @param memory_context A pointer to an optional context that will be passed to each memory function.
199+
* @param memory_context A pointer to a `struct nb_buffer_memory_context` that will be used when memory management is needed.
171200
*
172201
* **Example**
173202
* @code
174-
void * my_alloc(size_t memory_size, void * context);
175-
void my_release(void * ptr, void * context);
176-
void * my_realloc(void * ptr, size_t memory_size, void * context);
177-
void * my_copy(void * destination, const void * source, size_t size, void * context);
178-
void * my_move(void * destination, const void * source, size_t size, void * context);
203+
void * my_alloc(size_t memory_size, void * memory_context);
204+
void my_release(void * ptr, void * memory_context);
205+
void * my_realloc(void * ptr, size_t memory_size, void * memory_context);
206+
void * my_copy(void * destination, const void * source, size_t size, void * memory_context);
207+
void * my_move(void * destination, const void * source, size_t size, void * memory_context);
179208
void * memory_context;
180209
210+
struct nb_buffer_memory_context ctx = {
211+
.alloc = my_alloc,
212+
.free = my_release,
213+
.realloc = my_realloc,
214+
.copy = my_copy,
215+
.move = my_move,
216+
.context = memory_context
217+
};
218+
181219
int main(void) {
182220
struct nb_buffer buffer;
183221
nb_init_advanced(
184222
&buffer,
185223
sizeof(int),
186-
my_alloc,
187-
my_realloc,
188-
my_release,
189-
my_copy,
190-
my_move,
191-
memory_context
224+
&ctx
192225
);
193226
194227
nb_release(&buffer);
@@ -202,12 +235,7 @@ NAUGHTY_BUFFERS_EXPORT void nb_init(struct nb_buffer * buffer, size_t block_size
202235
NAUGHTY_BUFFERS_EXPORT void nb_init_advanced(
203236
struct nb_buffer * buffer,
204237
size_t block_size,
205-
nb_alloc_fn alloc_fn,
206-
nb_realloc_fn realloc_fn,
207-
nb_free_fn free_fn,
208-
nb_copy_fn copy_fn,
209-
nb_move_fn move_fn,
210-
void * memory_context
238+
struct nb_buffer_memory_context * memory_context
211239
);
212240

213241
/**

src/naughty-buffers/buffer.c

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,56 @@
22
#include "memory.h"
33
#include <stdlib.h>
44

5-
static size_t size_t_max(size_t a, size_t b) {
5+
static inline void * ctx_alloc(struct nb_buffer * buffer, size_t size) {
6+
return buffer->memory_context->alloc_fn(size, buffer->memory_context->context);
7+
}
8+
9+
static inline void * ctx_realloc(struct nb_buffer * buffer, void * ptr, size_t size) {
10+
return buffer->memory_context->realloc_fn(ptr, size, buffer->memory_context->context);
11+
}
12+
13+
static inline void * ctx_copy(struct nb_buffer * buffer, void * destination, void * source, size_t size) {
14+
return buffer->memory_context->copy_fn(destination, source, size, buffer->memory_context->context);
15+
}
16+
17+
static inline void * ctx_move(struct nb_buffer * buffer, void * destination, void * source, size_t size) {
18+
return buffer->memory_context->move_fn(destination, source, size, buffer->memory_context->context);
19+
}
20+
21+
static inline void ctx_release(struct nb_buffer * buffer, void * ptr) {
22+
buffer->memory_context->free_fn(ptr, buffer->memory_context->context);
23+
}
24+
25+
struct nb_buffer_memory_context default_memory_context = {
26+
.context = NULL,
27+
.free_fn = nb_memory_release,
28+
.copy_fn = nb_memory_copy,
29+
.realloc_fn = nb_memory_realloc,
30+
.alloc_fn = nb_memory_alloc,
31+
.move_fn = nb_memory_move
32+
};
33+
34+
static inline size_t size_t_max(size_t a, size_t b) {
635
if (a > b) return a;
736
else return b;
837
}
938

1039
void nb_init(struct nb_buffer * buffer, size_t block_size) {
11-
nb_init_advanced(
12-
buffer, block_size, nb_memory_alloc, nb_memory_realloc, nb_memory_release, nb_memory_copy, nb_memory_move, NULL
13-
);
14-
}
15-
16-
void nb_init_advanced(
17-
struct nb_buffer * buffer,
18-
size_t block_size,
19-
nb_alloc_fn alloc_fn,
20-
nb_realloc_fn realloc_fn,
21-
nb_free_fn free_fn,
22-
nb_copy_fn copy_fn,
23-
nb_move_fn move_fn,
24-
void * memory_context
25-
) {
40+
nb_init_advanced(buffer, block_size, &default_memory_context);
41+
}
42+
43+
void nb_init_advanced(struct nb_buffer * buffer, size_t block_size, struct nb_buffer_memory_context * memory_context) {
2644
buffer->block_size = block_size;
2745
buffer->block_capacity = 2;
2846
buffer->block_count = 0;
29-
buffer->alloc_fn = alloc_fn;
30-
buffer->realloc_fn = realloc_fn;
31-
buffer->free_fn = free_fn;
32-
buffer->copy_fn = copy_fn;
33-
buffer->move_fn = move_fn;
3447
buffer->memory_context = memory_context;
35-
buffer->data = buffer->alloc_fn(buffer->block_size * 2, buffer->memory_context);
48+
buffer->data = ctx_alloc(buffer, buffer->block_size * 2);
3649
}
3750

3851
uint8_t nb_grow(struct nb_buffer * buffer, size_t desired_capacity) {
3952
size_t new_block_capacity = buffer->block_capacity * 2;
4053
while (new_block_capacity <= desired_capacity) new_block_capacity *= 2;
41-
void * new_data = buffer->realloc_fn(buffer->data, buffer->block_size * new_block_capacity, buffer->memory_context);
54+
void * new_data = ctx_realloc(buffer, buffer->data, buffer->block_size * new_block_capacity);
4255
if (!new_data) return 0;
4356
buffer->data = new_data;
4457
buffer->block_capacity = new_block_capacity;
@@ -53,7 +66,7 @@ enum NB_PUSH_RESULT nb_push(struct nb_buffer * buffer, void * data) {
5366

5467
uint8_t * buffer_data = buffer->data;
5568
void * block_data = buffer_data + (buffer->block_count * buffer->block_size);
56-
buffer->copy_fn(block_data, data, buffer->block_size, buffer->memory_context);
69+
ctx_copy(buffer, block_data, data, buffer->block_size);
5770
buffer->block_count += 1;
5871
return NB_PUSH_OK;
5972
}
@@ -72,15 +85,11 @@ void * nb_front(struct nb_buffer * buffer) { return nb_at(buffer, 0); }
7285
void * nb_back(struct nb_buffer * buffer) { return nb_at(buffer, buffer->block_count - 1); }
7386

7487
void nb_release(struct nb_buffer * buffer) {
75-
buffer->free_fn(buffer->data, buffer->memory_context);
88+
ctx_release(buffer, buffer->data);
7689

7790
buffer->block_size = 0;
7891
buffer->block_capacity = 0;
7992
buffer->block_count = 0;
80-
buffer->alloc_fn = NULL;
81-
buffer->realloc_fn = NULL;
82-
buffer->free_fn = NULL;
83-
buffer->copy_fn = NULL;
8493
buffer->memory_context = NULL;
8594
buffer->data = NULL;
8695
}
@@ -92,7 +101,7 @@ enum NB_ASSIGN_RESULT nb_assign(struct nb_buffer * buffer, size_t index, void *
92101
}
93102
uint8_t * buffer_data = buffer->data;
94103
void * block_data = buffer_data + (index * buffer->block_size);
95-
buffer->copy_fn(block_data, data, buffer->block_size, buffer->memory_context);
104+
ctx_copy(buffer, block_data, data, buffer->block_size);
96105
if (index >= buffer->block_count) buffer->block_count = index + 1;
97106
return NB_ASSIGN_OK;
98107
}
@@ -109,9 +118,9 @@ enum NB_INSERT_RESULT nb_insert(struct nb_buffer * buffer, size_t index, void *
109118
uint8_t * dest = buffer_data + ((index + 1) * buffer->block_size);
110119
uint8_t * src = block_data;
111120
size_t move_size = (buffer->block_count - index) * buffer->block_size;
112-
buffer->move_fn(dest, src, move_size, buffer->memory_context);
121+
ctx_move(buffer, dest, src, move_size);
113122
}
114-
buffer->copy_fn(block_data, data, buffer->block_size, buffer->memory_context);
123+
ctx_copy(buffer, block_data, data, buffer->block_size);
115124
if (index >= buffer->block_count) buffer->block_count = index + 1;
116125
else buffer->block_count += 1;
117126
return NB_INSERT_OK;
@@ -133,7 +142,7 @@ void nb_remove_at(struct nb_buffer * buffer, size_t index) {
133142
uint8_t * src = buffer_data + ((index + 1) * buffer->block_size);
134143
size_t move_count = buffer->block_count - index - 1;
135144
size_t move_size = move_count * buffer->block_size;
136-
buffer->move_fn(dest, src, move_size, buffer->memory_context);
145+
ctx_move(buffer, dest, src, move_size);
137146
buffer->block_count--;
138147
}
139148

src/tests/array-generator.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ void * nb_test_move(void * destination, const void * source, size_t size, void *
4545
return memmove(destination, source, size);
4646
}
4747

48+
struct nb_buffer_memory_context ctx = {
49+
.move_fn = nb_test_move,
50+
.alloc_fn = nb_test_alloc,
51+
.realloc_fn = nb_test_realloc,
52+
.copy_fn = nb_test_copy,
53+
.free_fn = nb_test_release
54+
};
55+
4856
void array_generator_init_works() {
4957
struct test_array test_array;
5058
test_array_init(&test_array);
@@ -56,15 +64,9 @@ void array_generator_init_works() {
5664

5765
void array_generator_init_advanced_works() {
5866
struct test_array test_array;
59-
test_array_init_advanced(
60-
&test_array, nb_test_alloc, nb_test_realloc, nb_test_release, nb_test_copy, nb_test_move, &test_array
61-
);
62-
63-
assert(test_array.buffer.alloc_fn == nb_test_alloc);
64-
assert(test_array.buffer.realloc_fn == nb_test_realloc);
65-
assert(test_array.buffer.free_fn == nb_test_release);
66-
assert(test_array.buffer.copy_fn == nb_test_copy);
67-
assert(test_array.buffer.memory_context == &test_array);
67+
test_array_init_advanced(&test_array, &ctx);
68+
69+
assert(test_array.buffer.memory_context == &ctx);
6870

6971
assert(test_array.buffer.block_size == sizeof(struct nb_test));
7072

0 commit comments

Comments
 (0)