void VM::check_exception(CallFrame* call_frame) { if(thread_state()->raise_reason() == cNone) { std::cout << "Exception propogating, but none registered!\n"; call_frame->print_backtrace(this); rubinius::abort(); } }
void join() { if (!detached) return; #if defined(__APPLE__) || defined(__linux__) /* Release GIL and disassociate from thread state (which was originally associated with the main Python thread) */ py::gil_scoped_release thread_state(true); coro_transfer(&ctx_main, &ctx_thread); coro_stack_free(&stack); /* Destroy the thread state that was created in mainloop() */ { py::gil_scoped_acquire acquire; acquire.dec_ref(); } #endif thread.join(); detached = false; #if defined(__APPLE__) || defined(__linux__) /* Reacquire GIL and reassociate with thread state [via RAII destructor in 'thread_state'] */ #endif }
thread_status status() const { lua_State* lthread = thread_state(); thread_status lstat = static_cast<thread_status>(lua_status(lthread)); if (lstat != thread_status::ok && lua_gettop(lthread) == 0) { // No thing on the thread's stack means its dead return thread_status::dead; } return lstat; }
void BasicThread::stop_thread(bool is_cancel) { if( THR_NOSTATE == m_state ) return; thread_state(THR_FINISH); if( is_cancel ) pthread_cancel(m_thread); else pthread_join(m_thread, 0); m_state = THR_NOSTATE; }
thread_state get_thread_state(thread_id_type const& id, error_code& ec) { hpx::applier::applier* app = hpx::applier::get_applier_ptr(); if (NULL == app) { HPX_THROWS_IF(ec, invalid_status, "hpx::threads::get_thread_state", "global applier object is not accessible"); return thread_state(unknown); } if (&ec != &throws) ec = make_success_code(); return app->get_thread_manager().get_state(id); }
thread_state set_thread_state(thread_id_type id, thread_state_enum state, thread_state_ex_enum stateex, thread_priority priority, error_code& ec) { hpx::applier::applier* app = hpx::applier::get_applier_ptr(); if (NULL == app) { HPX_THROWS_IF(ec, invalid_status, "hpx::threads::set_thread_state", "global applier object is not accessible"); return thread_state(unknown); } if (&ec != &throws) ec = make_success_code(); return app->get_thread_manager().set_state(id, state, stateex, priority, ec); }
void TimerThread::on_running() { int run_date = TDU::int_date();; bool fclean = false; bool fstart = false; while( THR_RUNNING == thread_state() ) { int cur_date = TDU::int_date(); if( run_date != cur_date ) { if( 0 != run_date ) GNR::read_config(); run_date = cur_date; fclean = false; fstart = false; m_parent->put_item(CMD_CHANGE_DATE, true); usleep(1); continue; } else if( fclean && fstart ) { sleep(5); continue; } int cur_time = TDU::int_time(); if( !fclean && GNR::time_clean_up() <= cur_time ) { fclean = true; m_parent->put_item(CMD_CLEAN_UP, true); usleep(100); } else if( !fstart && GNR::time_start_up() <= cur_time ) { fstart = true; m_parent->put_item(CMD_START_UP, true); usleep(100); } } }
void VM::raise_stack_error(CallFrame* call_frame) { G(stack_error)->locations(this, System::vm_backtrace(this, Fixnum::from(0), call_frame)); thread_state()->raise_exception(G(stack_error)); }
void VM::raise_stack_error(CallFrame* call_frame) { G(stack_error)->locations(this, Location::from_call_stack(this, call_frame)); thread_state()->raise_exception(G(stack_error)); }
inline thread_state set_thread_state( thread_id_type const& thrd, thread_state_enum new_state, thread_state_ex_enum new_state_ex, thread_priority priority, std::size_t thread_num, error_code& ec) { if (HPX_UNLIKELY(!thrd)) { HPX_THROWS_IF(ec, null_thread_id, "threads::detail::set_thread_state", "NULL thread id encountered"); return thread_state(unknown); } // set_state can't be used to force a thread into active state if (new_state == threads::active) { std::ostringstream strm; strm << "invalid new state: " << get_thread_state_name(new_state); HPX_THROWS_IF(ec, bad_parameter, "threads::detail::set_thread_state", strm.str()); return thread_state(unknown); } // we know that the id is actually the pointer to the thread if (!thrd) { if (&ec != &throws) ec = make_success_code(); return thread_state(terminated); // this thread has already been terminated } thread_state previous_state; do { // action depends on the current state previous_state = thrd->get_state(); thread_state_enum previous_state_val = previous_state; // nothing to do here if the state doesn't change if (new_state == previous_state_val) { LTM_(warning) << "set_thread_state: old thread state is the same as new " "thread state, aborting state change, thread(" << thrd.get() << "), description(" << thrd->get_description() << "), new state(" << get_thread_state_name(new_state) << ")"; if (&ec != &throws) ec = make_success_code(); return thread_state(new_state); } // the thread to set the state for is currently running, so we // schedule another thread to execute the pending set_state switch (previous_state_val) { case active: { // schedule a new thread to set the state LTM_(warning) << "set_thread_state: thread is currently active, scheduling " "new thread, thread(" << thrd.get() << "), description(" << thrd->get_description() << "), new state(" << get_thread_state_name(new_state) << ")"; thread_init_data data( boost::bind(&set_active_state, thrd, new_state, new_state_ex, priority, previous_state), "set state for active thread", 0, priority); create_work(thrd->get_scheduler_base(), data, pending, ec); if (&ec != &throws) ec = make_success_code(); return previous_state; // done } break; case terminated: { LTM_(warning) << "set_thread_state: thread is terminated, aborting state " "change, thread(" << thrd.get() << "), description(" << thrd->get_description() << "), new state(" << get_thread_state_name(new_state) << ")"; if (&ec != &throws) ec = make_success_code(); // If the thread has been terminated while this set_state was // pending nothing has to be done anymore. return previous_state; } break; case pending: if (suspended == new_state) { // we do not allow explicit resetting of a state to suspended // without the thread being executed. std::ostringstream strm; strm << "set_thread_state: invalid new state, can't demote a " "pending thread, " << "thread(" << thrd.get() << "), description(" << thrd->get_description() << "), new state(" << get_thread_state_name(new_state) << ")"; LTM_(fatal) << strm.str(); HPX_THROWS_IF(ec, bad_parameter, "threads::detail::set_thread_state", strm.str()); return thread_state(unknown); } break; case suspended: break; // fine, just set the new state default: HPX_ASSERT(false); // should not happen break; } // If the previous state was pending we are supposed to remove the // thread from the queue. But in order to avoid linearly looking // through the queue we defer this to the thread function, which // at some point will ignore this thread by simply skipping it // (if it's not pending anymore). LTM_(info) << "set_thread_state: thread(" << thrd.get() << "), " "description(" << thrd->get_description() << "), " "new state(" << get_thread_state_name(new_state) << "), " "old state(" << get_thread_state_name(previous_state_val) << ")"; // So all what we do here is to set the new state. if (thrd->restore_state(new_state, previous_state)) { thrd->set_state_ex(new_state_ex); break; } // state has changed since we fetched it from the thread, retry LTM_(error) << "set_thread_state: state has been changed since it was fetched, " "retrying, thread(" << thrd.get() << "), " "description(" << thrd->get_description() << "), " "new state(" << get_thread_state_name(new_state) << "), " "old state(" << get_thread_state_name(previous_state_val) << ")"; } while (true); if (new_state == pending) { // REVIEW: Passing a specific target thread may interfere with the // round robin queuing. thrd->get_scheduler_base()->schedule_thread(thrd.get(), thread_num, priority); thrd->get_scheduler_base()->do_some_work(thread_num); } if (&ec != &throws) ec = make_success_code(); return previous_state; }