Compare commits
3 commits
1765cf676e
...
e33bbcb4f7
Author | SHA1 | Date | |
---|---|---|---|
|
e33bbcb4f7 | ||
|
ddb67325c4 | ||
|
85e68c9abb |
4 changed files with 128 additions and 95 deletions
|
@ -118,7 +118,7 @@ IncludeIsMainSourceRegex: ''
|
||||||
IndentAccessModifiers: false
|
IndentAccessModifiers: false
|
||||||
IndentCaseBlocks: false
|
IndentCaseBlocks: false
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
IndentExternBlock: AfterExternBlock
|
IndentExternBlock: NoIndent
|
||||||
IndentGotoLabels: true
|
IndentGotoLabels: true
|
||||||
IndentPPDirectives: None
|
IndentPPDirectives: None
|
||||||
IndentRequiresClause: true
|
IndentRequiresClause: true
|
||||||
|
|
|
@ -13,6 +13,11 @@
|
||||||
namespace mesytec::mnode::mana
|
namespace mesytec::mnode::mana
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template <typename T> inline bool is_aligned(const T *ptr, size_t alignment = alignof(T))
|
||||||
|
{
|
||||||
|
return (((uintptr_t)ptr) % alignment) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
class Arena
|
class Arena
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -26,16 +31,11 @@ class Arena
|
||||||
Arena(Arena &&other) = default;
|
Arena(Arena &&other) = default;
|
||||||
Arena &operator=(Arena &&other) = default;
|
Arena &operator=(Arena &&other) = default;
|
||||||
|
|
||||||
// pushes at least the required amount of memory onto the arena.
|
// Pushes at least the required amount of memory onto the arena. The memory is aligned to
|
||||||
// 'required' is rounded up to the nearest multiple of 'default_align_to' to make
|
// 'default_align_to' and zeroed
|
||||||
// subsequent allocations aligned.
|
|
||||||
u8 *push_size(size_t required)
|
u8 *push_size(size_t required)
|
||||||
{
|
{
|
||||||
size_t padded = round_up(required, default_align_to);
|
if (!segment_)
|
||||||
size_t pad_waste = padded - required;
|
|
||||||
required = padded;
|
|
||||||
|
|
||||||
if (!segment_ || segment_->free() < required)
|
|
||||||
{
|
{
|
||||||
if (segment_count() < max_segments())
|
if (segment_count() < max_segments())
|
||||||
{
|
{
|
||||||
|
@ -52,12 +52,20 @@ class Arena
|
||||||
|
|
||||||
assert(segment_ && segment_->free() >= required);
|
assert(segment_ && segment_->free() >= required);
|
||||||
|
|
||||||
auto result = segment_->cur();
|
void *ptr = segment_->cur();
|
||||||
std::memset(result, 0, required);
|
size_t space = segment_->free();
|
||||||
segment_->used += required;
|
if (!std::align(default_align_to, required, ptr, space))
|
||||||
++allocations_;
|
throw std::bad_alloc();
|
||||||
|
|
||||||
|
assert(is_aligned(ptr, default_align_to));
|
||||||
|
|
||||||
|
size_t pad_waste = segment_->free() - space;
|
||||||
|
segment_->used += required + pad_waste;
|
||||||
pad_waste_ += pad_waste;
|
pad_waste_ += pad_waste;
|
||||||
return result;
|
++allocations_;
|
||||||
|
|
||||||
|
std::memset(ptr, 0, required);
|
||||||
|
return reinterpret_cast<u8 *>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> T *push_t(size_t count = 1)
|
template <typename T> T *push_t(size_t count = 1)
|
||||||
|
|
|
@ -9,42 +9,55 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
mana_custom,
|
mana_custom,
|
||||||
mana_uint8,
|
mana_uint8,
|
||||||
mana_sint8,
|
mana_sint8,
|
||||||
mana_uint16,
|
mana_uint16,
|
||||||
mana_uint32,
|
mana_sint16,
|
||||||
mana_uint64,
|
mana_uint32,
|
||||||
mana_float,
|
mana_sint32,
|
||||||
mana_double,
|
mana_uint64,
|
||||||
} mana_data_type_t;
|
mana_sint64,
|
||||||
|
mana_float,
|
||||||
|
mana_double,
|
||||||
|
} mana_data_type_t;
|
||||||
|
|
||||||
typedef struct
|
// Offset based pointer. Allows to memcpy() structures with these pointers
|
||||||
{
|
// inside as long as the range covered by the pointers is also copied.
|
||||||
mana_data_type_t data_type;
|
//
|
||||||
ptrdiff_t offset;
|
// Raw pointer value is '&ptr + offset'. nullptr is defined as offset=1.
|
||||||
} mana_offset_ptr_t;
|
// => Cannot point to the first byte of the struct itself but that's fine.
|
||||||
|
// Do not create temporaries of these. The offset will then be relative to the
|
||||||
|
// temporary on the stack! Do not copy these unless you copy the full memory
|
||||||
|
// range so that the offset_ptr_t in the new location stays valid.
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mana_data_type_t data_type;
|
||||||
|
ptrdiff_t offset;
|
||||||
|
} mana_offset_ptr_t;
|
||||||
|
|
||||||
typedef struct
|
// Typed offset pointer based array. Stores the array size in bytes instead of
|
||||||
{
|
// elements to allow storing any type using mana_custom.
|
||||||
mana_offset_ptr_t ptr;
|
typedef struct
|
||||||
size_t size_bytes;
|
{
|
||||||
} mana_offset_array_t;
|
mana_offset_ptr_t ptr;
|
||||||
|
size_t size_bytes;
|
||||||
|
} mana_offset_array_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
mana_status_ok,
|
mana_status_ok,
|
||||||
mana_status_invalid_argument,
|
mana_status_invalid_argument,
|
||||||
mana_status_internal_error,
|
mana_status_internal_error,
|
||||||
} mana_status_code_t;
|
} mana_status_code_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
mana_status_code_t code;
|
mana_status_code_t code;
|
||||||
char message[256];
|
char message[256];
|
||||||
} mana_status_t;
|
} mana_status_t;
|
||||||
|
|
||||||
#define MANA_DEFINE_PLUGIN_INIT(name) void *name(int plugin_argc, const char **plugin_argv)
|
#define MANA_DEFINE_PLUGIN_INIT(name) void *name(int plugin_argc, const char **plugin_argv)
|
||||||
|
|
||||||
|
@ -63,22 +76,22 @@ extern "C"
|
||||||
#define MANA_DEFINE_PLUGIN_SYSTEM_EVENT(name) \
|
#define MANA_DEFINE_PLUGIN_SYSTEM_EVENT(name) \
|
||||||
void name(void *context, const uint32_t *data, size_t size)
|
void name(void *context, const uint32_t *data, size_t size)
|
||||||
|
|
||||||
typedef MANA_DEFINE_PLUGIN_INIT(mana_init_t);
|
typedef MANA_DEFINE_PLUGIN_INIT(mana_init_t);
|
||||||
typedef MANA_DEFINE_PLUGIN_SHUTDOWN(mana_shutdown_t);
|
typedef MANA_DEFINE_PLUGIN_SHUTDOWN(mana_shutdown_t);
|
||||||
typedef MANA_DEFINE_PLUGIN_BEGIN_RUN(mana_begin_run_t);
|
typedef MANA_DEFINE_PLUGIN_BEGIN_RUN(mana_begin_run_t);
|
||||||
typedef MANA_DEFINE_PLUGIN_END_RUN(mana_end_run_t);
|
typedef MANA_DEFINE_PLUGIN_END_RUN(mana_end_run_t);
|
||||||
typedef MANA_DEFINE_PLUGIN_EVENT_DATA(mana_process_event_t);
|
typedef MANA_DEFINE_PLUGIN_EVENT_DATA(mana_process_event_t);
|
||||||
typedef MANA_DEFINE_PLUGIN_SYSTEM_EVENT(mana_process_system_event_t);
|
typedef MANA_DEFINE_PLUGIN_SYSTEM_EVENT(mana_process_system_event_t);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
mana_init_t *init;
|
mana_init_t *init;
|
||||||
mana_shutdown_t *shutdown;
|
mana_shutdown_t *shutdown;
|
||||||
mana_begin_run_t *begin_run;
|
mana_begin_run_t *begin_run;
|
||||||
mana_end_run_t *end_run;
|
mana_end_run_t *end_run;
|
||||||
mana_process_event_t *process_event;
|
mana_process_event_t *process_event;
|
||||||
mana_process_system_event_t *process_system_event;
|
mana_process_system_event_t *process_system_event;
|
||||||
} mana_sink_plugin_t;
|
} mana_sink_plugin_t;
|
||||||
|
|
||||||
// use this to define the entry point into the plugin
|
// use this to define the entry point into the plugin
|
||||||
// from c++: extern "C" MANA_C_SINK_PLUGIN() { ... return plugin; }
|
// from c++: extern "C" MANA_C_SINK_PLUGIN() { ... return plugin; }
|
||||||
|
|
|
@ -16,8 +16,11 @@
|
||||||
namespace mesytec::mnode::mana
|
namespace mesytec::mnode::mana
|
||||||
{
|
{
|
||||||
|
|
||||||
|
inline bool is_null(const mana_offset_ptr_t &ptr) { return ptr.offset == 1; }
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
inline void set(mana_offset_ptr_t &ptr, void *p)
|
inline void set(mana_offset_ptr_t &ptr, void *p)
|
||||||
{
|
{
|
||||||
assert(p != reinterpret_cast<u8 *>(&ptr) + 1);
|
assert(p != reinterpret_cast<u8 *>(&ptr) + 1);
|
||||||
|
@ -33,31 +36,6 @@ inline void set(mana_offset_ptr_t &ptr, void *p)
|
||||||
ptr.offset = 1;
|
ptr.offset = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
inline bool is_null(const mana_offset_ptr_t &ptr) { return ptr.offset == 1; }
|
|
||||||
|
|
||||||
inline void *get(mana_offset_ptr_t &ptr)
|
|
||||||
{
|
|
||||||
return is_null(ptr) ? nullptr : reinterpret_cast<u8 *>(&ptr) + ptr.offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> T *get(mana_offset_ptr_t &ptr); // to catch unsupported types
|
|
||||||
|
|
||||||
template <typename T> T *get_(mana_offset_ptr_t &ptr, mana_data_type_t expected)
|
|
||||||
{
|
|
||||||
if (ptr.data_type != expected)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return reinterpret_cast<T *>(get(ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> u32 *get(mana_offset_ptr_t &ptr) { return get_<u32>(ptr, mana_uint32); }
|
|
||||||
template <> u64 *get(mana_offset_ptr_t &ptr) { return get_<u64>(ptr, mana_uint64); }
|
|
||||||
template <> s8 *get(mana_offset_ptr_t &ptr) { return get_<s8>(ptr, mana_sint8); }
|
|
||||||
template <> char *get(mana_offset_ptr_t &ptr) { return get_<char>(ptr, mana_sint8); }
|
|
||||||
template <> float *get(mana_offset_ptr_t &ptr) { return get_<float>(ptr, mana_float); }
|
|
||||||
template <> double *get(mana_offset_ptr_t &ptr) { return get_<double>(ptr, mana_double); }
|
|
||||||
|
|
||||||
inline void set(mana_offset_ptr_t &ptr, mana_data_type_t data_type, void *p)
|
inline void set(mana_offset_ptr_t &ptr, mana_data_type_t data_type, void *p)
|
||||||
{
|
{
|
||||||
|
@ -65,13 +43,47 @@ inline void set(mana_offset_ptr_t &ptr, mana_data_type_t data_type, void *p)
|
||||||
detail::set(ptr, p);
|
detail::set(ptr, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set(mana_offset_ptr_t &ptr, std::nullptr_t) { set(ptr, mana_uint32, nullptr); }
|
inline void *get(mana_offset_ptr_t &ptr)
|
||||||
inline void set(mana_offset_ptr_t &ptr, u32 *p) { set(ptr, mana_uint32, p); }
|
{
|
||||||
inline void set(mana_offset_ptr_t &ptr, u64 *p) { set(ptr, mana_uint64, p); }
|
return is_null(ptr) ? nullptr : reinterpret_cast<u8 *>(&ptr) + ptr.offset;
|
||||||
inline void set(mana_offset_ptr_t &ptr, s8 *p) { set(ptr, mana_sint8, p); }
|
}
|
||||||
inline void set(mana_offset_ptr_t &ptr, char *p) { set(ptr, mana_sint8, p); }
|
|
||||||
inline void set(mana_offset_ptr_t &ptr, float *p) { set(ptr, mana_float, p); }
|
template <typename T> T *get(mana_offset_ptr_t &ptr, mana_data_type_t expected)
|
||||||
inline void set(mana_offset_ptr_t &ptr, double *p) { set(ptr, mana_double, p); }
|
{
|
||||||
|
if (ptr.data_type != expected)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return reinterpret_cast<T *>(get(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T> T *get(mana_offset_ptr_t &ptr); // to catch unsupported types
|
||||||
|
|
||||||
|
template <> u32 *get(mana_offset_ptr_t &ptr) { return detail::get<u32>(ptr, mana_uint32); }
|
||||||
|
template <> u64 *get(mana_offset_ptr_t &ptr) { return detail::get<u64>(ptr, mana_uint64); }
|
||||||
|
template <> s8 *get(mana_offset_ptr_t &ptr) { return detail::get<s8>(ptr, mana_sint8); }
|
||||||
|
template <> char *get(mana_offset_ptr_t &ptr) { return detail::get<char>(ptr, mana_sint8); }
|
||||||
|
template <> float *get(mana_offset_ptr_t &ptr) { return detail::get<float>(ptr, mana_float); }
|
||||||
|
template <> double *get(mana_offset_ptr_t &ptr) { return detail::get<double>(ptr, mana_double); }
|
||||||
|
|
||||||
|
// To make 'set(ptr, nullptr)' work.
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, std::nullptr_t)
|
||||||
|
{
|
||||||
|
detail::set(ptr, ptr.data_type, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, u8 *p) { detail::set(ptr, mana_uint8, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, s8 *p) { detail::set(ptr, mana_sint8, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, char *p) { detail::set(ptr, mana_sint8, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, u16 *p) { detail::set(ptr, mana_uint16, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, s16 *p) { detail::set(ptr, mana_sint16, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, u32 *p) { detail::set(ptr, mana_uint32, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, s32 *p) { detail::set(ptr, mana_sint32, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, u64 *p) { detail::set(ptr, mana_uint64, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, s64 *p) { detail::set(ptr, mana_sint64, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, float *p) { detail::set(ptr, mana_float, p); }
|
||||||
|
inline void set(mana_offset_ptr_t &ptr, double *p) { detail::set(ptr, mana_double, p); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T *push_offset_array(mana::Arena &arena, mana_offset_array_t &dest, size_t size)
|
T *push_offset_array(mana::Arena &arena, mana_offset_array_t &dest, size_t size)
|
||||||
|
@ -86,7 +98,7 @@ template <typename T>
|
||||||
T *push_typed_offset_array(mana::Arena &arena, mana_offset_array_t &dest, size_t size)
|
T *push_typed_offset_array(mana::Arena &arena, mana_offset_array_t &dest, size_t size)
|
||||||
{
|
{
|
||||||
T *ptr = arena.push_t<T>(size);
|
T *ptr = arena.push_t<T>(size);
|
||||||
mana::set(dest.ptr, ptr);
|
set(dest.ptr, ptr);
|
||||||
dest.size_bytes = size * sizeof(T);
|
dest.size_bytes = size * sizeof(T);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +110,7 @@ template <typename T> size_t element_count(mana_offset_array_t &array)
|
||||||
|
|
||||||
template <typename T> mvlc::util::span<T> get_span(mana_offset_array_t &array)
|
template <typename T> mvlc::util::span<T> get_span(mana_offset_array_t &array)
|
||||||
{
|
{
|
||||||
auto ptr = reinterpret_cast<T *>(get(array.ptr));
|
auto ptr = get<T>(array.ptr);
|
||||||
auto size = element_count<T>(array);
|
auto size = element_count<T>(array);
|
||||||
return {ptr, size};
|
return {ptr, size};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue