[ox/std] Add MallocaPtr

This commit is contained in:
Gary Talent 2018-05-03 01:09:17 -05:00
parent 85a98222d4
commit ecbeabff48
5 changed files with 100 additions and 15 deletions

View File

@ -135,7 +135,7 @@ Error Directory<InodeId_t>::write(PathIterator path, InodeId_t inode) noexcept {
auto old = m_fs->read(m_inodeId); auto old = m_fs->read(m_inodeId);
if (old.valid()) { if (old.valid()) {
const auto newSize = m_size + DirectoryEntry<InodeId_t>::spaceNeeded(name.size()); const auto newSize = m_size + DirectoryEntry<InodeId_t>::spaceNeeded(name.size());
auto cpy = new (ox_malloca(newSize)) Buffer(old); auto cpy = ox_malloca(newSize, Buffer, old);
cpy->setSize(newSize); cpy->setSize(newSize);
auto val = cpy->malloc(name.size()); auto val = cpy->malloc(name.size());
if (val.valid()) { if (val.valid()) {

View File

@ -337,8 +337,7 @@ map<string, int(*)(string)> tests = {
"Ptr::subPtr", "Ptr::subPtr",
[](string) { [](string) {
constexpr auto buffLen = 5000; constexpr auto buffLen = 5000;
uint8_t buff[buffLen]; ox::ptrarith::Ptr<uint8_t, uint32_t> p(ox_alloca(buffLen), buffLen, 500, 500);
ox::ptrarith::Ptr<uint8_t, uint32_t> p(buff, buffLen, 500, 500);
oxAssert(p.valid(), "Ptr::subPtr: Ptr p is invalid."); oxAssert(p.valid(), "Ptr::subPtr: Ptr p is invalid.");
auto subPtr = p.subPtr<uint64_t>(50); auto subPtr = p.subPtr<uint64_t>(50);
@ -351,8 +350,7 @@ map<string, int(*)(string)> tests = {
[](string) { [](string) {
int err = 0; int err = 0;
constexpr auto buffLen = 5000; constexpr auto buffLen = 5000;
uint8_t buff[buffLen]; auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
auto list = new (buff) ox::ptrarith::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
oxAssert(list->malloc(50).valid(), "NodeBuffer::insert: malloc 1 failed"); oxAssert(list->malloc(50).valid(), "NodeBuffer::insert: malloc 1 failed");
oxAssert(list->malloc(50).valid(), "NodeBuffer::insert: malloc 2 failed"); oxAssert(list->malloc(50).valid(), "NodeBuffer::insert: malloc 2 failed");
auto first = list->firstItem(); auto first = list->firstItem();
@ -369,8 +367,7 @@ map<string, int(*)(string)> tests = {
constexpr auto str1Len = ox_strlen(str1) + 1; constexpr auto str1Len = ox_strlen(str1) + 1;
constexpr auto str2 = "Hello, Moon!"; constexpr auto str2 = "Hello, Moon!";
constexpr auto str2Len = ox_strlen(str2) + 1; constexpr auto str2Len = ox_strlen(str2) + 1;
uint8_t buff[buffLen]; auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
auto list = new (buff) ox::ptrarith::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
ox::fs::FileStore32 fileStore(list, buffLen); ox::fs::FileStore32 fileStore(list, buffLen);
oxAssert(fileStore.format() == 0, "FileStore::format failed."); oxAssert(fileStore.format() == 0, "FileStore::format failed.");
oxAssert(fileStore.write(4, const_cast<char*>(str1), str1Len, 1) == 0, "FileStore::write 1 failed."); oxAssert(fileStore.write(4, const_cast<char*>(str1), str1Len, 1) == 0, "FileStore::write 1 failed.");

View File

@ -5,6 +5,7 @@ add_library(
assert.cpp assert.cpp
byteswap.cpp byteswap.cpp
memops.cpp memops.cpp
new.cpp
random.cpp random.cpp
strops.cpp strops.cpp
) )

15
deps/ox/src/ox/std/new.cpp vendored Normal file
View File

@ -0,0 +1,15 @@
/*
* Copyright 2015 - 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "new.hpp"
namespace ox {
template class MallocaPtr<int>;
}

View File

@ -8,6 +8,8 @@
#pragma once #pragma once
#include <ox/__buildinfo/defines.hpp>
#include "types.hpp" #include "types.hpp"
#if defined(_MSC_VER) #if defined(_MSC_VER)
@ -22,25 +24,95 @@
#endif #endif
void *operator new(std::size_t, void*) noexcept;
namespace ox { namespace ox {
constexpr auto MaxAllocaSize = 10 * 1024; constexpr auto MallocaStackLimit = 1024;
} }
#if defined(OX_USE_STDLIB) #if defined(OX_USE_STDLIB)
#define ox_malloca(size) size > MaxAllocaSize ? malloc(size) : ox_alloca(size) #define ox_malloca(size, Type, ...) ox::MallocaPtr<Type>(size, new (size > MallocaStackLimit ? new uint8_t[size] : ox_alloca(size)) Type(__VA_ARGS__))
#else #else
#define ox_malloca(size) ox_alloca(size) #define ox_malloca(size, Type, ...) ox::MallocaPtr<Type>(size, ox_alloca(size))
#endif #endif
inline void ox_freea(std::size_t size, void *ptr) { inline constexpr void ox_freea(std::size_t size, void *ptr) {
if constexpr(ox::defines::UseStdLib) { if constexpr(ox::defines::UseStdLib) {
if (size > ox::MaxAllocaSize) { if (size > ox::MallocaStackLimit) {
free(ptr); delete[] reinterpret_cast<uint8_t*>(ptr);
} }
} }
} }
void* operator new(std::size_t, void*) noexcept; namespace ox {
template<typename T>
class MallocaPtr {
private:
std::size_t m_size = 0;
T *m_val = nullptr;
public:
inline MallocaPtr() noexcept = default;
inline MallocaPtr(MallocaPtr &&other) noexcept {
m_size = other.m_size;
m_val = other.m_val;
other.m_size = 0;
}
inline MallocaPtr(std::size_t size, T *val) noexcept {
m_size = size;
m_val = val;
}
inline ~MallocaPtr() noexcept {
if constexpr(ox::defines::UseStdLib) {
if (m_size > ox::MallocaStackLimit) {
delete[] reinterpret_cast<uint8_t*>(m_val);
}
}
}
inline const T *operator->() const noexcept {
return reinterpret_cast<T*>(m_val);
}
inline T *operator->() noexcept {
return reinterpret_cast<T*>(m_val);
}
inline operator const T*() const noexcept {
return reinterpret_cast<T*>(m_val);
}
inline operator T*() noexcept {
return reinterpret_cast<T*>(m_val);
}
inline const T &operator*() const noexcept {
return *reinterpret_cast<T*>(m_val);
}
inline T &operator*() noexcept {
return *reinterpret_cast<T*>(m_val);
}
inline bool operator==(const MallocaPtr<T> &other) const noexcept {
return m_val == other.m_val && m_size == other.m_size;
}
inline bool operator!=(const MallocaPtr<T> &other) const noexcept {
return m_val != other.m_val || m_size != other.m_size;
}
};
extern template class MallocaPtr<int>;
}