/** * @file kc_memory_entry.c * @brief KC メモリ管理 Entry サブモジュール * @copyright 2003 - 2023 Nomura Kei */ #include <stdlib.h> #include <kc_memory.h> #include <kc_memory_entry.h> #include "kc_memory_entry_inner.h" #ifdef KC_MEMORY_ENABLED #undef KC_MEMORY_ENABLED #endif #if !(KC_IS_WINDOWS) #define _aligned_free(ptr) raw_free(ptr) #endif //////////////////////////////////////////////////////////////////////////////// // // 定数定義 // //////////////////////////////////////////////////////////////////////////////// // // 変数定義 // // For UNITTEST #ifdef UNITTEST bool (*_UT_KcMemory_can_alloc)( KcMemoryEntry *entry, size_t alignment, size_t size, KcMemoryMark mark, const char *file, const char *func, int line) = NULL; #endif // UNITTEST /** * KcMemoryEntry を構築します。 * entry が NULL の場合、新規に KeMemoryEntry を構築します。 * entry が NULL でない場合、entry の管理するメモリサイズを変更し、各種値を更新します。 * 構築に失敗した場合、NULL を返します。 * * @param entry メモリエントリ * @param alignment アライメント * @param size メモリサイズ * @param mark メモリ状態 * @param file メモリ確保ファイル名 * @param func メモリ確保関数名 * @param line メモリ確保行番号 * @return 構築した KcMemoryEntry */ KcMemoryEntry *KcMemoryEntry_new(KcMemoryEntry *entry, size_t alignment, size_t size, KcMemoryMark mark, const char *file, const char *func, int line) { #ifdef UNITTEST if (_UT_KcMemory_can_alloc && !_UT_KcMemory_can_alloc(entry, alignment, size, mark, file, func, line)) { return NULL; } #endif KcMemoryEntry *new_entry; if ((entry == NULL) && (alignment > 0) && (mark == KC_MEMORY_ALLOCATED_ALIGNED)) { // アライメント指定でメモリを確保する。 new_entry = (KcMemoryEntry *)raw_aligned_alloc( alignment, (size_t)(sizeof(KcMemoryEntry) + size)); } else { new_entry = (KcMemoryEntry *)raw_realloc( entry, (size_t)(sizeof(KcMemoryEntry) + size)); } KcMemoryEntry_set(new_entry, size, mark, file, func, line); return new_entry; } /** * KcMemoryEntry を破棄します。 * * @param entry 破棄するメモリエントリ */ void KcMemoryEntry_delete(KcMemoryEntry *entry) { if (entry->mark == KC_MEMORY_ALLOCATED_ALIGNED) { entry->mark = KC_MEMORY_DELETED; entry->size = 0; _aligned_free(entry); } else { entry->mark = KC_MEMORY_DELETED; entry->size = 0; raw_free(entry); } } /** * 指定された entry に、指定された値を設定します。 * entry が NULL の場合、何もしません。 * * @param entry メモリエントリ * @param size メモリサイズ * @param mark メモリ状態 * @param file メモリ確保ファイル名 * @param func メモリ確保関数名 * @param line メモリ確保行番号 */ void KcMemoryEntry_set(KcMemoryEntry *entry, size_t size, KcMemoryMark mark, const char *file, const char *func, int line) { if (entry != NULL) { entry->size = size; entry->mark = mark; entry->file = file; entry->func = func; entry->line = line; entry->_prev = NULL; entry->_next = NULL; entry->data = (entry + 1); } }