// //the routine for deleting keys in pool // void* NVM_KV_Pool_Del_Manager::start_thread() { pthread_mutex_t *glb_mtx = get_store()->get_pool_mgr()->get_glb_mutex(); NVM_KV_Store* kv_store = get_store(); NVM_KV_Pool_Mgr* pool_mgr = kv_store->get_pool_mgr(); bool delete_all_pools = false; int ret_code = NVM_SUCCESS; set_cancel_state(); //register function that needs to be called on thread cancellation pthread_cleanup_push(&NVM_KV_Scanner::scanner_cancel_routine, get_mutex()); pthread_cleanup_push(&NVM_KV_Scanner::scanner_cancel_routine, glb_mtx); while (true) { //cancellation point pthread_testcancel(); //check if the pool deletion map is empty, if not //return from the wait else start waiting for //external trigger pthread_mutex_lock(get_mutex()); while (!pool_mgr->has_pools_to_delete()) { wait_for_trigger(); } //copy out the pool deletion bitmap to m_pools_to_delete bitmap for //processing. This operation is protected by pool bitmap mutex. pool_mgr->get_pool_deletion_bitmap(m_pools_to_delete, delete_all_pools); pthread_mutex_unlock(get_mutex()); //to yield to pool deletion manager, pool deletion status is set right //away pool_mgr->set_pool_del_status(true); //acquire global lock to synchronize with expiry manager pthread_mutex_lock(glb_mtx); if ((ret_code = start_pool_delete(delete_all_pools)) != NVM_SUCCESS) { fprintf(stderr, "Pool deletion encounter error: %d\n", ret_code); } pool_mgr->set_pool_del_status(false); //trigger expiry thread if (get_store()->expiry_status()) { get_store()->get_expiry_thread()->restart_scanner_if_asleep(); } pthread_mutex_unlock(glb_mtx); } pthread_cleanup_pop(0); pthread_cleanup_pop(0); return NULL; }
void FawkesMainThread::loop() { if (!thread_manager_->timed_threads_exist()) { multi_logger_->log_debug("FawkesMainThread", "No timed threads exist, waiting"); try { thread_manager_->wait_for_timed_threads(); multi_logger_->log_debug("FawkesMainThread", "Timed threads have been added, " "running main loop now"); } catch (InterruptedException &e) { multi_logger_->log_debug("FawkesMainThread", "Waiting for timed threads interrupted"); return; } } plugin_manager_->lock(); try { if (time_wait_) { time_wait_->mark_start(); } loop_start_->stamp_systime(); CancelState old_state; set_cancel_state(CANCEL_DISABLED, &old_state); mainloop_mutex_->lock(); if (unlikely(mainloop_thread_ != NULL)) { try { if (likely(mainloop_thread_ != NULL)) { mainloop_thread_->wakeup(mainloop_barrier_); mainloop_barrier_->wait(); } } catch (Exception &e) { multi_logger_->log_warn("FawkesMainThread", e); } } else { uint num_hooks = syncpoints_start_hook_.size(); if (syncpoints_end_hook_.size() != num_hooks) { multi_logger_->log_error( "FawkesMainThread", "Hook syncpoints are not initialized properly, not waking up any threads!"); } else { for (uint i = 0; i < num_hooks; i++) { syncpoints_start_hook_[i]->emit("FawkesMainThread"); syncpoints_end_hook_[i]->reltime_wait_for_all("FawkesMainThread", 0, max_thread_time_nanosec_); } } } mainloop_mutex_->unlock(); set_cancel_state(old_state); test_cancel(); thread_manager_->try_recover(recovered_threads_); if (!recovered_threads_.empty()) { // threads have been recovered! //multi_logger_->log_error(name(), "Threads recovered %zu", recovered_threads_.size()); if (enable_looptime_warnings_) { if (recovered_threads_.size() == 1) { multi_logger_->log_warn("FawkesMainThread", "The thread %s could be " "recovered and resumes normal operation", recovered_threads_.front().c_str()); } else { std::string s; for (std::list<std::string>::iterator i = recovered_threads_.begin(); i != recovered_threads_.end(); ++i) { s += *i + " "; } multi_logger_->log_warn("FawkesMainThread", "The following threads could be " "recovered and resumed normal operation: %s", s.c_str()); } } recovered_threads_.clear(); } if (desired_loop_time_sec_ > 0) { loop_end_->stamp_systime(); float loop_time = *loop_end_ - loop_start_; if (enable_looptime_warnings_) { // give some extra 10% to eliminate frequent false warnings due to regular // time jitter (TimeWait might not be all that precise) if (loop_time > 1.1 * desired_loop_time_sec_) { multi_logger_->log_warn("FawkesMainThread", "Loop time exceeded, " "desired: %f sec (%u usec), actual: %f sec", desired_loop_time_sec_, desired_loop_time_usec_, loop_time); } } } plugin_manager_->unlock(); if (time_wait_) { time_wait_->wait_systime(); } else { yield(); } } catch (Exception &e) { multi_logger_->log_warn("FawkesMainThread", "Exception caught while executing default main " "loop, ignoring."); multi_logger_->log_warn("FawkesMainThread", e); } catch (std::exception &e) { multi_logger_->log_warn("FawkesMainThread", "STL Exception caught while executing default main " "loop, ignoring. (what: %s)", e.what()); } // catch ... is not a good idea, would catch cancellation exception // at least needs to be rethrown. }
void FawkesMainThread::loop() { if ( ! __thread_manager->timed_threads_exist() ) { __multi_logger->log_debug("FawkesMainThread", "No timed threads exist, waiting"); try { __thread_manager->wait_for_timed_threads(); __multi_logger->log_debug("FawkesMainThread", "Timed threads have been added, " "running main loop now"); } catch (InterruptedException &e) { __multi_logger->log_debug("FawkesMainThread", "Waiting for timed threads interrupted"); return; } } __plugin_manager->lock(); try { if ( __time_wait ) { __time_wait->mark_start(); } __loop_start->stamp_systime(); CancelState old_state; set_cancel_state(CANCEL_DISABLED, &old_state); __mainloop_mutex->lock(); if (unlikely(__mainloop_thread != NULL)) { try { if (likely(__mainloop_thread != NULL)) { __mainloop_thread->wakeup(__mainloop_barrier); __mainloop_barrier->wait(); } } catch (Exception &e) { __multi_logger->log_warn("FawkesMainThread", e); } } else { safe_wake(BlockedTimingAspect::WAKEUP_HOOK_PRE_LOOP, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_ACQUIRE, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PREPARE, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PROCESS, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_WORLDSTATE, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_THINK, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SKILL, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_ACT, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_ACT_EXEC, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_POST_LOOP, __max_thread_time_usec); } __mainloop_mutex->unlock(); set_cancel_state(old_state); test_cancel(); __thread_manager->try_recover(__recovered_threads); if ( ! __recovered_threads.empty() ) { // threads have been recovered! //__multi_logger->log_error(name(), "Threads recovered %zu", __recovered_threads.size()); if(__enable_looptime_warnings) { if ( __recovered_threads.size() == 1 ) { __multi_logger->log_warn("FawkesMainThread", "The thread %s could be " "recovered and resumes normal operation", __recovered_threads.front().c_str()); } else { std::string s; for (std::list<std::string>::iterator i = __recovered_threads.begin(); i != __recovered_threads.end(); ++i) { s += *i + " "; } __multi_logger->log_warn("FawkesMainThread", "The following threads could be " "recovered and resumed normal operation: %s", s.c_str()); } } __recovered_threads.clear(); } if (__desired_loop_time_sec > 0) { __loop_end->stamp_systime(); float loop_time = *__loop_end - __loop_start; if(__enable_looptime_warnings) { // give some extra 10% to eliminate frequent false warnings due to regular // time jitter (TimeWait might not be all that precise) if (loop_time > 1.1 * __desired_loop_time_sec) { __multi_logger->log_warn("FawkesMainThread", "Loop time exceeded, " "desired: %f sec (%u usec), actual: %f sec", __desired_loop_time_sec, __desired_loop_time_usec, loop_time); } } } __plugin_manager->unlock(); if ( __time_wait ) { __time_wait->wait_systime(); } else { yield(); } } catch (Exception &e) { __multi_logger->log_warn("FawkesMainThread", "Exception caught while executing default main " "loop, ignoring."); __multi_logger->log_warn("FawkesMainThread", e); } catch (std::exception &e) { __multi_logger->log_warn("FawkesMainThread", "STL Exception caught while executing default main " "loop, ignoring. (what: %s)", e.what()); } // catch ... is not a good idea, would catch cancellation exception // at least needs to be rethrown. }