Работа над документацией
This commit is contained in:
@@ -0,0 +1 @@
|
||||
sandbox
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cppbuild",
|
||||
"label": "C/C++: cl.exe build active file",
|
||||
"command": "cl.exe",
|
||||
"args": [
|
||||
"/Zi",
|
||||
"/EHsc",
|
||||
"/nologo",
|
||||
"/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",
|
||||
"${file}"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${fileDirname}"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$msCompile"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"detail": "Task generated by Debugger."
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
cmake_minimal_required(VERSION 3.10)
|
||||
project(neurox)
|
||||
set(SOURCES src/FXAlloc.c)
|
||||
set(HEADERS headers/_FXAlloc.h)
|
||||
set(INCLUDES includes/FXAlloc.h)
|
||||
add_library(fxalloc STATIC ${SOURCES} ${HEADERS} ${INCLUDES})
|
||||
target_include_directories(fxalloc PUBLIC includes PRIVATE headers)
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
/**
|
||||
* @brief Структура преднастройки аллокатора задающая градации и количество блоков памяти
|
||||
*
|
||||
* @property +est_size: size_t - Предполагаемый размер блока
|
||||
* @property +est_count: size_t - Предполагаемое количество блоков
|
||||
*/
|
||||
typedef struct FXGrade {
|
||||
/// Предполагаемый размер блока
|
||||
const size_t est_size;
|
||||
/// Предполагаемое количество блоков
|
||||
const size_t est_count;
|
||||
} FXGrade;
|
||||
|
||||
/**
|
||||
* @brief Переменная для сохранения преднастроек пула памяти с ноль-терминантом
|
||||
* Определена в src/FXAlloc.c
|
||||
*/
|
||||
extern const FXGrade* grades;
|
||||
|
||||
/**
|
||||
* @brief Функция выделения памяти
|
||||
* @param[in] _NBytes: size_t - Количество байт
|
||||
* @retval !0 - Кратный size_t указатель выровненный для любого типа данных
|
||||
* @retval NULL - В случае единственно возможной ошибки EBADALLOC результат сохранён в errno
|
||||
*/
|
||||
void* fxalloc(size_t _NBytes);
|
||||
|
||||
/**
|
||||
* @brief Высвобождает память выделенную исключительно fxalloc
|
||||
* @param[in] _Ptr: void*
|
||||
*/
|
||||
void fxfree(void* _Ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "FXAlloc.h"
|
||||
|
||||
#include "mword.h"
|
||||
|
||||
typedef struct FXMemoryBlock FXMemoryBlock;
|
||||
|
||||
/**
|
||||
* @brief Минимальная структурная единица - блок памяти
|
||||
* В памяти расположены друг за другом с гарантированным выравниванием по void*
|
||||
* Клиентский указатель указывает непосредственно за структуру
|
||||
* fxalloc() → return (void*)(block + 1);
|
||||
* fxfree() → FXMemoryBlock* block = (FXMemoryBlock*)_Ptr - 1;
|
||||
* @property next: FXMemoryBlock* - Указатель на следующий свободный блок
|
||||
* @property Индекс потока в глобальном пуле
|
||||
* @property Индекс грейда в пуле конкретного потока
|
||||
* */
|
||||
struct FXMemoryBlock {
|
||||
/// @brief Указатель на следующий свободный блок
|
||||
FXMemoryBlock* next;
|
||||
/// @brief Индекс потока в глобальном пуле
|
||||
umword_t tid;
|
||||
/// @brief Индекс грейда в пуле конкретного потока
|
||||
umword_t gid;
|
||||
};
|
||||
|
||||
struct FXMemoryBlock {
|
||||
/// @brief Указатель на следующий свободный блок
|
||||
FXMemoryBlock* next;
|
||||
/// @brief Индекс потока в глобальном пуле
|
||||
uint32_t tid;
|
||||
/// @brief Индекс грейда в пуле конкретного потока
|
||||
uint32_t gid;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Минимальная структурная единица - блок памяти
|
||||
* В памяти расположены друг за другом с гарантированным выравниванием по void*
|
||||
* Клиентский указатель указывает непосредственно за структуру
|
||||
* fxalloc() → return (void*)(block + 1);
|
||||
* fxfree() → FXMemoryBlock* block = (FXMemoryBlock*)_Ptr - 1;
|
||||
* @property next: FXMemoryBlock* - Указатель на следующий свободный блок
|
||||
* @property Индекс потока в глобальном пуле
|
||||
* @property Индекс грейда в пуле конкретного потока
|
||||
* */
|
||||
struct FXMemoryBlock {
|
||||
/// @brief Указатель на следующий свободный блок
|
||||
FXMemoryBlock* next;
|
||||
/// @brief Полезные данные в блоке
|
||||
uint32_t used;
|
||||
/// @brief Индекс потока в глобальном пуле
|
||||
uint16_t tid;
|
||||
/// @brief Индекс грейда в пуле конкретного потока
|
||||
uint16_t gid;
|
||||
};
|
||||
|
||||
/// @brief Группа блоков одной градации
|
||||
typedef struct FXGradedMemoryPool {
|
||||
/// @brief Указатель на последний свободный блок
|
||||
FXMemoryBlock* free;
|
||||
/// @brief Всего блоков в данной группе
|
||||
umword_t total;
|
||||
/// @brief Количество преаллоцированных блоков
|
||||
umword_t count_pre;
|
||||
/// @brief Количество используемых блоков
|
||||
mword_t used;
|
||||
/// @brief Количество свободных блоков
|
||||
mword_t free;
|
||||
} FXMemoryPoolGrade;
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef FX_MEMORY_BLOCK_H
|
||||
#define FX_MEMORY_BLOCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mword.h"
|
||||
|
||||
// Определяем оптимальный тип метаданных для FXMemoryBlock
|
||||
#if defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(__amd64__) || defined(__amd64) || \
|
||||
defined(__aarch64__) || defined(_M_ARM64) || \
|
||||
defined(__AARCH64__) || defined(__powerpc64__) || \
|
||||
defined(__ppc64__)
|
||||
// Для 64-битных архитектур используем uint32_t
|
||||
// для оптимального баланса между размером и производительностью
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
|
||||
#elif defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__i486__) || defined(__i586__) || \
|
||||
defined(__i686__) || defined(__arm__) || \
|
||||
defined(_M_ARM) || defined(__ARM_ARCH_7__) || \
|
||||
defined(__ARM_ARCH_8__) || defined(__powerpc__) || \
|
||||
defined(__ppc__)
|
||||
// Для 32-битных архитектур используем uint32_t
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
|
||||
#elif defined(__riscv)
|
||||
#if __riscv_xlen == 64
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
#elif __riscv_xlen == 32
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
#else
|
||||
#error "Unsupported RISC-V word size: __riscv_xlen must be 32 or 64"
|
||||
#endif
|
||||
|
||||
#else
|
||||
// Резервный вариант: определяем по размеру указателя
|
||||
#if sizeof(void*) == 8
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
#elif sizeof(void*) == 4
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
#else
|
||||
#error "Unsupported pointer size"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Проверка корректности определения типа
|
||||
static_assert(sizeof(fxmbmeta_t) == 4, "fxmbmeta_t must be 32-bit");
|
||||
|
||||
#endif // FX_MEMORY_BLOCK_H
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(__amd64__) || defined(__amd64)
|
||||
// x64: 64-битное машинное слово
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
|
||||
#elif defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__i486__) || defined(__i586__) || \
|
||||
defined(__i686__)
|
||||
// x86: 32-битное машинное слово
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64) || defined(__AARCH64__)
|
||||
// ARM64: 64-битное машинное слово
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
|
||||
#elif defined(__arm__) || defined(_M_ARM) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__)
|
||||
// ARM32: 32-битное машинное слово
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
|
||||
#elif defined(__riscv) && defined(__riscv_xlen)
|
||||
#if __riscv_xlen == 64
|
||||
// RISC‑V 64: 64-битное машинное слово
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
#elif __riscv_xlen == 32
|
||||
// RISC‑V 32: 32-битное машинное слово
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
#else
|
||||
#error "Unsupported RISC-V word size: __riscv_xlen must be 32 or 64"
|
||||
#endif
|
||||
|
||||
#elif defined(__powerpc64__) || defined(__ppc64__)
|
||||
// PowerPC64: 64-битное машинное слово
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
|
||||
#elif defined(__powerpc__) || defined(__ppc__)
|
||||
// PowerPC32: 32-битное машинное слово
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
|
||||
|
||||
#else
|
||||
// Резервный вариант: определяем по диапазону unsigned long
|
||||
#include <limits.h>
|
||||
#if ULONG_MAX == 18446744073709551615ULL // 2^64 - 1
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
#elif ULONG_MAX == 4294967295UL // 2^32 - 1
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
#elif ULONG_MAX == 65535U // 2^16 - 1
|
||||
typedef int16_t mword_t;
|
||||
typedef uint16_t umword_t;
|
||||
#else
|
||||
#error "Cannot determine machine word size: unsupported ULONG_MAX"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Проверки добавлены по настоянию YandexGPT 5.1 Pro(АлисаAI) */
|
||||
// Статическая проверка: размер слова — степень двойки
|
||||
static_assert((sizeof(mword_t) & (sizeof(mword_t) - 1)) == 0, "Machine word size must be a power of two");
|
||||
|
||||
// Статическая проверка: signed и unsigned версии имеют одинаковый размер
|
||||
static_assert(sizeof(mword_t) == sizeof(umword_t), "mword_t and umword_t must have the same size");
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "FXAlloc.h"
|
||||
|
||||
#include <threads.h>
|
||||
|
||||
// В этой переменной настраиваем градации и предположительное количесвто блоков
|
||||
static const FXGrade grades[] = {
|
||||
{ 32, 200 }, { 64, 200 }, { 128, 8000 },
|
||||
{ 256, 4000 }, { 512, 2000 }, { 1024, 1200 },
|
||||
{ 4096, 200 }, { 0x10000, 4 },
|
||||
{ 0 } // Ноль-терминант
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows-версия
|
||||
__declspec(thread) extern void* (*fxalloc)(size_t _NBytes);
|
||||
__declspec(thread) extern void (*fxfree)(void* _Ptr);
|
||||
#else
|
||||
// POSIX-версия
|
||||
extern static pthread_key_t thread_key;
|
||||
|
||||
extern void* (*fxalloc)(size_t _NBytes);
|
||||
extern void (*fxfree)(void* _Ptr);
|
||||
#endif
|
||||
|
||||
|
||||
extern static pthread_key_t thread_key;
|
||||
|
||||
void* fastalloc();
|
||||
|
||||
void init_tls() {
|
||||
pthread_setspecific(thread_key, (void*)fxalloc);
|
||||
fxalloc = fastalloc;
|
||||
// или более сложный вариант с хранением структуры
|
||||
}
|
||||
Reference in New Issue
Block a user