@@ -39,15 +39,12 @@ class WorkPool::impl {
3939 std::vector<std::thread> owned_std_threads;
4040 std::vector<photon::vcpu_base *> vcpus;
4141 std::atomic<uint64_t > vcpu_index{0 };
42- photon::semaphore queue_sem;
43- photon::condition_variable exit_cv;
4442 photon::common::RingChannel<
4543 LockfreeMPMCRingQueue<Delegate<void >, RING_SIZE >>
4644 ring;
4745 int mode;
4846
49- impl (size_t vcpu_num, int ev_engine, int io_engine, int mode)
50- : queue_sem(0 ), mode(mode), ready_vcpu(0 ) {
47+ impl (size_t vcpu_num, int ev_engine, int io_engine, int mode) : mode(mode) {
5148 for (size_t i = 0 ; i < vcpu_num; ++i) {
5249 owned_std_threads.emplace_back (
5350 &WorkPool::impl::worker_thread_routine, this , ev_engine,
@@ -56,14 +53,10 @@ class WorkPool::impl {
5653 ready_vcpu.wait (vcpu_num);
5754 }
5855
59- ~impl () {
60- auto num = vcpus.size ();
61- for (size_t i = 0 ; i < num; i++) {
62- enqueue ({});
63- }
56+ ~impl () { // avoid depending on photon to make it destructible wihout photon
57+ for (auto num = vcpus.size (); num; --num) enqueue ({});
6458 for (auto &worker : owned_std_threads) worker.join ();
65- photon::scoped_lock lock (worker_mtx);
66- while (vcpus.size ()) exit_cv.wait (lock, 1UL * 1000 );
59+ while (vcpus.size ()) std::this_thread::yield ();
6760 }
6861
6962 void enqueue (Delegate<void > call, AutoContext = {}) {
@@ -108,49 +101,45 @@ class WorkPool::impl {
108101 auto v = photon::get_vcpu ();
109102 auto it = std::find (vcpus.begin (), vcpus.end (), v);
110103 vcpus.erase (it);
111- exit_cv.notify_all ();
112104 }
113105
114106 struct TaskLB {
115107 Delegate<void > task;
116- std::atomic< uint64_t > * count;
108+ volatile uint64_t * count;
117109 };
118110
119111 void main_loop () {
120112 add_vcpu ();
121113 DEFER (remove_vcpu ());
122- std::atomic< uint64_t > running_tasks{ 0 } ;
114+ volatile uint64_t running_tasks = 0 ;
123115 photon::ThreadPoolBase *pool = nullptr ;
124116 if (mode > 0 ) pool = photon::new_thread_pool (mode);
125117 DEFER (if (pool) delete_thread_pool (pool));
126118 ready_vcpu.signal (1 );
127119 for (;;) {
128- auto task = ring. recv ( running_tasks. load () ? 0 : QUEUE_YIELD_COUNT ,
129- QUEUE_YIELD_US );
120+ auto yc = running_tasks ? 0 : QUEUE_YIELD_COUNT ;
121+ auto task = ring. recv (yc, QUEUE_YIELD_US );
130122 if (!task) break ;
131- running_tasks. fetch_add ( 1 , std::memory_order_acq_rel);
123+ running_tasks = running_tasks + 1 ; // ++ -- are deprecated for volatile in C++20
132124 TaskLB tasklb{task, &running_tasks};
133125 if (mode < 0 ) {
134126 delegate_helper (&tasklb);
135- } else if (mode == 0 ) {
136- auto th = photon::thread_create (
137- &WorkPool::impl::delegate_helper, &tasklb);
138- photon::thread_yield_to (th);
139127 } else {
140- auto th = pool->thread_create (&WorkPool::impl::delegate_helper,
141- &tasklb);
128+ auto th = !pool ? thread_create (&delegate_helper, &tasklb) :
129+ pool-> thread_create (&delegate_helper, &tasklb) ;
130+ // yield to th so as to copy tasklb to th's stack
142131 photon::thread_yield_to (th);
143132 }
144133 }
145- while (running_tasks. load (std::memory_order_acquire) )
134+ while (running_tasks)
146135 photon::thread_yield ();
147136 }
148137
149138 static void *delegate_helper (void *arg) {
150139 // must copy to keep tasklb alive
151140 TaskLB tasklb = *(TaskLB*)arg;
152141 tasklb.task ();
153- tasklb.count -> fetch_sub ( 1 , std::memory_order_acq_rel);
142+ * tasklb.count = *tasklb. count - 1 ; // ++ -- are deprecated for volatile in C++20
154143 return nullptr ;
155144 }
156145
@@ -200,7 +189,7 @@ class WorkPool::impl {
200189WorkPool::WorkPool (size_t vcpu_num, int ev_engine, int io_engine, int mode)
201190 : pImpl(new impl(vcpu_num, ev_engine, io_engine, mode)) {}
202191
203- WorkPool::~WorkPool () {}
192+ WorkPool::~WorkPool () { /* implicitly delete pImpl */ }
204193
205194template <>
206195void WorkPool::do_call<AutoContext>(Delegate<void > call) {
0 commit comments