diff --git a/src/allocator.cpp b/src/allocator.cpp
index 2626147..2c344a8 100644
--- a/src/allocator.cpp
+++ b/src/allocator.cpp
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with RandomX. If not, see.
*/
+#include
#include "allocator.hpp"
#include "intrin_portable.h"
#include "virtual_memory.hpp"
@@ -26,7 +27,10 @@ namespace randomx {
template
void* AlignedAllocator::allocMemory(size_t count) {
- return _mm_malloc(count, alignment);
+ void *mem = _mm_malloc(count, alignment);
+ if (mem == nullptr)
+ throw std::bad_alloc();
+ return mem;
}
template
diff --git a/src/randomx.cpp b/src/randomx.cpp
index bb8aa22..cc076c1 100644
--- a/src/randomx.cpp
+++ b/src/randomx.cpp
@@ -28,7 +28,7 @@ along with RandomX. If not, see.
extern "C" {
randomx_cache *randomx_alloc_cache(randomx_flags flags) {
- randomx_cache *cache;
+ randomx_cache *cache = nullptr;
try {
switch (flags & (RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES)) {
@@ -99,72 +99,72 @@ extern "C" {
delete dataset;
}
- randomx_vm *randomx_create_vm(randomx_flags flags) {
+ randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset) {
randomx_vm *vm = nullptr;
try {
switch (flags & (RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES)) {
- case RANDOMX_FLAG_DEFAULT: //0
+ case RANDOMX_FLAG_DEFAULT:
vm = new randomx::InterpretedLightVmDefault();
break;
- case RANDOMX_FLAG_FULL_MEM: //1
+ case RANDOMX_FLAG_FULL_MEM:
vm = new randomx::InterpretedVmDefault();
break;
- case RANDOMX_FLAG_JIT: //2
+ case RANDOMX_FLAG_JIT:
vm = new randomx::CompiledLightVmDefault();
break;
- case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT: //3
+ case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT:
vm = new randomx::CompiledVmDefault();
break;
- case RANDOMX_FLAG_HARD_AES: //4
+ case RANDOMX_FLAG_HARD_AES:
vm = new randomx::InterpretedLightVmHardAes();
break;
- case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_HARD_AES: //5
+ case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_HARD_AES:
vm = new randomx::InterpretedVmHardAes();
break;
- case RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES: //6
+ case RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES:
vm = new randomx::CompiledLightVmHardAes();
break;
- case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES: //7
+ case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES:
vm = new randomx::CompiledVmHardAes();
break;
- case RANDOMX_FLAG_LARGE_PAGES: //8
+ case RANDOMX_FLAG_LARGE_PAGES:
vm = new randomx::InterpretedLightVmLargePage();
break;
- case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_LARGE_PAGES: //9
+ case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_LARGE_PAGES:
vm = new randomx::InterpretedVmLargePage();
break;
- case RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES: //10
+ case RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES:
vm = new randomx::CompiledLightVmLargePage();
break;
- case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES: //11
+ case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES:
vm = new randomx::CompiledVmLargePage();
break;
- case RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: //12
+ case RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES:
vm = new randomx::InterpretedLightVmLargePageHardAes();
break;
- case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: //13
+ case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES:
vm = new randomx::InterpretedVmLargePageHardAes();
break;
- case RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: //14
+ case RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES:
vm = new randomx::CompiledLightVmLargePageHardAes();
break;
- case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: //15
+ case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES:
vm = new randomx::CompiledVmLargePageHardAes();
break;
@@ -172,6 +172,12 @@ extern "C" {
UNREACHABLE;
}
+ if(cache != nullptr)
+ vm->setCache(cache);
+
+ if(dataset != nullptr)
+ vm->setDataset(dataset);
+
vm->allocate();
}
catch (std::exception &ex) {
diff --git a/src/randomx.h b/src/randomx.h
index 58d9888..f620c06 100644
--- a/src/randomx.h
+++ b/src/randomx.h
@@ -27,10 +27,10 @@ along with RandomX. If not, see.
typedef enum {
RANDOMX_FLAG_DEFAULT = 0,
- RANDOMX_FLAG_FULL_MEM = 1,
- RANDOMX_FLAG_JIT = 2,
- RANDOMX_FLAG_HARD_AES = 4,
- RANDOMX_FLAG_LARGE_PAGES = 8,
+ RANDOMX_FLAG_LARGE_PAGES = 1,
+ RANDOMX_FLAG_HARD_AES = 2,
+ RANDOMX_FLAG_FULL_MEM = 4,
+ RANDOMX_FLAG_JIT = 8,
} randomx_flags;
typedef struct randomx_dataset randomx_dataset;
@@ -49,7 +49,7 @@ randomx_dataset *randomx_alloc_dataset(randomx_flags flags);
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startBlock, unsigned long blockCount);
void randomx_release_dataset(randomx_dataset *dataset);
-randomx_vm *randomx_create_vm(randomx_flags flags);
+randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset);
void randomx_vm_set_cache(randomx_vm *machine, randomx_cache* cache);
void randomx_vm_set_dataset(randomx_vm *machine, randomx_dataset *dataset);
void randomx_destroy_vm(randomx_vm *machine);
diff --git a/src/tests/api-example1.c b/src/tests/api-example1.c
index f8277b9..7de0db2 100644
--- a/src/tests/api-example1.c
+++ b/src/tests/api-example1.c
@@ -8,8 +8,7 @@ int main() {
randomx_cache *myCache = randomx_alloc_cache(RANDOMX_FLAG_DEFAULT);
randomx_init_cache(myCache, mySeed, sizeof mySeed);
- randomx_vm *myMachine = randomx_create_vm(RANDOMX_FLAG_DEFAULT);
- randomx_vm_set_cache(myMachine, myCache);
+ randomx_vm *myMachine = randomx_create_vm(RANDOMX_FLAG_DEFAULT, myCache, NULL);
randomx_calculate_hash(myMachine, &myInput, sizeof myInput, hash);
diff --git a/src/tests/api-example2.cpp b/src/tests/api-example2.cpp
index ebd99c4..5d78037 100644
--- a/src/tests/api-example2.cpp
+++ b/src/tests/api-example2.cpp
@@ -26,8 +26,7 @@ int main() {
t2.join();
randomx_release_cache(myCache);
- randomx_vm *myMachine = randomx_create_vm((randomx_flags)(RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES));
- randomx_vm_set_dataset(myMachine, myDataset);
+ randomx_vm *myMachine = randomx_create_vm((randomx_flags)(RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES), nullptr, myDataset);
randomx_calculate_hash(myMachine, &myInput, sizeof myInput, hash);
diff --git a/src/tests/benchmark.cpp b/src/tests/benchmark.cpp
index a92f9b6..f20e59c 100644
--- a/src/tests/benchmark.cpp
+++ b/src/tests/benchmark.cpp
@@ -201,11 +201,11 @@ int main(int argc, char** argv) {
std::cout << "Memory initialized in " << sw.getElapsed() << " s" << std::endl;
std::cout << "Initializing " << threadCount << " virtual machine(s) ..." << std::endl;
for (int i = 0; i < threadCount; ++i) {
- randomx_vm *vm = randomx_create_vm(flags);
- if (miningMode)
- randomx_vm_set_dataset(vm, dataset);
- else
- randomx_vm_set_cache(vm, cache);
+ randomx_vm *vm = randomx_create_vm(flags, cache, dataset);
+ if (vm == nullptr) {
+ std::cout << "ERROR: Unsupported virtual machine options" << std::endl;
+ return 1;
+ }
vms.push_back(vm);
}
std::cout << "Running benchmark (" << noncesCount << " nonces) ..." << std::endl;
diff --git a/src/virtual_machine.cpp b/src/virtual_machine.cpp
index a8e2b63..a0e60cb 100644
--- a/src/virtual_machine.cpp
+++ b/src/virtual_machine.cpp
@@ -17,12 +17,13 @@ You should have received a copy of the GNU General Public License
along with RandomX. If not, see.
*/
+#include
+#include
+#include
#include "virtual_machine.hpp"
#include "common.hpp"
#include "aes_hash.hpp"
#include "blake2/blake2.h"
-#include
-#include
#include "intrin_portable.h"
#include "allocator.hpp"
@@ -93,6 +94,8 @@ std::ostream& operator<<(std::ostream& os, const randomx::RegisterFile& rf) {
namespace randomx {
+ alignas(16) volatile static __m128i aesDummy;
+
template
VmBase::~VmBase() {
Allocator::freeMemory(scratchpad, ScratchpadSize);
@@ -100,6 +103,13 @@ namespace randomx {
template
void VmBase::allocate() {
+ if (mem.memory == nullptr)
+ throw std::invalid_argument("Cache/Dataset not set");
+ if (!softAes) { //if hardware AES is not supported, it's better to fail now than to return a ticking bomb
+ __m128i tmp = _mm_load_si128((const __m128i*)&aesDummy);
+ tmp = _mm_aesenc_si128(tmp, tmp);
+ _mm_store_si128((__m128i*)&aesDummy, tmp);
+ }
scratchpad = (uint8_t*)Allocator::allocMemory(ScratchpadSize);
}
diff --git a/src/vm_compiled_light.hpp b/src/vm_compiled_light.hpp
index 8183039..242680d 100644
--- a/src/vm_compiled_light.hpp
+++ b/src/vm_compiled_light.hpp
@@ -37,7 +37,7 @@ namespace randomx {
AlignedAllocator::freeMemory(ptr, sizeof(CompiledLightVm));
}
void setCache(randomx_cache* cache) override;
- void setDataset(randomx_dataset* dataset) override {}
+ void setDataset(randomx_dataset* dataset) override { }
void run(void* seed) override;
using CompiledVm::mem;