MCPcopy Create free account
hub / github.com/LadybugDB/ladybug / runWorkerThread

Method runWorkerThread

src/common/task_system/task_scheduler.cpp:101–145  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

99}
100
101void TaskScheduler::runWorkerThread() {
102#if defined(__APPLE__)
103 qos_class_t qosClass = (qos_class_t)threadQos;
104 if (qosClass != QOS_CLASS_DEFAULT && qosClass != QOS_CLASS_UNSPECIFIED) {
105 auto pthreadQosStatus = pthread_set_qos_class_self_np(qosClass, 0);
106 UNUSED(pthreadQosStatus);
107 }
108#endif
109 std::unique_lock<std::mutex> lck{taskSchedulerMtx, std::defer_lock};
110 std::exception_ptr exceptionPtr = nullptr;
111 std::shared_ptr<ScheduledTask> scheduledTask = nullptr;
112 while (true) {
113 // Warning: Threads acquire a global lock (using taskSchedulerMutex) right before
114 // deregistering themselves from a task (and they immediately register themselves for
115 // another task without releasing the lock). This acquire-right-before-deregistering ensures
116 // that all writes that were done by threads in Task_j happen before a Task_{j+1} which
117 // depends on Task_j can start. That's because before Task_{j+1} can start, each thread T_i
118 // working on Task_j will need to deregister itself using the global lock. Therefore, by the
119 // time any thread gets to start on Task_{j+1}, all writes made to Task_j by T_i will become
120 // globally visible because T_i grabbed the global lock before deregistering (and without
121 // T_i deregistering Task_{j+1} cannot start).
122 lck.lock();
123 if (scheduledTask != nullptr) {
124 if (exceptionPtr != nullptr) {
125 scheduledTask->task->setException(exceptionPtr);
126 exceptionPtr = nullptr;
127 }
128 scheduledTask->task->deRegisterThreadAndFinalizeTask();
129 scheduledTask = nullptr;
130 }
131 cv.wait(lck, [&] {
132 scheduledTask = getTaskAndRegister();
133 return scheduledTask != nullptr || stopWorkerThreads;
134 });
135 lck.unlock();
136 if (stopWorkerThreads) {
137 return;
138 }
139 try {
140 scheduledTask->task->run();
141 } catch (std::exception& e) {
142 exceptionPtr = std::current_exception();
143 }
144 }
145}
146#else
147// Single-threaded version of TaskScheduler
148TaskScheduler::TaskScheduler(uint64_t) : stopWorkerThreads{false}, nextScheduledTaskID{0} {}

Callers

nothing calls this directly

Calls 5

waitMethod · 0.80
unlockMethod · 0.80
lockMethod · 0.45
runMethod · 0.45

Tested by

no test coverage detected