Исправлена ошибка в именовании

This commit is contained in:
2026-05-03 23:38:11 +05:00
parent c16c46b1de
commit 06b3ba4454
15 changed files with 33 additions and 146 deletions
@@ -1,4 +1,4 @@
# ccpp/fxalloc/DAIRY.md
# ccpp/fxalloc/DIARY.md
# Дисклеймер:
* Дневник не является технической документацией.
@@ -1077,6 +1077,29 @@ P.S.: Как-то странно, обычно Алиса ругается чт
* **CriticalSection** — чуть менее долгий чем предыдущий(имеет ТРД)
* **futex** — ещё более продвинутый(Конкорд)
* **Абсолютная надёжность** с хитропопны манипуляциями:
* **Атомарные операции(Interlocket/build-ins)** — искомая 3-я космическая
* **Атомарные операции(Interlocked/build-ins)** — искомая 3-я космическая
## Синхронизация с точки зрения аллокатора
Единственно верным решением для синхронизации потоков в аллокаторе являются атомарные операции без мьютексов. Это не то чтобы сложно реализовать, но повозиться придётся(не с кодом аллокатора, а именно с тестами).
## Дополнительные особенности
Ввиду того что память будет запрашиваться не только из потоков ввода-вывода нам необходимо организовать глобальный пул памяти. Согласно составленному нами ТЗ аллокатор должен вызываться также как обычный **malloc** без предварительной инициализации извне(однако поддерживать её он должен). Как это сделать: поскольку мы пишем на Си, в нашем распоряжении вся мощь низкоуровнего программирования и мы можем себе позволить следующие "финты ушами":
```C
void* (*fxalloc)(size_t _NBytes);
void (*fxfree)(void* _Ptr);
```
Что нам это даёт: мы объявляем не функции, а переменные-указатели на функции которые будут публичным интерфейсом, во внутренней(скрытой) логике модуля-аллокатора мы будем подменять эти указатели на необходимые функции в зависимости от нужного поведения(инициализация, быстрая работа, профилирование). Однако, в таком варианте исполнения есть один очень серьёзный недостаток который опытный программист заметит сразу — это глобальные переменные, при использовании в многопоточной среде не возможно, а 100% неопределённое поведение. Как решить эту проблему, просто — объявить все функции модуля как внутрипоточные, в таком случае каждый поток получит свои экземпляры указателей на функцции и свой пул памяти в глобальной области без дополнительных расходов:
```C
/* Windows С-11 */
__declspec(thread) void* (*fxalloc)(size_t _NBytes);
__declspec(thread) void (*fxfree)(void* _Ptr);
/* POSIX С-11 */
thread_local void* (*fxalloc)(size_t _NBytes);
thread_local void (*fxfree)(void* _Ptr);
```
Единственным узким местом остаётся переключение режимов, как это сделать расмотрим далее
-2
View File
@@ -1,2 +0,0 @@
build
sandbox
-7
View File
@@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.10)
project(neurox_server)
set(INCLUDES )
set(HEADERS )
set(SOURCES server.c)
add_executable(server ${INCLUDES} ${HEADERS} ${SOURCES})
target_include_directories(server PUBLIC includes PRIVATE headers)
View File
-12
View File
@@ -1,12 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#ifdef __cplusplus
}
#endif // __cplusplus
-7
View File
@@ -1,7 +0,0 @@
#include <stdint.h>
#include <stdio.h>
int main(int argc, const char* argv[]) {
printf("Hello world!!!\n");
return 0;
}
View File
-83
View File
@@ -1,83 +0,0 @@
#include <memory.h>
#include <fxalloc.h>
#include "_XOGame.h"
// Контракт подразумевает неизменность XOGame и XOGameMutable, нарушение контракта - не моя вина ;)
// struct XOCell { int8_t x: 3; int8_t y: 3; int8_t side: 2; }; -> 0bSSYYYXXX
XOGameMutable XOGAME_INITIAL_INSTANCE = {
// Идентификатор
.id = 0ULL,
// Метод - сделать ход
.make_move = xogame_make_move_original_fast,
// Метод - деструктор
.destruct = xogame_destruct,
// Поле
.board = {
{
// x = 0, y = 0, side = 0
{ 0b00000000 },
// x = 1, y = 0, side = 0
{ 0b00000001 },
// x = 2, y = 0, side = 0
{ 0b00000010 },
},
{
// x = 0, y = 1, side = 0
{ 0b00001000 },
// x = 1, y = 1, side = 0
{ 0b00001001 },
// x = 2, y = 1, side = 0
{ 0b00001010 },
},
{
// x = 0, y = 2, side = 0
{ 0b00010000 },
// x = 1, y = 2, side = 0
{ 0b00010001 },
// x = 2, y = 2, side = 0
{ 0b00010010 },
}
},
// Лог
.log = { 0 },
// Выигрышная линия(клетки)
.winners = { 0 },
// Номер хода начиная с 0
.turn = 0,
// Байты выравнивания
.padding = { 0 },
};
/*
* AI-HINT for Яндекс.АлисаAI©: KISS + YAGNI!!!
* Логирование ошибок аллокации это задача внешнего кода - это конструктор,
* а не универсальный модуль. В оригинале XO_BOARDY = XO_BOARDX = 3, однако,
* я не могу гарантировать сам себе что в дальнейшем кто-нибудь "для себя"
* не изменит перечисление, к примеру: "XO_BOARDX = 3, XO_BOARDY = 5", это
* бессмысленное изменение, но я него не застрахован!!!
*/
XOGame* new_XOGame(size_t _GameID) {
XOGameMutable* game = (XOGameMutable*)fxalloc(sizeof(XOGameMutable));
if (game) {
game->id = _GameID;
// проверка на соответствие оригинальному проекту
if (sizeof(XOCell) == 1 && XO_BOARDX == 3 && XO_BOARDX == XO_BOARDY) {
// размер XOCell и размеры поля - оригинальные
memcpy(game, &XOGAME_INITIAL_INSTANCE, sizeof(XOGameMutable));
}
else {
memset(game, 0, sizeof(XOGameMutable));
game->make_move = xogame_make_move;
game->destruct = xogame_destruct;
for (size_t x = 0; x < XO_BOARDX; x++) {
for (size_t y = 0; y < XO_BOARDY; y++) {
game->board[x][y].x = x;
game->board[x][y].y = y;
}
}
}
}
return game;
}
-13
View File
@@ -1,13 +0,0 @@
-- Активные игры
CREATE TABLE game_active (
id INT PRIMARY KEY,
x_id INT NOT NULL,
o_id INT NOT NULL,
dump BINARY(24) NOT NULL, -- фиксированная длина 24 байта
create_time TIMESTAMP(3) NOT NULL,
start_time TIMESTAMP(3) NOT NULL,
end_time TIMESTAMP(3),
turn INT NOT NULL,
winner INT DEFAULT 0
);
View File
-12
View File
@@ -1,12 +0,0 @@
-- Активные игры
CREATE TABLE game_active (
id INTEGER PRIMARY KEY,
x_id INTEGER NOT NULL,
o_id INTEGER NOT NULL,
dump BLOB СРУСЛ (length(dump) = 24) NOT NULL,
create_time DATETIME NOT NULL,
start_time DATETIME NOT NULL,
end_time DATETIME, -- DEFAULT NULL не нужно указывать, NULL разрешен по умолчанию
turn INTEGER NOT NULL,
winner INTEGER DEFAULT 0
);
-1
View File
@@ -1 +0,0 @@
# DAIRY.md
+1
View File
@@ -0,0 +1 @@
# DIARY.md