#pragma once #include "FXAlloc.h" #ifdef _WIN32 typedef HANDLE fxsync_t; #else typedef pthread_mutex_t fxsync_t; #endif #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L) #error "C11 standard is required for _Atomic support" #endif #if defined(__clang__) // Clang: _Atomic поддерживается в C11 во всех актуальных версиях #elif defined(__GNUC__) #if (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 9) #error "GCC < 4.9 does not support _Atomic (C11)" #endif #elif defined(_MSC_VER) #if _MSC_VER < 1930 // VS 2022+ (_MSC_VER >= 1930) #error "MSVC < VS 2022 (_MSC_VER < 1930) does not support _Atomic (C11)" #endif #else #error "Unsupported compiler. Only Clang, GCC >=4.9, and MSVC VS 2022+ support _Atomic in C11" #endif typedef struct FXMemoryBlock FXMemoryBlock; #pragma pack(push, 8) /** * @brief Метаданные отдельного блока памяти * */ typedef struct FXMemoryBlock { FXMemoryBlock* next; ///< Следующий в стэке свободных FXMemoryBlock* list; ///< Следующий в списке алоцированных uint32_t thread_idx; ///< Индекс потока uint32_t grade_idx; ///< Индекс грейда uint32_t used; ///< Использовано байт uint32_t padding; ///< Это ненужные байты, во всяком случае - пока uint8_t data[]; ///< Пользовательские данные } FXMemoryBlock; #pragma pack(push, 16) /** * @brief Грейдовый пул выделяемый для градации * */ typedef struct FXGradePool { FXMemoryBlock* prealloced; ///< Преаллоцированные блоки FXMemoryBlock* lifo; ///< Стэк свободных блоков FXMemoryBlock* list; ///< Список аллоцированных блоков uint32_t ntotal; ///< Блоков всего uint32_t nbusy; ///< Блоков занято uint32_t nalloc; ///< Блоков алоцировано через `malloc` uint32_t nprealloc; ///< Блоков преаллоцировано } FXGradePool; #pragma pack(push, 8) /** * @brief Thread memory pool * */ typedef struct FXThreadPool { uint32_t isActive; uint32_t ngrades; FXGradePool grades[]; } FXThreadPool; #pragma pack(pop) typedef struct FXGlobalMemoryPool { FXThreadPool** pools; fxsync_t mutex; } FXGlobalMemoryPool;