Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
386 changes: 203 additions & 183 deletions sp.h

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions sp/sp_asset.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct sp_asset_registry {
};

void sp_asset_registry_init(sp_asset_registry_t* r, sp_mem_t mem, sp_asset_registry_config_t config);
void* sp_asset_registry_on_alloc(void* ud, sp_mem_alloc_mode_t mode, u64 size, void* old);
void* sp_asset_registry_on_alloc(void* ud, sp_mem_alloc_mode_t mode, u64 size, void* old, u64 old_size);
void sp_asset_registry_shutdown(sp_asset_registry_t* r);
sp_asset_t* sp_asset_registry_import(sp_asset_registry_t* r, sp_asset_kind_t k, sp_str_t name, void* user_data);
sp_asset_t* sp_asset_registry_add(sp_asset_registry_t* r, sp_asset_kind_t k, sp_str_t name, void* data);
Expand All @@ -92,10 +92,10 @@ s32 sp_asset_registry_thread_fn(void* user_data);
#endif

#if defined(SP_ASSET_IMPLEMENTATION)
void* sp_asset_registry_on_alloc(void* ud, sp_mem_alloc_mode_t mode, u64 size, void* old) {
void* sp_asset_registry_on_alloc(void* ud, sp_mem_alloc_mode_t mode, u64 size, void* old, u64 old_size) {
sp_asset_registry_t* r = (sp_asset_registry_t*)ud;
sp_mutex_lock(&r->alloc_mutex);
void* result = sp_mem_arena_on_alloc(r->arena, mode, size, old);
void* result = sp_mem_arena_on_alloc(r->arena, mode, size, old, old_size);
sp_mutex_unlock(&r->alloc_mutex);
return result;
}
Expand Down
4 changes: 2 additions & 2 deletions sp/sp_prompt.h
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,7 @@ sp_prompt_ctx_t* sp_prompt_new(sp_mem_t mem) {
sp_prompt_ctx_t* sp_prompt_begin(sp_mem_t mem) {
sp_prompt_ctx_t* ctx = sp_prompt_new(mem);
if (sp_prompt_begin_ex(ctx)) {
sp_free(mem, ctx);
sp_free(mem, ctx, sizeof(sp_prompt_ctx_t));
return SP_NULLPTR;
}
return ctx;
Expand Down Expand Up @@ -1014,7 +1014,7 @@ void sp_prompt_ctx_init(sp_prompt_ctx_t* ctx, sp_mem_t mem, u32 cols, u32 rows)
sp_da_init(ctx->mem, ctx->frames);

sp_mutex_init(&ctx->channel.lock, SP_MUTEX_PLAIN);
ctx->channel.arena = sp_mem_arena_new_ex(mem, 4096, SP_MEM_ARENA_MODE_DEFAULT, SP_MEM_ALIGNMENT);
ctx->channel.arena = sp_mem_arena_new_ex(mem, 4096, SP_MEM_ALIGNMENT);

// Write buffering is really important, because our rendering algorithm is extremely
// naive. It's not much more than this:
Expand Down
2 changes: 1 addition & 1 deletion test/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ UTEST_F(dyn_array, pointer_type) {
}

for (u64 i = 0; i < sp_da_size(arr); i++) {
sp_free(ut.mem, arr[i]);
sp_free(ut.mem, arr[i], sp_cstr_len(arr[i]) + 1);
}

sp_da_free(arr);
Expand Down
32 changes: 15 additions & 17 deletions test/bench/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ static void bench_alloc_slot(const bench_workload_t* w, u32 slot) {
}

static void bench_free_slot(u32 slot) {
sp_free(state.mem, state.ptrs[slot]);
sp_free(state.mem, state.ptrs[slot], state.sizes[slot]);
state.live_req -= state.sizes[slot];
state.ptrs[slot] = SP_NULLPTR;
state.sizes[slot] = 0;
}

static void bench_realloc_slot(u32 slot, u64 size) {
state.ptrs[slot] = sp_realloc(state.mem, state.ptrs[slot], size);
state.ptrs[slot] = sp_realloc(state.mem, state.ptrs[slot], state.sizes[slot], size);
SP_ASSERT(state.ptrs[slot]);
bench_touch(state.ptrs[slot], size);
state.live_req -= state.sizes[slot];
Expand Down Expand Up @@ -140,8 +140,9 @@ static bool bench_heap_sample(void* ctx, u64* used, u64* reserved) {
}

#if !defined(SP_FREESTANDING)
static void* bench_malloc_on_alloc(void* user_data, sp_mem_alloc_mode_t mode, u64 size, void* ptr) {
static void* bench_malloc_on_alloc(void* user_data, sp_mem_alloc_mode_t mode, u64 size, void* ptr, u64 old_size) {
sp_unused(user_data);
sp_unused(old_size);
switch (mode) {
case SP_ALLOCATOR_MODE_ALLOC: return malloc(size);
case SP_ALLOCATOR_MODE_RESIZE: return realloc(ptr, size);
Expand Down Expand Up @@ -189,10 +190,10 @@ typedef struct {
static bench_os_counters_t bench_os_counters = sp_zero;

static u64 bench_os_reservation(u64 size) {
return sp_align_offset(size + sizeof(sp_mem_os_header_t), 4096);
return sp_align_offset(size, 4096);
}

static void* bench_os_on_alloc(void* user_data, sp_mem_alloc_mode_t mode, u64 size, void* ptr) {
static void* bench_os_on_alloc(void* user_data, sp_mem_alloc_mode_t mode, u64 size, void* ptr, u64 old_size) {
bench_os_counters_t* counters = (bench_os_counters_t*)user_data;
switch (mode) {
case SP_ALLOCATOR_MODE_ALLOC: {
Expand All @@ -205,25 +206,22 @@ static void* bench_os_on_alloc(void* user_data, sp_mem_alloc_mode_t mode, u64 si
return p;
}
case SP_ALLOCATOR_MODE_RESIZE: {
if (!ptr) return bench_os_on_alloc(user_data, SP_ALLOCATOR_MODE_ALLOC, size, SP_NULLPTR);
u64 old = sp_mem_os_get_header(ptr)->size;
void* p = sp_mem_os_realloc(ptr, size);
if (!ptr) return bench_os_on_alloc(user_data, SP_ALLOCATOR_MODE_ALLOC, size, SP_NULLPTR, 0);
void* p = sp_mem_os_realloc(ptr, old_size, size);
if (p) {
u64 now = sp_mem_os_get_header(p)->size;
counters->used -= old;
counters->used += now;
counters->reserved -= bench_os_reservation(old);
counters->reserved += bench_os_reservation(now);
counters->used -= old_size;
counters->used += size;
counters->reserved -= bench_os_reservation(old_size);
counters->reserved += bench_os_reservation(size);
counters->peak_reserved = sp_max(counters->peak_reserved, counters->reserved);
}
return p;
}
case SP_ALLOCATOR_MODE_FREE: {
if (ptr) {
u64 old = sp_mem_os_get_header(ptr)->size;
counters->used -= old;
counters->reserved -= bench_os_reservation(old);
sp_mem_os_free(ptr);
counters->used -= old_size;
counters->reserved -= bench_os_reservation(old_size);
sp_mem_os_free(ptr, old_size);
}
return SP_NULLPTR;
}
Expand Down
11 changes: 6 additions & 5 deletions test/bench/ubench.h
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ void ubench_register_benchmark(sp_str_t name, ubench_body_t body, const ubench_f
const ubench_size_t i = ubench_state.benchmarks_length++;
ubench_state.benchmarks = sp_ptr_cast(
ubench_benchmark_state_t*,
sp_realloc(ubench_state.mem, ubench_state.benchmarks, sizeof(ubench_benchmark_state_t) * ubench_state.benchmarks_length)
sp_realloc(ubench_state.mem, ubench_state.benchmarks, sizeof(ubench_benchmark_state_t) * i, sizeof(ubench_benchmark_state_t) * ubench_state.benchmarks_length)
);

ubench_state.benchmarks[i].name = name;
Expand Down Expand Up @@ -1190,7 +1190,7 @@ bench_store* bench_store_open(const c8 *path) {
return s;

error:
if (s) sp_mem_allocator_free(mem, s);
if (s) sp_mem_allocator_free(mem, s, sizeof(bench_store));
return SP_NULLPTR;
}

Expand All @@ -1200,7 +1200,7 @@ void bench_store_close(bench_store* s) {
if (s->db) sqlite3_close(s->db);

sp_mem_t mem = sp_mem_os_new();
sp_mem_allocator_free(mem, s);
sp_mem_allocator_free(mem, s, sizeof(bench_store));
}

s64 bench_store_begin_run(bench_store* s, const bench_machine_info* mi, const bench_run_info* ri) {
Expand Down Expand Up @@ -1777,6 +1777,7 @@ s32 ubench_main(s32 argc, const c8 *const argv[]) {
ubench_size_t *,
sp_realloc(ubench_state.mem,
sp_ptr_cast(void *, failed_benchmarks),
sizeof(ubench_size_t) * failed_benchmark_index,
sizeof(ubench_size_t) * failed_benchmarks_length));
failed_benchmarks[failed_benchmark_index] = index;
failed++;
Expand Down Expand Up @@ -1857,8 +1858,8 @@ s32 ubench_main(s32 argc, const c8 *const argv[]) {
}

cleanup:
sp_free(ubench_state.mem, sp_ptr_cast(void *, failed_benchmarks));
sp_free(ubench_state.mem, sp_ptr_cast(void *, ubench_state.benchmarks));
sp_free(ubench_state.mem, sp_ptr_cast(void *, failed_benchmarks), sizeof(ubench_size_t) * failed_benchmarks_length);
sp_free(ubench_state.mem, sp_ptr_cast(void *, ubench_state.benchmarks), sizeof(ubench_benchmark_state_t) * ubench_state.benchmarks_length);

#if defined(UBENCH_ENABLE_PERF_COUNTERS) && defined(SP_LINUX)
ubench_perf_close(&perf);
Expand Down
2 changes: 1 addition & 1 deletion test/ht.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ UTEST_F(siphash, collision_resistance) {

EXPECT_EQ(collisions, 0);

sp_free(ut.mem, hashes);
sp_free(ut.mem, hashes, count * sizeof(u64));
}

UTEST_F(sp_ht, hash_table_with_dyn_array_values) {
Expand Down
30 changes: 15 additions & 15 deletions test/leak.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ UTEST(tracking, alloc_free_balance) {
EXPECT_EQ(t.live_count, 1u);
EXPECT_EQ(t.live_bytes, 64u);

sp_free(mem, p);
sp_free(mem, p, 64);
EXPECT_EQ(t.live_count, 0u);
EXPECT_EQ(t.live_bytes, 0u);
EXPECT_EQ(t.double_frees, 0u);
Expand All @@ -55,7 +55,7 @@ UTEST(tracking, detects_leak) {
sp_alloc(mem, 16);
sp_alloc(mem, 32);
void* freed = sp_alloc(mem, 8);
sp_free(mem, freed);
sp_free(mem, freed, 8);

EXPECT_EQ(t.live_count, 2u);
EXPECT_EQ(t.live_bytes, 48u);
Expand All @@ -69,9 +69,9 @@ UTEST(tracking, detects_double_free) {
sp_mem_t mem = sp_mem_tracking_as_allocator(&t);

void* p = sp_alloc(mem, 64);
sp_free(mem, p);
sp_free(mem, p);
sp_free(mem, p);
sp_free(mem, p, 64);
sp_free(mem, p, 64);
sp_free(mem, p, 64);

EXPECT_EQ(t.double_frees, 2u);
EXPECT_EQ(t.live_count, 0u);
Expand All @@ -90,7 +90,7 @@ UTEST(tracking, detects_wild_free) {
// large enough for the back-step, and the bytes there won't match either
// sentinel (we zero-init the buffer).
static u8 buf[256] = {0};
sp_free(mem, &buf[200]);
sp_free(mem, &buf[200], 8);

EXPECT_EQ(t.wild_frees, 1u);
EXPECT_EQ(t.double_frees, 0u);
Expand All @@ -104,7 +104,7 @@ UTEST(tracking, free_null_is_noop) {
sp_mem_tracking_init(&t);
sp_mem_t mem = sp_mem_tracking_as_allocator(&t);

sp_free(mem, SP_NULLPTR);
sp_free(mem, SP_NULLPTR, 0);

EXPECT_EQ(t.double_frees, 0u);
EXPECT_EQ(t.wild_frees, 0u);
Expand All @@ -121,14 +121,14 @@ UTEST(tracking, realloc_grows_and_preserves) {
u8* p = sp_alloc_n(mem, u8, 4);
sp_for(i, 4) p[i] = (u8)(i + 1);

u8* g = sp_void_cast(g, sp_realloc(mem, p, 64));
u8* g = sp_void_cast(g, sp_realloc(mem, p, 4, 64));
EXPECT_NE(g, SP_NULLPTR);
sp_for(i, 4) EXPECT_EQ(g[i], (u8)(i + 1));

EXPECT_EQ(t.live_count, 1u);
EXPECT_EQ(t.live_bytes, 64u);

sp_free(mem, g);
sp_free(mem, g, 64);
EXPECT_EQ(t.live_count, 0u);

sp_mem_tracking_deinit(&t);
Expand All @@ -139,12 +139,12 @@ UTEST(tracking, realloc_null_is_alloc) {
sp_mem_tracking_init(&t);
sp_mem_t mem = sp_mem_tracking_as_allocator(&t);

void* p = sp_realloc(mem, SP_NULLPTR, 32);
void* p = sp_realloc(mem, SP_NULLPTR, 0, 32);
EXPECT_NE(p, SP_NULLPTR);
EXPECT_EQ(t.live_count, 1u);
EXPECT_EQ(t.live_bytes, 32u);

sp_free(mem, p);
sp_free(mem, p, 32);
sp_mem_tracking_deinit(&t);
}

Expand All @@ -154,7 +154,7 @@ UTEST(tracking, realloc_zero_is_free) {
sp_mem_t mem = sp_mem_tracking_as_allocator(&t);

void* p = sp_alloc(mem, 32);
void* r = sp_realloc(mem, p, 0);
void* r = sp_realloc(mem, p, 32, 0);
EXPECT_EQ(r, SP_NULLPTR);
EXPECT_EQ(t.live_count, 0u);
EXPECT_EQ(t.live_bytes, 0u);
Expand Down Expand Up @@ -200,11 +200,11 @@ UTEST_F(leak, multiple_allocs_independent) {
EXPECT_EQ(ut.tracker.live_count, 3u);
EXPECT_EQ(ut.tracker.live_bytes, 56u);

sp_free(ut.mem, b);
sp_free(ut.mem, b, 16);
EXPECT_EQ(ut.tracker.live_count, 2u);
EXPECT_EQ(ut.tracker.live_bytes, 40u);

sp_free(ut.mem, a);
sp_free(ut.mem, c);
sp_free(ut.mem, a, 8);
sp_free(ut.mem, c, 32);
EXPECT_EQ(ut.tracker.live_count, 0u);
}
Loading
Loading