1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-29 04:55:58 +02:00
Beef/BeefLibs/corlib/src/Allocator.bf

128 lines
2.1 KiB
Beef
Raw Normal View History

2022-02-11 08:12:30 -05:00
using System.Reflection;
using System.Threading;
2020-06-16 10:33:52 -07:00
namespace System
{
interface IRawAllocator
{
void* Alloc(int size, int align) mut;
void Free(void* ptr) mut;
2020-06-16 10:33:52 -07:00
}
2022-06-29 07:18:01 -07:00
interface ITypedAllocator : IRawAllocator
{
void* AllocTyped(Type type, int size, int align) mut;
2022-06-29 07:18:01 -07:00
}
2020-06-16 10:33:52 -07:00
struct StdAllocator : IRawAllocator
{
public void* Alloc(int size, int align)
{
return Internal.StdMalloc(size);
}
public void Free(void* ptr)
{
Internal.StdFree(ptr);
}
}
2022-02-11 08:12:30 -05:00
2022-06-29 07:18:01 -07:00
class SingleAllocator : ITypedAllocator
{
void* mPtr;
int mSize;
Type mType;
[AllowAppend]
public this(int size)
{
void* ptr = append uint8[size]*(?);
mPtr = ptr;
mSize = size;
}
public ~this()
{
if ((mType != null) && (mType.IsObject))
{
Object obj = Internal.UnsafeCastToObject(mPtr);
delete:null obj;
}
if (mSize < 0)
delete mPtr;
}
protected virtual void* AllocLarge(int size, int align)
{
return new uint8[size]*;
}
protected virtual void FreeLarge(void* ptr)
{
delete ptr;
}
public void* Alloc(int size, int align)
{
return AllocTyped(typeof(void), size, align);
}
public void Free(void* ptr)
{
Runtime.Assert(ptr == mPtr);
mType = typeof(void);
}
[Optimize]
public void* AllocTyped(Type type, int size, int align)
{
Runtime.Assert(mType == null, "SingleAllocator has been used for multiple allocations");
mType = type;
do
{
2022-09-07 15:36:16 -07:00
if (size > mSize)
2022-06-29 07:18:01 -07:00
break;
void* usePtr = (void*)(int)Math.Align((int)mPtr, align);
if ((uint8*)usePtr + size > (uint8*)mPtr + mSize)
break;
mPtr = usePtr;
mSize = 0;
return mPtr;
}
mSize = -1;
mPtr = AllocLarge(size, align);
return mPtr;
}
}
2022-02-11 08:12:30 -05:00
struct AllocWrapper<T> where T : new, delete
{
alloctype(T) mVal;
public alloctype(T) Val
{
get mut
{
if (mVal != default)
return mVal;
var newVal = new T();
let prevValue = Interlocked.CompareExchange(ref mVal, default, newVal);
if (prevValue != default)
{
delete newVal;
return prevValue;
}
return newVal;
}
}
public void Dispose() mut
{
delete mVal;
mVal = default;
}
}
2020-06-16 10:33:52 -07:00
}
2022-02-11 08:12:30 -05:00