#include #include #ifdef CHAISCRIPT_NO_DYNLOAD #include #endif #include #include int expected_value(int num_iters) { int i = 0; for (int k = 0; k < num_iters * 10; ++k) { i += k; } return i; } void do_work(chaiscript::ChaiScript_Basic &c, const size_t id) { try { std::stringstream ss; ss << "MyVar" << rand(); c.add(chaiscript::var(5), ss.str()); ss.str(""); ss << id; c.use("multithreaded_work.inc"); c("do_chai_work(4000, " + ss.str() + ");"); } catch (const std::exception &e) { std::cout << "exception: " << e.what() << " thread: " << id; } } int main() { // Disable deprecation warning for getenv call. #ifdef CHAISCRIPT_MSVC #ifdef max // Why Microsoft? why? #undef max #endif #pragma warning(push) #pragma warning(disable : 4996) #endif const char *usepath = getenv("CHAI_USE_PATH"); const char *modulepath = getenv("CHAI_MODULE_PATH"); #ifdef CHAISCRIPT_MSVC #pragma warning(pop) #endif std::vector usepaths; usepaths.emplace_back(""); if (usepath) { usepaths.emplace_back(usepath); } std::vector modulepaths; #ifdef CHAISCRIPT_NO_DYNLOAD chaiscript::ChaiScript chai(/* unused */ modulepaths, usepaths); #else modulepaths.emplace_back(""); if (modulepath) { modulepaths.emplace_back(modulepath); } // For this test we are going to load the dynamic stdlib // to make sure it continues to work chaiscript::ChaiScript_Basic chai( std::make_unique>(), modulepaths, usepaths); #endif std::vector> threads; // Ensure at least two, but say only 7 on an 8 core processor size_t num_threads = static_cast(std::max(static_cast(std::thread::hardware_concurrency()) - 1, 2)); std::cout << "Num threads: " << num_threads << '\n'; for (size_t i = 0; i < num_threads; ++i) { threads.push_back(std::make_shared(do_work, std::ref(chai), i)); } for (size_t i = 0; i < num_threads; ++i) { threads[i]->join(); } for (size_t i = 0; i < num_threads; ++i) { std::stringstream ss; ss << i; if (chai.eval("getvalue(" + ss.str() + ")") != expected_value(4000)) { return EXIT_FAILURE; } if (chai.eval("getid(" + ss.str() + ")") != static_cast(i)) { return EXIT_FAILURE; } } return EXIT_SUCCESS; }