void fill(size_t num) { for (size_t i = 0; i < m_max_priority; ++i) for (size_t j = 0; j < num; ++j) m_queue.push(i, j); }
std::size_t size(unsigned int timeout = 5) { boost::shared_lock<boost::shared_mutex> lock(mutex_, boost::get_system_time() + boost::posix_time::seconds(timeout)); if (!lock || queue_.empty()) return 0; return queue_.size(); }
void dequeue_( msg_type & msg) { msg = queue_.front(); queue_.pop(); }
bool empty_() const { return queue_.empty(); }
//! Returns the current number of nodes in the queue. size_type size() const { return m_queue.size(); }
std::size_t size() const{ return queue_.size(); }
bool dequeue(T& value) { return m_queue.pop(value); }
//! Returns true if the queue is empty inline bool empty() { m_mutex.lock(); bool res = m_queue.empty(); m_mutex.unlock(); return res; }
static inline void finish (bool output_fired, bd_t bda, bd_t bdb) { if (action_.automaton.get () != 0) { // We were executing an action of this automaton. switch (action_.action->type) { case INPUT: // We were executing an input. Move to the next input. ++input_action_pos_; proceed_to_input (); // -EEE input_action_list_.front ()->output_action.automaton->unlock_execution (); finish_output (); break; case OUTPUT: // We were executing an output ... if (output_fired) { // ... and the output output did something. output_buffer_a_ = action_.automaton->lookup_buffer (bda); // Synchronize the buffers. if (output_buffer_a_.get () != 0) { output_buffer_a_->sync (0, output_buffer_a_->size ()); } output_buffer_b_ = action_.automaton->lookup_buffer (bdb); if (output_buffer_b_.get () != 0) { output_buffer_b_->sync (0, output_buffer_b_->size ()); } // Proceed to execute the inputs. input_action_pos_ = input_action_list_.begin (); // This does not return if there are inputs. proceed_to_input (); } // No input actions to execute. // -EEE action_.automaton->unlock_execution (); finish_output (); break; case INTERNAL: case SYSTEM: // -EEE action_.automaton->unlock_execution (); break; } } // We are done with the current action. action_.automaton = shared_ptr<automaton> (); for (;;) { irq_handler::process_interrupts (); while (!ready_queue_.empty ()) { // Get the automaton context and remove it from the ready queue. automaton_context* c = ready_queue_.front (); ready_queue_.pop_front (); // Load the action. action_ = c->front (); c->pop_front (); // The automaton exists. Continue loading and execute. switch (action_.action->type) { case INPUT: // Error. Not a local action. kpanic ("Non-local action on execution queue"); break; case OUTPUT: { kassert (input_action_list_.empty ()); // Copy the bindings. action_.automaton->copy_bound_inputs (action_, back_inserter (input_action_list_)); // Sort the bindings by input automaton. sort (input_action_list_.begin (), input_action_list_.end (), sort_bindings_by_input ()); // We lock the automata in order. This is called Havender's Principle. bool output_locked = false; for (input_action_list_type::const_iterator pos = input_action_list_.begin (); pos != input_action_list_.end (); ++pos) { shared_ptr<automaton> input_automaton = (*pos)->input_action.automaton; if (!output_locked && action_.automaton->aid () < input_automaton->aid ()) { // +EEE action_.automaton->lock_execution (); output_locked = true; } // +FFF input_automaton->lock_execution (); } if (!output_locked) { // +EEE action_.automaton->lock_execution (); output_locked = true; } input_action_pos_ = input_action_list_.begin (); } break; case INTERNAL: case SYSTEM: // +EEE action_.automaton->lock_execution (); break; } if (!c->empty ()) { // Automaton has more actions, return to ready queue. ready_queue_.push_back (c); } action_.automaton->execute (*action_.action, action_.parameter, output_buffer_a_, output_buffer_b_); } // Out of actions. action_.automaton = shared_ptr<automaton> (); irq_handler::wait_for_interrupt (); } }
void reset() { cancel(); T value; while (m_queue.pop(value)); }
void dump() { queue_type::stored_ptr entry; while ((entry = queue.pop()) != nullptr) write_entry(std::move(entry)); }
reset_queue_entry(barrier_queue_entry& e, queue_type& q) : e_(e), q_(q), last_(q.last()) {}
void clear() { m_queue.clear(); }
bool empty_unsafe() { return m_queue.empty(); }
/// Check if there is any data in the outgoing_queue to be sent over the socket bool outgoing_not_empty() const { return !m_outgoing_queue.empty(); }
void swap(queue_type &q) { m_mutex.lock(); q.swap(m_queue); m_mutex.unlock(); }
/// Check if there is any space in the outgoing_queue bool outgoing_not_full() const { return !m_outgoing_queue.full(); }
//! get the current size of the queue inline size_t size() { return m_queue.size(); }
/// Check if there is any data in the incoming_queue bool incoming_not_empty() const { return !m_incoming_queue.empty(); }
//! Method for dereferencing the iterator. const_reference operator*() const { return m_queue.front(); }
/// Check if there is any space in the incoming_queue for received packets bool incoming_not_full() const { return !m_incoming_queue.full(); }
void enqueue_( msg_type const& msg) { queue_.push( msg); }
bool empty(unsigned int timeout = 5) { boost::shared_lock<boost::shared_mutex> lock(mutex_, boost::get_system_time() + boost::posix_time::seconds(timeout)); if (!lock.owns_lock()) return false; return queue_.empty(); }
bool full_() const { if ( high_water_mark_ == infinity_) return false; return queue_.size() > high_water_mark_; }
boost::optional<T> top(unsigned int timeout = 5) { boost::shared_lock<boost::shared_mutex> lock(mutex_, boost::get_system_time() + boost::posix_time::seconds(timeout)); if (!lock || queue_.empty()) return boost::optional<T>(); return boost::optional<T>(queue_.front()); }
void flush_() { queue_.clear(); }
void enqueue(queue_element_type* msg) { while (!m_messageQueue.push(msg)) ; }