Skip to content

Commit 7fd09de

Browse files
committed
workpool refine: making it completely usable in non-photon env
by converting mutex to spinlock
1 parent 898fec7 commit 7fd09de

2 files changed

Lines changed: 18 additions & 16 deletions

File tree

thread/workerpool.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class WorkPool::impl {
3535
static constexpr uint64_t QUEUE_YIELD_COUNT = 256;
3636
static constexpr uint64_t QUEUE_YIELD_US = 1024;
3737

38-
photon::mutex worker_mtx;
38+
photon::spinlock worker_lock;
3939
std::vector<std::thread> owned_std_threads;
4040
std::vector<photon::vcpu_base *> vcpus;
4141
std::atomic<uint64_t> vcpu_index{0};
@@ -54,7 +54,7 @@ class WorkPool::impl {
5454
}
5555

5656
~impl() { // avoid depending on photon to make it destructible wihout photon
57-
for (auto num = vcpus.size(); num; --num) enqueue({});
57+
for (auto num = vcpus.size(); num; --num) enqueue({}, PhotonContext());
5858
for (auto &worker : owned_std_threads) worker.join();
5959
while (vcpus.size()) std::this_thread::yield();
6060
}
@@ -81,7 +81,6 @@ class WorkPool::impl {
8181
}
8282

8383
int get_vcpu_num() {
84-
photon::scoped_lock _(worker_mtx);
8584
return vcpus.size();
8685
}
8786

@@ -92,12 +91,12 @@ class WorkPool::impl {
9291
}
9392

9493
void add_vcpu() {
95-
photon::scoped_lock _(worker_mtx);
94+
SCOPED_LOCK(worker_lock);
9695
vcpus.push_back(photon::get_vcpu());
9796
}
9897

9998
void remove_vcpu() {
100-
photon::scoped_lock _(worker_mtx);
99+
SCOPED_LOCK(worker_lock);
101100
auto v = photon::get_vcpu();
102101
auto it = std::find(vcpus.begin(), vcpus.end(), v);
103102
vcpus.erase(it);
@@ -151,6 +150,10 @@ class WorkPool::impl {
151150
return vcpus[index];
152151
}
153152

153+
int thread_migrate(photon::thread* th, size_t index) {
154+
return photon::thread_migrate(th, get_vcpu_in_pool(index));
155+
}
156+
154157
int join_current_vcpu_into_workpool() {
155158
if (!photon::CURRENT) return -1;
156159
main_loop();
@@ -205,8 +208,8 @@ void WorkPool::do_call<PhotonContext>(Delegate<void> call) {
205208
}
206209

207210
void WorkPool::enqueue(Delegate<void> call) { pImpl->enqueue(call); }
208-
photon::vcpu_base *WorkPool::get_vcpu_in_pool(size_t index) {
209-
return pImpl->get_vcpu_in_pool(index);
211+
int WorkPool::thread_migrate(photon::thread* th, size_t index) {
212+
return pImpl->thread_migrate(th, index);
210213
}
211214
int WorkPool::join_current_vcpu_into_workpool() {
212215
return pImpl->join_current_vcpu_into_workpool();

thread/workerpool.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace photon {
2929
class WorkPool {
3030
public:
3131
/**
32-
* @brief Construct a new Work Pool object
32+
* @brief Construct a new Work Pool object; available in non-photon environment
3333
*
3434
* @param vcpu_num how many VCPU (std threads) create for this workpool
3535
* @param ev_engine how to initial event engine as preset VCPUs
@@ -44,21 +44,22 @@ class WorkPool {
4444
WorkPool(const WorkPool& other) = delete;
4545
WorkPool& operator=(const WorkPool& rhs) = delete;
4646

47+
// available in non-photon environment
4748
~WorkPool();
4849

4950
/**
5051
* @brief `hold_as_worker` makes blocks current std thread join workpool, as
51-
* a woker member. Noticed that worker should initial environment by self,
52+
* a woker member. Note that workers should initialize photon environment by themselves,
5253
* workpool will not do photon environment for it. When workpool destructed,
5354
* the function call will be finished, and return 0.
5455
* @return int 0 for success, and -1 for failure
5556
*/
5657
int join_current_vcpu_into_workpool();
5758

5859
/**
59-
* @brief Get the vcpu num
60-
*
61-
* @return int
60+
* @brief Get the vcpu num; available in non-photon environment
61+
*
62+
* @return int
6263
*/
6364
int get_vcpu_num();
6465

@@ -83,6 +84,7 @@ class WorkPool {
8384

8485
/**
8586
* @brief `async_call` just like `call`, but do not wait for task done.
87+
* available in non-photon environment.
8688
*
8789
* @param task Pointer to async task callable object. Call by lamda could
8890
* using `workpool.async_call(new auto ([&](){ // some lambda; }));` The
@@ -103,9 +105,7 @@ class WorkPool {
103105
* [0, vcpu_num), it will choose the next one in pool (round-robin).
104106
* @return int 0 for success, and <0 means failed to migrate.
105107
*/
106-
int thread_migrate(photon::thread* th = CURRENT, size_t index = -1UL) {
107-
return photon::thread_migrate(th, get_vcpu_in_pool(index));
108-
}
108+
int thread_migrate(photon::thread* th = CURRENT, size_t index = -1UL);
109109

110110
protected:
111111
class impl; // does not depend on T
@@ -115,7 +115,6 @@ class WorkPool {
115115
template<typename Context>
116116
void do_call(Delegate<void> call);
117117
void enqueue(Delegate<void> call);
118-
photon::vcpu_base* get_vcpu_in_pool(size_t index);
119118

120119
template<typename Task>
121120
static void __async_call_helper(void* task) {

0 commit comments

Comments
 (0)