Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to allocate cache, dataset and VMs all at once #174

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ src/argon2_ref.c
src/argon2_ssse3.c
src/argon2_avx2.c
src/bytecode_machine.cpp
src/container.cpp
src/cpu.cpp
src/dataset.cpp
src/soft_aes.cpp
Expand Down
18 changes: 17 additions & 1 deletion src/allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,20 @@ namespace randomx {
freePagedMemory(ptr, count);
};

}
void* NullAllocator::allocMemory(size_t count) {
return nullptr;
}

void NullAllocator::freeMemory(void* ptr, size_t count) {

};

void* MonsterPageAllocator::allocMemory(size_t count) {
return allocMonsterPagesMemory(count);
}

void MonsterPageAllocator::freeMemory(void* ptr, size_t count) {
freePagedMemory(ptr, count);
};

}
11 changes: 10 additions & 1 deletion src/allocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,13 @@ namespace randomx {
static void freeMemory(void*, size_t);
};

}
struct NullAllocator {
static void* allocMemory(size_t);
static void freeMemory(void*, size_t);
};

struct MonsterPageAllocator {
static void* allocMemory(size_t);
static void freeMemory(void*, size_t);
};
}
164 changes: 164 additions & 0 deletions src/container.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
Copyright (c) 2019, tevador <[email protected]>

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "container.hpp"
#include "allocator.hpp"
#include "virtual_machine.hpp"
#include "virtual_memory.hpp"
#include "dataset.hpp"
#include "vm_interpreted.hpp"
#include "vm_compiled.hpp"
#include <new>
#include <memory>
#include <cstdint>
#include <cassert>
#include <limits>
#include <iostream>

namespace randomx {

static void* allocStatic(size_t bytes, size_t align, void*& bufferHead, size_t& bufferCapacity) {
auto ptr = std::align(align, bytes, bufferHead, bufferCapacity);
assert(ptr != nullptr);
void* memory = bufferHead;
bufferHead = (uint8_t*)bufferHead + bytes;
bufferCapacity -= bytes;
//std::cout << "Container alloc: " << bytes << ", remaining: " << bufferCapacity << std::endl;
return memory;
}

template<class T>
static T* constructStatic(void*& bufferHead, size_t& bufferCapacity) {
return new(allocStatic(sizeof(T), alignof(T), bufferHead, bufferCapacity)) T();
}

static void addAlign(uint64_t& size, size_t add, size_t align) {
size = alignSize(size, align);
size += add;
}

template<class T>
static void addAlign(uint64_t& size) {
addAlign(size, sizeof(T), alignof(T));
}

static uint64_t calculateSize(randomx_flags flags, size_t vmCount) {
uint64_t size = 0;
uint64_t align = randomx::CacheLineSize;
addAlign<Container>(size);
addAlign<randomx_container_data>(size);
if (flags & RANDOMX_FLAG_FULL_MEM) {
addAlign<randomx_cache>(size);
if (flags & RANDOMX_FLAG_JIT) {
addAlign<randomx::JitCompiler>(size);
}
}
if ((flags & RANDOMX_FLAG_LARGE_PAGES) && !(flags & RANDOMX_FLAG_MONSTER_PAGES)) {
align = 2 * 1024 * 1024;
}
addAlign<randomx_dataset>(size);
addAlign(size, sizeof(uintptr_t) * vmCount, alignof(uintptr_t));
for (size_t i = 0; i < vmCount; ++i) {
randomx_vm* vm;
if (flags & RANDOMX_FLAG_JIT) {
if (flags & RANDOMX_FLAG_HARD_AES) {
if (flags & RANDOMX_FLAG_SECURE) {
addAlign<randomx::CompiledVmContainerHardAesSecure>(size);
}
else {
addAlign<randomx::CompiledVmContainerHardAes>(size);
}
}
else {
if (flags & RANDOMX_FLAG_SECURE) {
addAlign<randomx::CompiledVmContainerSecure>(size);
}
else {
addAlign<randomx::CompiledVmContainer>(size);
}
}
}
else {
if (flags & RANDOMX_FLAG_HARD_AES) {
addAlign<randomx::InterpretedVmContainerHardAes>(size);
}
else {
addAlign<randomx::InterpretedVmContainer>(size);
}
}
}
for (size_t i = 0; i < vmCount; ++i) {
addAlign(size, randomx::ScratchpadSize, align);
}
if (flags & RANDOMX_FLAG_FULL_MEM) {
addAlign(size, randomx::CacheSize, align);
}
addAlign(size, randomx::DatasetSize, align);
return size;
}

template<class Allocator>
Container* Container::create(randomx_flags flags, size_t vmCount) {
uint64_t bufferSize = calculateSize(flags, vmCount);
//std::cout << "Container size: " << bufferSize << std::endl;
if (bufferSize > std::numeric_limits<size_t>::max()) {
throw std::bad_alloc();
}
size_t bufferCapacity = bufferSize;
void* buffer = Allocator::allocMemory(bufferSize);
void* bufferHead = buffer;
auto* container = constructStatic<Container>(bufferHead, bufferCapacity);
auto* data = constructStatic<randomx_container_data>(bufferHead, bufferCapacity);
data->buffer = buffer;
data->bufferSize = bufferSize;
data->bufferHead = bufferHead;
data->bufferCapacity = bufferCapacity;
data->dealloc = &Allocator::freeMemory;
container->data = data;
return container;
}

template Container* Container::create<MonsterPageAllocator>(randomx_flags flags, size_t vmCount);
template Container* Container::create<LargePageAllocator>(randomx_flags flags, size_t vmCount);
template Container* Container::create<DefaultAllocator>(randomx_flags flags, size_t vmCount);

void* Container::alloc(size_t bytes, size_t align) {
return allocStatic(bytes, align, data->bufferHead, data->bufferCapacity);
}

void Container::dealloc() {
if (cache != nullptr) {
cache->dealloc(cache);
}
for (size_t i = 0; i < vmCount; ++i) {
vms[i]->~randomx_vm();
}
data->dealloc(data->buffer, data->bufferSize);
}

}
70 changes: 70 additions & 0 deletions src/container.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
Copyright (c) 2019, tevador <[email protected]>

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#include "randomx.h"
#include <type_traits>

namespace randomx {

typedef void(DeallocFunc)(void*, size_t);

}

struct randomx_container_data {
void* buffer;
void* bufferHead;
size_t bufferSize;
size_t bufferCapacity;
randomx::DeallocFunc* dealloc;
};

namespace randomx {

struct Container : public randomx_container {
template<class Allocator>
static Container* create(randomx_flags flags, size_t vmCount);
void* alloc(size_t bytes, size_t align = sizeof(uintptr_t));
template<typename T>
void* alloc() {
return alloc(sizeof(T), alignof(T));
}
template<class T>
T* construct() {
return new(alloc<T>()) T();
}
template<class T>
T* construct(size_t numElements) {
return new(alloc(numElements * sizeof(T), alignof(T))) T[numElements];
}
void dealloc();
};

static_assert(std::is_standard_layout<Container>(), "Container must be a standard-layout struct");
}
6 changes: 6 additions & 0 deletions src/dataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ namespace randomx {
template void deallocCache<DefaultAllocator>(randomx_cache* cache);
template void deallocCache<LargePageAllocator>(randomx_cache* cache);

void deallocCacheContainer(randomx_cache* cache) {
if (cache->jit != nullptr) {
cache->jit->~JitCompiler();
}
}

void initCache(randomx_cache* cache, const void* key, size_t keySize) {
uint32_t memory_blocks, segment_length;
argon2_instance_t instance;
Expand Down
2 changes: 2 additions & 0 deletions src/dataset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ namespace randomx {
template<class Allocator>
void deallocCache(randomx_cache* cache);

void deallocCacheContainer(randomx_cache* cache);

void initCache(randomx_cache*, const void*, size_t);
void initCacheCompile(randomx_cache*, const void*, size_t);
void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t blockNumber);
Expand Down
Loading