threads work in progress
This commit is contained in:
75
ml.cpp
75
ml.cpp
@@ -21,6 +21,8 @@
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
|
||||
#define TOO_FEW_ARGS "too few arguments to function"
|
||||
#define TOO_MANY_ARGS "too many arguments to function"
|
||||
@@ -1745,6 +1747,68 @@ namespace builtin {
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
|
||||
std::mutex register_mutex;
|
||||
std::vector<std::thread> threads_register;
|
||||
std::vector<std::mutex> mutexes_register;
|
||||
std::mutex interpreter_mutex;
|
||||
|
||||
MlValue thread_create(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
auto functor = [](std::vector<MlValue> args, MlEnvironment &env) -> void {
|
||||
for (size_t i = 0; i < args.size(); i++)
|
||||
MlValue acc = args[i].eval(env);
|
||||
};
|
||||
|
||||
std::thread th(functor, args, std::ref(env));
|
||||
auto th_id = th.get_id();
|
||||
|
||||
std::lock_guard<std::mutex> lockGuard(register_mutex);
|
||||
threads_register.push_back(std::move(th));
|
||||
|
||||
static_assert(sizeof(std::thread::id)==sizeof(uint64_t), "size of thead::id is not equal to the size of uint_64");
|
||||
uint64_t* ptr=(uint64_t*) &th_id;
|
||||
long tid = (*ptr);
|
||||
|
||||
return MlValue(tid);
|
||||
}
|
||||
|
||||
MlValue thread_under_lock(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
if (args.size() != 2)
|
||||
throw MlError(MlValue("thread_under_lock", thread_under_lock), env, args.size() > 2 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
|
||||
|
||||
if (args[0].as_string() != "ilock")
|
||||
throw MlError(MlValue("thread_under_lock", thread_under_lock), env, UNKNOWN_ERROR);
|
||||
|
||||
|
||||
std::lock_guard<std::mutex> lockGuard(interpreter_mutex);
|
||||
|
||||
MlValue acc;
|
||||
for (size_t i = 0; i < args.size(); i++)
|
||||
acc = args[i].eval(env);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
MlValue threads_join(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
if (args.size() != 0)
|
||||
throw MlError(MlValue("threads_join", threads_join), env, TOO_MANY_ARGS);
|
||||
|
||||
for (auto &th : threads_register)
|
||||
if (th.joinable()) th.join();
|
||||
|
||||
return MlValue::nil();
|
||||
}
|
||||
|
||||
MlValue thread_sleep(std::vector<MlValue> args, MlEnvironment &env) {
|
||||
eval_args(args, env);
|
||||
|
||||
if (args.size() != 1)
|
||||
throw MlError(MlValue("thread-sleep", thread_sleep), env, args.size() > 1 ? TOO_MANY_ARGS : TOO_FEW_ARGS);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(args[0].as_int()));
|
||||
return args[0];
|
||||
}
|
||||
}
|
||||
|
||||
void repl(MlEnvironment &env) {
|
||||
@@ -1819,7 +1883,6 @@ MlValue MlEnvironment::get(const std::string &name) const {
|
||||
if (name == "quote") return MlValue("quote", builtin::quote);
|
||||
if (name == "defun") return MlValue("defun", builtin::defun);
|
||||
if (name == "lambda") return MlValue("lambda", builtin::lambda);
|
||||
if (name == "benchmark") return MlValue("benchmark", builtin::benchmark);
|
||||
if (name == "and") return MlValue("and", builtin::do_and);
|
||||
if (name == "or") return MlValue("or", builtin::do_or);
|
||||
if (name == "set!") return MlValue("set!", builtin::setx);
|
||||
@@ -1907,6 +1970,15 @@ MlValue MlEnvironment::get(const std::string &name) const {
|
||||
// Constants
|
||||
if (name == "endl") return MlValue::string("\n");
|
||||
|
||||
// Other special forms
|
||||
if (name == "benchmark") return MlValue("benchmark", builtin::benchmark);
|
||||
|
||||
// Threading operations
|
||||
if (name == "thread-create") return MlValue("thread-create", builtin::thread_create);
|
||||
if (name == "thread-under-lock") return MlValue("thread-under-lock", builtin::thread_under_lock);
|
||||
if (name == "thread-sleep") return MlValue("thread-sleep", builtin::thread_sleep);
|
||||
if (name == "threads-join") return MlValue("threads-join", builtin::threads_join);
|
||||
|
||||
std::map<std::string, MlValue>::const_iterator itr = defs.find(name);
|
||||
if (itr != defs.end()) return itr->second;
|
||||
else if (parent_scope != nullptr) {
|
||||
@@ -2004,4 +2076,3 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user