载入中...
搜索中...
未找到
Thread.cpp
浏览该文件的文档.
1#include "thread/Thread.h"
2
3#include "common/Exception.h"
4#include "common/Capability.h"
6
7#include <simplesquirrel/simplesquirrel.hpp>
8
9#include <functional>
10#include <thread>
11
12namespace eve {
13namespace thread {
14
16
17Thread::Thread() = default;
18
20 if (defaultPool_)
21 defaultPool_->stop();
22 if (defaultJobSystem_)
23 defaultJobSystem_->stop();
24}
25
27 unsigned n = std::thread::hardware_concurrency();
28 return n == 0 ? 1 : static_cast<int>(n);
29}
30
32 std::lock_guard<std::mutex> lock(mu_);
33 if (!defaultPool_)
34 defaultPool_ = std::make_unique<ThreadPool>(getHardwareConcurrency());
35 return defaultPool_.get();
36}
37
39 if (workerCount < 0)
40 throw eve::Exception("Thread::newThreadPool: workerCount must be >= 0");
41 return new ThreadPool(workerCount);
42}
43
45 std::lock_guard<std::mutex> lock(mu_);
46 if (!defaultJobSystem_)
47 defaultJobSystem_ = std::unique_ptr<JobSystem>(createJobSystem(getHardwareConcurrency()));
48 return defaultJobSystem_.get();
49}
50
52 if (name.empty())
53 throw eve::Exception("Thread::getChannel: name must not be empty");
54 std::lock_guard<std::mutex> lock(mu_);
55 auto it = namedChannels_.find(name);
56 if (it != namedChannels_.end())
57 return it->second.get();
58 auto ch = std::make_unique<Channel>(name);
59 Channel *raw = ch.get();
60 namedChannels_.emplace(std::move(name), std::move(ch));
61 return raw;
62}
63
65
66void Thread::postMain(std::string name, std::string data) {
67 if (name.empty())
68 throw eve::Exception("Thread::postMain: name must not be empty");
69 auto *poster = cap::query<caps::IMainThreadPost>();
70 if (!poster)
71 throw eve::Exception("Thread::postMain: no main-thread queue (event module not linked)");
72 poster->prepare();
73 poster->postToMainThread(std::move(name), std::move(data));
74}
75
76void Thread::expose(ssq::Table &table) {
77 auto cls = table.addClass(name, Thread::create, false);
78 expose(cls);
79
80 // Avoid clashing with network::Channel ("Channel").
81 auto ch = table.addClass<Channel>(
82 "ThreadChannel", std::function<Channel *()>([]() -> Channel * { return nullptr; }), true);
83 ch.addFunc("getName", &Channel::getName);
84 ch.addFunc("push", &Channel::push);
85 ch.addFunc("pop", &Channel::pop);
86 ch.addFunc("demand", &Channel::demand);
87 ch.addFunc("supply", &Channel::supply);
88 ch.addFunc("hasData", &Channel::hasData);
89 ch.addFunc("getCount", &Channel::getCount);
90 ch.addFunc("clear", &Channel::clear);
91
92 auto task = table.addClass<Task>(
93 "Task", std::function<Task *()>([]() -> Task * { return nullptr; }), true);
94 task.addFunc("getStatus", &Task::getStatus);
95 task.addFunc("isDone", &Task::isDone);
96 task.addFunc("hasFailed", &Task::hasFailed);
97 task.addFunc("getError", &Task::getError);
98 task.addFunc("wait", &Task::wait);
99
100 auto pool = table.addClass<ThreadPool>(
101 "ThreadPool", std::function<ThreadPool *()>([]() -> ThreadPool * { return nullptr; }), true);
102 pool.addFunc("getWorkerCount", &ThreadPool::getWorkerCount);
103 pool.addFunc("getPendingCount", &ThreadPool::getPendingCount);
104 pool.addFunc("isRunning", &ThreadPool::isRunning);
105 pool.addFunc("submitSleep", &ThreadPool::submitSleep);
106 pool.addFunc("submitPush", &ThreadPool::submitPush);
107 pool.addFunc("submitPost", &ThreadPool::submitPost);
108 pool.addFunc("waitAll", &ThreadPool::waitAll);
109 pool.addFunc("stop", &ThreadPool::stop);
110}
111
112void Thread::expose(ssq::Class &cls) {
113 cls.addFunc("getName", &Thread::getName);
114 cls.addFunc("getHardwareConcurrency", &Thread::getHardwareConcurrency);
115 cls.addFunc("getPool", &Thread::getPool);
116 cls.addFunc("newThreadPool", &Thread::newThreadPool);
117 cls.addFunc("getChannel", &Thread::getChannel);
118 cls.addFunc("newChannel", &Thread::newChannel);
119 cls.addFunc("postMain", &Thread::postMain);
120}
121
122} // namespace thread
123} // namespace eve
HSQOBJECT cls
Definition ECS.cpp:21
glm::vec3 n
Definition Grass.cpp:64
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:24
Light2D::Data * data
const char * name
Definition RockMesh.cpp:21
virtual std::string getName() const =0
Thread-safe message queue (love2d-style Channel). Values are strings so the API stays overload-free f...
Definition Channel.h:17
void push(std::string value)
Definition Channel.cpp:16
bool hasData() const
Definition Channel.cpp:54
std::string pop()
Non-blocking pop; returns "" if empty.
Definition Channel.cpp:24
std::string demand()
Block until a value is available, then pop it.
Definition Channel.cpp:33
int getCount() const
Definition Channel.cpp:59
std::string getName() const
Definition Channel.cpp:14
std::string supply(int timeoutMs)
Block up to timeoutMs; returns "" on timeout.
Definition Channel.cpp:42
Abstract job scheduler: dependencies, parallel_for, task_group, arena.
Definition JobSystem.h:153
bool hasFailed() const
Definition Task.cpp:28
void wait()
Block until the task finishes (done or failed).
Definition Task.cpp:38
std::string getError() const
Definition Task.cpp:33
bool isDone() const
Definition Task.cpp:23
std::string getStatus() const
Definition Task.cpp:18
Fixed-size worker pool. Owns worker std::threads; tasks run FIFO. Squirrel VM is not thread-safe — do...
Definition ThreadPool.h:24
void waitAll()
Block until idle. Throws when called by a worker belonging to this pool.
int getPendingCount() const
Task * submitSleep(int ms)
Sleep on a worker, then mark done — useful from scripts / tests.
void stop()
Stop accepting work and join workers. Worker calls are rejected. Idempotent.
Task * submitPost(std::string name, std::string data="", int delayMs=0)
Sleep, then post an Event on the main queue (thread-safe). Scripts poll via event....
Task * submitPush(Channel *channel, std::string message, int delayMs=0)
Sleep, then push a message onto a channel (cross-thread signalling).
Thread module: default pool, named channels, pool factory. Script: eve.Thread() → getPool / newThread...
Definition Thread.h:21
Channel * newChannel()
Anonymous channel (not registered in the name map). Caller owns it.
Definition Thread.cpp:64
ThreadPool * getPool()
Shared default pool (created lazily with hardwareConcurrency workers).
Definition Thread.cpp:31
void postMain(std::string name, std::string data="")
Thread-safe post onto the Event module queue (any thread). Main loop: event.pump is unrelated; just e...
Definition Thread.cpp:66
JobSystem * getJobSystem()
Shared engine-wide JobSystem (created lazily with hardware concurrency workers). Use it for dependenc...
Definition Thread.cpp:44
Channel * getChannel(std::string name)
Named shared channel (love2d-style). Same name → same Channel instance for the lifetime of the module...
Definition Thread.cpp:51
ThreadPool * newThreadPool(int workerCount=0)
Create an independent pool. Caller owns it (delete when done).
Definition Thread.cpp:38
int getHardwareConcurrency() const
Hardware concurrency hint (at least 1).
Definition Thread.cpp:26
~Thread() override
Definition Thread.cpp:19
I * query()
Definition Capability.h:77
JobSystem * createJobSystem(int workerCount)
Create a JobSystem with the configured backend.
Definition JobSystem.cpp:14
Definition Build.cpp:11