| @@ -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 | |||
| #include "types.hpp" | |||
| #include "allocation_stats.hpp" | |||
| #include "macros.hpp" | |||
| template <typename type> | |||
| @@ -84,7 +85,7 @@ struct Array_List { | |||
| u32 count; | |||
| void alloc(u32 initial_capacity = 16) { | |||
| data = (type*)malloc(initial_capacity * sizeof(type)); | |||
| data = (type*)ftb_malloc(initial_capacity * sizeof(type)); | |||
| count = 0; | |||
| length = initial_capacity; | |||
| } | |||
| @@ -98,7 +99,7 @@ struct Array_List { | |||
| void alloc_from(std::initializer_list<type> l) { | |||
| length = max(l.size(), 1); // alloc at least one | |||
| data = (type*)malloc(length * sizeof(type)); | |||
| data = (type*)ftb_malloc(length * sizeof(type)); | |||
| count = 0; | |||
| // TODO(Felix): Use memcpy here | |||
| for (type t : l) { | |||
| @@ -115,7 +116,7 @@ struct Array_List { | |||
| } | |||
| void dealloc() { | |||
| free(data); | |||
| ftb_free(data); | |||
| data = nullptr; | |||
| } | |||
| @@ -141,7 +142,7 @@ struct Array_List { | |||
| ret.length = length; | |||
| ret.count = count; | |||
| ret.data = (type*)malloc(length * sizeof(type)); | |||
| ret.data = (type*)ftb_malloc(length * sizeof(type)); | |||
| // TODO(Felix): Maybe use memcpy here | |||
| for (u32 i = 0; i < count; ++i) { | |||
| ret.data[i] = data[i]; | |||
| @@ -174,7 +175,7 @@ struct Array_List { | |||
| void append(type element) { | |||
| if (count == length) { | |||
| length *= 2; | |||
| data = (type*)realloc(data, length * sizeof(type)); | |||
| data = (type*)ftb_realloc(data, length * sizeof(type)); | |||
| } | |||
| data[count] = element; | |||
| count++; | |||
| @@ -183,7 +184,7 @@ struct Array_List { | |||
| void reserve(u32 amount) { | |||
| if (count+amount >= (u32)length) { | |||
| 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() { | |||
| free(this->data); | |||
| ftb_free(this->data); | |||
| this->data = nullptr; | |||
| } | |||
| }; | |||
| @@ -19,7 +19,7 @@ struct Bucket_Allocator { | |||
| } | |||
| void expand() { | |||
| buckets = (type**)realloc(buckets, bucket_count * 2 * sizeof(type*)); | |||
| buckets = (type**)ftb_realloc(buckets, bucket_count * 2 * sizeof(type*)); | |||
| bucket_count *= 2; | |||
| } | |||
| @@ -29,7 +29,7 @@ struct Bucket_Allocator { | |||
| if (next_bucket_index >= bucket_count) { | |||
| 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) { | |||
| @@ -46,16 +46,16 @@ struct Bucket_Allocator { | |||
| next_bucket_index = 0; | |||
| 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() { | |||
| for (u32 i = 0; i <= next_bucket_index; ++i) { | |||
| free(buckets[i]); | |||
| ftb_free(buckets[i]); | |||
| } | |||
| this->free_list.dealloc(); | |||
| free(buckets); | |||
| ftb_free(buckets); | |||
| } | |||
| u32 count_elements() { | |||
| @@ -15,14 +15,14 @@ struct Error { | |||
| Error* error = nullptr; | |||
| auto delete_error() -> void { | |||
| free(error); | |||
| ftb_free(error); | |||
| error = nullptr; | |||
| } | |||
| auto create_error(const char* c_func_name, const char* c_file_name, | |||
| 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_start(args, format); | |||
| @@ -74,11 +74,11 @@ struct Hash_Map { | |||
| // until here | |||
| current_capacity = initial_capacity; | |||
| cell_count = 0; | |||
| data = (HM_Cell*)calloc(initial_capacity, sizeof(HM_Cell)); | |||
| data = (HM_Cell*)ftb_calloc(initial_capacity, sizeof(HM_Cell)); | |||
| } | |||
| void dealloc() { | |||
| free(data); | |||
| ftb_free(data); | |||
| data = nullptr; | |||
| } | |||
| @@ -209,7 +209,7 @@ struct Hash_Map { | |||
| /* collision, check resize */ | |||
| if ((cell_count*1.0f / current_capacity) > 0.666f) { | |||
| 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; | |||
| current_capacity *= 4; | |||
| @@ -220,7 +220,7 @@ struct Hash_Map { | |||
| set_object(cell.original, cell.object, cell.hash); | |||
| } | |||
| } | |||
| free(old_data); | |||
| ftb_free(old_data); | |||
| index = hash_val & (current_capacity - 1); | |||
| } | |||
| ++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) | |||
| 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)); | |||
| 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) { | |||
| printf("ERROR: %s printer not found\n", spec); | |||
| free(spec); | |||
| ftb_free(spec); | |||
| return 0; | |||
| } | |||
| free(spec); | |||
| if (format[end_pos] == ',') { | |||
| int element_count; | |||
| @@ -265,7 +264,7 @@ int maybe_fprintf(FILE* file, static_string format, int* pos, va_list* arg_list) | |||
| format[end_pos] == '%') | |||
| { | |||
| 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[1] = 0; | |||
| 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*); | |||
| } | |||
| free(temp); | |||
| *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); | |||
| *out = (char*)malloc(sizeof(char) * (num_printed_chars+1)); | |||
| *out = (char*)ftb_malloc(sizeof(char) * (num_printed_chars+1)); | |||
| rewind(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); | |||
| *out = (char*)malloc(sizeof(char) * (num_printed_chars+1)); | |||
| *out = (char*)ftb_malloc(sizeof(char) * (num_printed_chars+1)); | |||
| rewind(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++) | |||
| printf(" %3lu: %s\n", size - i - 1, strings[i]); | |||
| puts(""); | |||
| free(strings); | |||
| ftb_free(strings); | |||
| #endif | |||
| } | |||
| @@ -1,4 +1,5 @@ | |||
| #include "./types.hpp" | |||
| #include "./allocation_stats.hpp" | |||
| typedef s32 testresult; | |||
| @@ -87,7 +88,7 @@ typedef s32 testresult; | |||
| fputs((i%3==1)? "." : " ", stdout); \ | |||
| fputs(console_red "failed\n" console_normal, stdout); \ | |||
| if(error) { \ | |||
| free(error); \ | |||
| ftb_free(error); \ | |||
| error = nullptr; \ | |||
| } \ | |||
| } | |||
| @@ -12,6 +12,7 @@ inline bool hm_objects_match(Key a, Key b); | |||
| #define ZoneScoped | |||
| #define ZoneScopedN(name) | |||
| #define USE_FTB_MALLOC | |||
| #include "../print.hpp" | |||
| #include "../testing.hpp" | |||
| #include "../bucket_allocator.hpp" | |||
| @@ -693,6 +694,8 @@ auto test_scheduler_animations() -> testresult { | |||
| } | |||
| s32 main(s32, char**) { | |||
| defer { print_malloc_stats(); }; | |||
| init_printer(); | |||
| defer { deinit_printer(); }; | |||
| testresult result; | |||