| 215 | } |
| 216 | |
| 217 | void executor::execute(){ |
| 218 | while(shutdown == 0 && exception_holder.empty()){ |
| 219 | //consider using get_all and calling in a loop. |
| 220 | auto cur_task = this->task_queue.pop_or_wait(); |
| 221 | pool.push([cur_task{std::move(cur_task)}, this](int thread_id){ |
| 222 | std::size_t memory_needed = cur_task->task_memory_needed(); |
| 223 | |
| 224 | // Here we want to wait until we make sure we have enough memory to operate, or if there are no tasks currently running, then we want to go ahead and run |
| 225 | std::unique_lock<std::mutex> lock(memory_safety_mutex); |
| 226 | memory_safety_cv.wait(lock, [this, memory_needed] { |
| 227 | if (memory_needed < (processing_memory_limit - resource->get_memory_used())){ |
| 228 | return true; |
| 229 | } else if (active_tasks_counter.load() == 0){ |
| 230 | std::shared_ptr<spdlog::logger> logger = spdlog::get("batch_logger"); |
| 231 | if (logger){ |
| 232 | logger->warn("|||{info}|||||", |
| 233 | "info"_a="WARNING: launching task even though over limit, because there are no tasks running. Memory used: {}"_format(std::to_string(resource->get_memory_used()))); |
| 234 | } |
| 235 | return true; |
| 236 | } else { |
| 237 | return false; |
| 238 | } |
| 239 | }); |
| 240 | |
| 241 | active_tasks_counter++; |
| 242 | |
| 243 | try { |
| 244 | cur_task->run(this->streams[thread_id], this); |
| 245 | } catch(...) { |
| 246 | std::unique_lock<std::mutex> lock(exception_holder_mutex); |
| 247 | exception_holder.push(std::current_exception()); |
| 248 | cur_task->fail(); |
| 249 | } |
| 250 | |
| 251 | active_tasks_counter--; |
| 252 | memory_safety_cv.notify_all(); |
| 253 | }); |
| 254 | } |
| 255 | } |
| 256 | |
| 257 | std::exception_ptr executor::last_exception(){ |
| 258 | std::unique_lock<std::mutex> lock(exception_holder_mutex); |
no test coverage detected