195 lines
2.5 KiB
D
195 lines
2.5 KiB
D
import std.stdio;
|
|
import core.stdc.string : memset;
|
|
|
|
alias i8 = byte;
|
|
alias i16 = short;
|
|
alias i32 = int;
|
|
alias i64 = long;
|
|
|
|
alias u8 = ubyte;
|
|
alias u16 = ushort;
|
|
alias u32 = uint;
|
|
alias u64 = ulong;
|
|
|
|
alias f32 = float;
|
|
alias f64 = double;
|
|
|
|
alias b32 = uint;
|
|
|
|
alias usize = size_t;
|
|
|
|
const DEFAULT_ALIGNMENT = (void *).sizeof * 2;
|
|
|
|
version(linux)
|
|
{
|
|
import core.sys.posix.sys.mman;
|
|
|
|
void*
|
|
MemAlloc(u64 size)
|
|
{
|
|
return mmap(null, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
|
|
}
|
|
|
|
void
|
|
MemFree(void* ptr, u64 size)
|
|
{
|
|
assert(munmap(ptr, size) == 0, "MemFree failure");
|
|
}
|
|
|
|
}
|
|
|
|
bool
|
|
BitEq(u64 l, u64 r)
|
|
{
|
|
return (l & r) == r;
|
|
}
|
|
|
|
void
|
|
Logf(Args...)(string fmt, Args args)
|
|
{
|
|
try
|
|
{
|
|
writefln(fmt, args);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
assert(false, "Incompatible format type");
|
|
}
|
|
}
|
|
|
|
void
|
|
Log(string str)
|
|
{
|
|
writeln(str);
|
|
}
|
|
|
|
void
|
|
Log(char* str)
|
|
{
|
|
writeln(str);
|
|
}
|
|
|
|
u64
|
|
KB(u64 v)
|
|
{
|
|
return v * 1024;
|
|
};
|
|
|
|
u64
|
|
MB(u64 v)
|
|
{
|
|
return KB(v) * 1024;
|
|
};
|
|
|
|
u64
|
|
GB(u64 v)
|
|
{
|
|
return MB(v) * 1024;
|
|
};
|
|
|
|
struct Node(T)
|
|
{
|
|
Node!(T)* next;
|
|
T value;
|
|
}
|
|
|
|
struct SLList(T)
|
|
{
|
|
Node!(T)* first;
|
|
Node!(T)* last;
|
|
}
|
|
|
|
pragma(inline): void
|
|
Push(T)(SLList!(T)*list, Node!(T)* node, Node!(T)* nil)
|
|
{
|
|
if (CheckNil(nil, list.first))
|
|
{
|
|
list.first = list.last = node;
|
|
node.next = nil;
|
|
}
|
|
else
|
|
{
|
|
list.last.next = node;
|
|
list.last = node;
|
|
node.next = nil;
|
|
}
|
|
}
|
|
|
|
pragma(inline): bool
|
|
CheckNil(T)(Node!(T)* nil, Node!(T)* node)
|
|
{
|
|
return node == null || node == nil;
|
|
}
|
|
|
|
struct Arena
|
|
{
|
|
u8* mem;
|
|
u64 length;
|
|
u64 pos;
|
|
};
|
|
|
|
Arena
|
|
CreateArena(u64 size)
|
|
{
|
|
Arena arena = {
|
|
mem: cast(u8 *)MemAlloc(size),
|
|
length: size,
|
|
pos: 0,
|
|
};
|
|
|
|
assert(arena.mem != null, "Unable to allocate memory for arena");
|
|
|
|
return arena;
|
|
};
|
|
|
|
T[]
|
|
AllocArray(T)(Arena* arena, u64 count)
|
|
{
|
|
void* mem = AllocAlign(arena, T.sizeof * count, DEFAULT_ALIGNMENT);
|
|
memset(mem, 0, T.sizeof * count);
|
|
return (cast(T*)mem)[0 .. count];
|
|
}
|
|
|
|
T*
|
|
Alloc(T)(Arena* arena)
|
|
{
|
|
void* mem = AllocAlign(arena, T.sizeof, DEFAULT_ALIGNMENT);
|
|
memset(mem, 0, T.sizeof);
|
|
return cast(T*)mem;
|
|
};
|
|
|
|
void*
|
|
AllocAlign(Arena* arena, u64 size, u64 alignment)
|
|
{
|
|
void* ptr = null;
|
|
|
|
uintptr mem_pos = cast(uintptr)arena.mem;
|
|
uintptr current = mem_pos + arena.pos;
|
|
uintptr offset = AlignPow2(current, alignment) - mem_pos;
|
|
|
|
if (offset+size <= arena.length)
|
|
{
|
|
ptr = &arena.mem[offset];
|
|
arena.pos = offset+size;
|
|
}
|
|
else
|
|
{
|
|
writefln("AllocAlign failure: out of memory, size requested: %s", size);
|
|
assert(0);
|
|
}
|
|
|
|
return ptr;
|
|
};
|
|
|
|
void
|
|
Reset(Arena* arena)
|
|
{
|
|
arena.pos = 0;
|
|
}
|
|
|
|
void
|
|
Free(Arena* arena)
|
|
{
|
|
(arena.mem);
|
|
}
|