| @@ -0,0 +1,43 @@ | |||||
| #pragma once | |||||
| #include <stdlib.h> | |||||
| #include <stdio.h> | |||||
| #include "types.hpp" | |||||
| #ifdef USE_FTB_MALLOC | |||||
| namespace Ftb_Malloc_Stats { | |||||
| u32 malloc_calls = 0; | |||||
| u32 free_calls = 0; | |||||
| u32 realloc_calls = 0; | |||||
| u32 calloc_calls = 0; | |||||
| u32 alloca_calls = 0; | |||||
| } | |||||
| #define ftb_malloc(size) (++Ftb_Malloc_Stats::malloc_calls, malloc(size)) | |||||
| #define ftb_free(ptr) (++Ftb_Malloc_Stats::free_calls, free(ptr)) | |||||
| #define ftb_realloc(ptr, size) (++Ftb_Malloc_Stats::realloc_calls, realloc(ptr, size)) | |||||
| #define ftb_calloc(num, size) (++Ftb_Malloc_Stats::calloc_calls, calloc(num, size)) | |||||
| #define ftb_alloca(size) (++Ftb_Malloc_Stats::alloca_calls, alloca(size)) | |||||
| void print_malloc_stats() { | |||||
| printf("\n" | |||||
| "Malloc Stats:\n" | |||||
| "-------------\n" | |||||
| " ftb_malloc calls: %u\n" | |||||
| " ftb_free calls: %u\n" | |||||
| " ftb_realloc calls: %u\n" | |||||
| " ftb_calloc calls: %u\n" | |||||
| " ftb_alloca calls: %u\n" , | |||||
| Ftb_Malloc_Stats::malloc_calls, | |||||
| Ftb_Malloc_Stats::free_calls, | |||||
| Ftb_Malloc_Stats::realloc_calls, | |||||
| Ftb_Malloc_Stats::calloc_calls, | |||||
| Ftb_Malloc_Stats::alloca_calls); | |||||
| } | |||||
| #else | |||||
| # define ftb_malloc malloc | |||||
| # define ftb_realloc realloc | |||||
| # define ftb_calloc calloc | |||||
| # define ftb_free free | |||||
| # define ftb_alloca alloca | |||||
| #endif | |||||
| @@ -7,6 +7,7 @@ | |||||
| #endif | #endif | ||||
| #include "types.hpp" | #include "types.hpp" | ||||
| #include "allocation_stats.hpp" | |||||
| #include "macros.hpp" | #include "macros.hpp" | ||||
| template <typename type> | template <typename type> | ||||
| @@ -84,7 +85,7 @@ struct Array_List { | |||||
| u32 count; | u32 count; | ||||
| void alloc(u32 initial_capacity = 16) { | void alloc(u32 initial_capacity = 16) { | ||||
| data = (type*)malloc(initial_capacity * sizeof(type)); | |||||
| data = (type*)ftb_malloc(initial_capacity * sizeof(type)); | |||||
| count = 0; | count = 0; | ||||
| length = initial_capacity; | length = initial_capacity; | ||||
| } | } | ||||
| @@ -98,7 +99,7 @@ struct Array_List { | |||||
| void alloc_from(std::initializer_list<type> l) { | void alloc_from(std::initializer_list<type> l) { | ||||
| length = max(l.size(), 1); // alloc at least one | length = max(l.size(), 1); // alloc at least one | ||||
| data = (type*)malloc(length * sizeof(type)); | |||||
| data = (type*)ftb_malloc(length * sizeof(type)); | |||||
| count = 0; | count = 0; | ||||
| // TODO(Felix): Use memcpy here | // TODO(Felix): Use memcpy here | ||||
| for (type t : l) { | for (type t : l) { | ||||
| @@ -115,7 +116,7 @@ struct Array_List { | |||||
| } | } | ||||
| void dealloc() { | void dealloc() { | ||||
| free(data); | |||||
| ftb_free(data); | |||||
| data = nullptr; | data = nullptr; | ||||
| } | } | ||||
| @@ -141,7 +142,7 @@ struct Array_List { | |||||
| ret.length = length; | ret.length = length; | ||||
| ret.count = count; | ret.count = count; | ||||
| ret.data = (type*)malloc(length * sizeof(type)); | |||||
| ret.data = (type*)ftb_malloc(length * sizeof(type)); | |||||
| // TODO(Felix): Maybe use memcpy here | // TODO(Felix): Maybe use memcpy here | ||||
| for (u32 i = 0; i < count; ++i) { | for (u32 i = 0; i < count; ++i) { | ||||
| ret.data[i] = data[i]; | ret.data[i] = data[i]; | ||||
| @@ -174,7 +175,7 @@ struct Array_List { | |||||
| void append(type element) { | void append(type element) { | ||||
| if (count == length) { | if (count == length) { | ||||
| length *= 2; | length *= 2; | ||||
| data = (type*)realloc(data, length * sizeof(type)); | |||||
| data = (type*)ftb_realloc(data, length * sizeof(type)); | |||||
| } | } | ||||
| data[count] = element; | data[count] = element; | ||||
| count++; | count++; | ||||
| @@ -183,7 +184,7 @@ struct Array_List { | |||||
| void reserve(u32 amount) { | void reserve(u32 amount) { | ||||
| if (count+amount >= (u32)length) { | if (count+amount >= (u32)length) { | ||||
| length *= 2; | length *= 2; | ||||
| data = (type*)realloc(data, length * sizeof(type)); | |||||
| data = (type*)ftb_realloc(data, length * sizeof(type)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -281,7 +282,7 @@ struct Auto_Array_List : public Array_List<type> { | |||||
| } | } | ||||
| ~Auto_Array_List() { | ~Auto_Array_List() { | ||||
| free(this->data); | |||||
| ftb_free(this->data); | |||||
| this->data = nullptr; | this->data = nullptr; | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -19,7 +19,7 @@ struct Bucket_Allocator { | |||||
| } | } | ||||
| void expand() { | void expand() { | ||||
| buckets = (type**)realloc(buckets, bucket_count * 2 * sizeof(type*)); | |||||
| buckets = (type**)ftb_realloc(buckets, bucket_count * 2 * sizeof(type*)); | |||||
| bucket_count *= 2; | bucket_count *= 2; | ||||
| } | } | ||||
| @@ -29,7 +29,7 @@ struct Bucket_Allocator { | |||||
| if (next_bucket_index >= bucket_count) { | if (next_bucket_index >= bucket_count) { | ||||
| expand(); | expand(); | ||||
| } | } | ||||
| buckets[next_bucket_index] = (type*)malloc(bucket_size * sizeof(type)); | |||||
| buckets[next_bucket_index] = (type*)ftb_malloc(bucket_size * sizeof(type)); | |||||
| } | } | ||||
| void increment_pointers(s32 amount = 1) { | void increment_pointers(s32 amount = 1) { | ||||
| @@ -46,16 +46,16 @@ struct Bucket_Allocator { | |||||
| next_bucket_index = 0; | next_bucket_index = 0; | ||||
| bucket_count = initial_bucket_count; | bucket_count = initial_bucket_count; | ||||
| buckets = (type**)malloc(bucket_count * sizeof(type*)); | |||||
| buckets[0] = (type*)malloc(bucket_size * sizeof(type)); | |||||
| buckets = (type**)ftb_malloc(bucket_count * sizeof(type*)); | |||||
| buckets[0] = (type*)ftb_malloc(bucket_size * sizeof(type)); | |||||
| } | } | ||||
| void dealloc() { | void dealloc() { | ||||
| for (u32 i = 0; i <= next_bucket_index; ++i) { | for (u32 i = 0; i <= next_bucket_index; ++i) { | ||||
| free(buckets[i]); | |||||
| ftb_free(buckets[i]); | |||||
| } | } | ||||
| this->free_list.dealloc(); | this->free_list.dealloc(); | ||||
| free(buckets); | |||||
| ftb_free(buckets); | |||||
| } | } | ||||
| u32 count_elements() { | u32 count_elements() { | ||||
| @@ -15,14 +15,14 @@ struct Error { | |||||
| Error* error = nullptr; | Error* error = nullptr; | ||||
| auto delete_error() -> void { | auto delete_error() -> void { | ||||
| free(error); | |||||
| ftb_free(error); | |||||
| error = nullptr; | error = nullptr; | ||||
| } | } | ||||
| auto create_error(const char* c_func_name, const char* c_file_name, | auto create_error(const char* c_func_name, const char* c_file_name, | ||||
| u32 c_file_line, String type, const char* format, ...) -> void { | u32 c_file_line, String type, const char* format, ...) -> void { | ||||
| error = (Error*) malloc(sizeof(Error)); | |||||
| error = (Error*) ftb_malloc(sizeof(Error)); | |||||
| va_list args; | va_list args; | ||||
| va_start(args, format); | va_start(args, format); | ||||
| @@ -74,11 +74,11 @@ struct Hash_Map { | |||||
| // until here | // until here | ||||
| current_capacity = initial_capacity; | current_capacity = initial_capacity; | ||||
| cell_count = 0; | cell_count = 0; | ||||
| data = (HM_Cell*)calloc(initial_capacity, sizeof(HM_Cell)); | |||||
| data = (HM_Cell*)ftb_calloc(initial_capacity, sizeof(HM_Cell)); | |||||
| } | } | ||||
| void dealloc() { | void dealloc() { | ||||
| free(data); | |||||
| ftb_free(data); | |||||
| data = nullptr; | data = nullptr; | ||||
| } | } | ||||
| @@ -209,7 +209,7 @@ struct Hash_Map { | |||||
| /* collision, check resize */ | /* collision, check resize */ | ||||
| if ((cell_count*1.0f / current_capacity) > 0.666f) { | if ((cell_count*1.0f / current_capacity) > 0.666f) { | ||||
| auto old_data = data; | auto old_data = data; | ||||
| data = (HM_Cell*)calloc(current_capacity*4, sizeof(HM_Cell)); | |||||
| data = (HM_Cell*)ftb_calloc(current_capacity*4, sizeof(HM_Cell)); | |||||
| cell_count = 0; | cell_count = 0; | ||||
| current_capacity *= 4; | current_capacity *= 4; | ||||
| @@ -220,7 +220,7 @@ struct Hash_Map { | |||||
| set_object(cell.original, cell.object, cell.hash); | set_object(cell.original, cell.object, cell.hash); | ||||
| } | } | ||||
| } | } | ||||
| free(old_data); | |||||
| ftb_free(old_data); | |||||
| index = hash_val & (current_capacity - 1); | index = hash_val & (current_capacity - 1); | ||||
| } | } | ||||
| ++cell_count; | ++cell_count; | ||||
| @@ -65,7 +65,7 @@ int maybe_special_print(FILE* file, static_string format, int* pos, va_list* arg | |||||
| if (format[end_pos] == 0) | if (format[end_pos] == 0) | ||||
| return 0; | return 0; | ||||
| char* spec = (char*)malloc(end_pos - (*pos)); | |||||
| char* spec = (char*)ftb_alloca(end_pos - (*pos)); | |||||
| strncpy(spec, format+(*pos)+1, end_pos - (*pos)); | strncpy(spec, format+(*pos)+1, end_pos - (*pos)); | ||||
| spec[end_pos - (*pos)-1] = '\0'; | spec[end_pos - (*pos)-1] = '\0'; | ||||
| @@ -86,11 +86,10 @@ int maybe_special_print(FILE* file, static_string format, int* pos, va_list* arg | |||||
| if (type == Printer_Function_Type::unknown) { | if (type == Printer_Function_Type::unknown) { | ||||
| printf("ERROR: %s printer not found\n", spec); | printf("ERROR: %s printer not found\n", spec); | ||||
| free(spec); | |||||
| ftb_free(spec); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| free(spec); | |||||
| if (format[end_pos] == ',') { | if (format[end_pos] == ',') { | ||||
| int element_count; | int element_count; | ||||
| @@ -265,7 +264,7 @@ int maybe_fprintf(FILE* file, static_string format, int* pos, va_list* arg_list) | |||||
| format[end_pos] == '%') | format[end_pos] == '%') | ||||
| { | { | ||||
| writen_len = end_pos - *pos + 2; | writen_len = end_pos - *pos + 2; | ||||
| char* temp = (char*)malloc((writen_len+1)* sizeof(char)); | |||||
| char* temp = (char*)alloca((writen_len+1)* sizeof(char)); | |||||
| temp[0] = '%'; | temp[0] = '%'; | ||||
| temp[1] = 0; | temp[1] = 0; | ||||
| strncpy(temp+1, format+*pos, writen_len); | strncpy(temp+1, format+*pos, writen_len); | ||||
| @@ -285,7 +284,6 @@ int maybe_fprintf(FILE* file, static_string format, int* pos, va_list* arg_list) | |||||
| va_arg(*arg_list, void*); | va_arg(*arg_list, void*); | ||||
| } | } | ||||
| free(temp); | |||||
| *pos = end_pos; | *pos = end_pos; | ||||
| } | } | ||||
| @@ -328,7 +326,7 @@ int print_va_args_to_string(char** out, static_string format, va_list* arg_list) | |||||
| int num_printed_chars = print_va_args_to_file(t_file, format, arg_list); | int num_printed_chars = print_va_args_to_file(t_file, format, arg_list); | ||||
| *out = (char*)malloc(sizeof(char) * (num_printed_chars+1)); | |||||
| *out = (char*)ftb_malloc(sizeof(char) * (num_printed_chars+1)); | |||||
| rewind(t_file); | rewind(t_file); | ||||
| fread(*out, sizeof(char), num_printed_chars, t_file); | fread(*out, sizeof(char), num_printed_chars, t_file); | ||||
| @@ -356,7 +354,7 @@ int print_to_string(char** out, static_string format, ...) { | |||||
| va_end(arg_list); | va_end(arg_list); | ||||
| *out = (char*)malloc(sizeof(char) * (num_printed_chars+1)); | |||||
| *out = (char*)ftb_malloc(sizeof(char) * (num_printed_chars+1)); | |||||
| rewind(t_file); | rewind(t_file); | ||||
| fread(*out, sizeof(char), num_printed_chars, t_file); | fread(*out, sizeof(char), num_printed_chars, t_file); | ||||
| @@ -45,7 +45,6 @@ auto print_stacktrace() -> void { | |||||
| for (i = 0; i < size; i++) | for (i = 0; i < size; i++) | ||||
| printf(" %3lu: %s\n", size - i - 1, strings[i]); | printf(" %3lu: %s\n", size - i - 1, strings[i]); | ||||
| puts(""); | puts(""); | ||||
| free(strings); | |||||
| ftb_free(strings); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -1,4 +1,5 @@ | |||||
| #include "./types.hpp" | #include "./types.hpp" | ||||
| #include "./allocation_stats.hpp" | |||||
| typedef s32 testresult; | typedef s32 testresult; | ||||
| @@ -87,7 +88,7 @@ typedef s32 testresult; | |||||
| fputs((i%3==1)? "." : " ", stdout); \ | fputs((i%3==1)? "." : " ", stdout); \ | ||||
| fputs(console_red "failed\n" console_normal, stdout); \ | fputs(console_red "failed\n" console_normal, stdout); \ | ||||
| if(error) { \ | if(error) { \ | ||||
| free(error); \ | |||||
| ftb_free(error); \ | |||||
| error = nullptr; \ | error = nullptr; \ | ||||
| } \ | } \ | ||||
| } | } | ||||
| @@ -12,6 +12,7 @@ inline bool hm_objects_match(Key a, Key b); | |||||
| #define ZoneScoped | #define ZoneScoped | ||||
| #define ZoneScopedN(name) | #define ZoneScopedN(name) | ||||
| #define USE_FTB_MALLOC | |||||
| #include "../print.hpp" | #include "../print.hpp" | ||||
| #include "../testing.hpp" | #include "../testing.hpp" | ||||
| #include "../bucket_allocator.hpp" | #include "../bucket_allocator.hpp" | ||||
| @@ -693,6 +694,8 @@ auto test_scheduler_animations() -> testresult { | |||||
| } | } | ||||
| s32 main(s32, char**) { | s32 main(s32, char**) { | ||||
| defer { print_malloc_stats(); }; | |||||
| init_printer(); | init_printer(); | ||||
| defer { deinit_printer(); }; | defer { deinit_printer(); }; | ||||
| testresult result; | testresult result; | ||||