📄 notifier.hh
字号:
inline NotifierSignalNotifierSignal::overderived_signal(){ return NotifierSignal(&static_value, overderived_mask | true_mask);}inline NotifierSignalNotifierSignal::uninitialized_signal(){ return NotifierSignal(&static_value, uninitialized_mask);}inline boolNotifierSignal::active() const{ if (likely(_mask)) return (*_v.v1 & _mask) != 0; else { for (vmpair *vm = _v.vm; vm->mask; ++vm) if ((*vm->value & vm->mask) != 0) return true; return false; }}inlineNotifierSignal::operator unspecified_bool_type() const{ return active() ? &NotifierSignal::active : 0;}inline boolNotifierSignal::idle() const{ return (_mask == false_mask && _v.v1 == &static_value);}inline boolNotifierSignal::busy() const{ return ((_mask & true_mask) && _v.v1 == &static_value);}inline boolNotifierSignal::overderived() const{ return ((_mask & overderived_mask) && _v.v1 == &static_value);}inline boolNotifierSignal::initialized() const{ return (!(_mask & uninitialized_mask) || _v.v1 != &static_value);}inline voidNotifierSignal::set_active(bool active){ assert(_mask && _v.v1 != &static_value && !(_mask & (_mask - 1))); if (active) *_v.v1 |= _mask; else *_v.v1 &= ~_mask;}inline NotifierSignal &NotifierSignal::operator=(const NotifierSignal &x){ if (likely(this != &x)) { if (unlikely(_mask == 0)) delete[] _v.vm; _mask = x._mask; if (likely(_mask)) _v.v1 = x._v.v1; else hard_assign_vm(x); } return *this;}inline booloperator==(const NotifierSignal& a, const NotifierSignal& b){ if (a._mask == b._mask) { if (likely(a._mask)) return a._v.v1 == b._v.v1; else return NotifierSignal::hard_equals(a._v.vm, b._v.vm); } else return false;}inline booloperator!=(const NotifierSignal& a, const NotifierSignal& b){ return !(a == b);}inline NotifierSignaloperator+(NotifierSignal a, const NotifierSignal& b){ return a += b;}/** @brief Constructs a Notifier. * @param op controls notifier path search * * This function constructs a Notifier object. The Notifier's associated * NotifierSignal is initially idle; it becomes associated with a signal after * initialize() is called. * * The @a op argument controls path search. The rest of this entry * describes it further. * * Elements interested in notification generally search for Notifier objects * along all possible packet paths upstream (or downstream) of one of their * ports. When a Notifier is found along a path, further searching along that * path is cut off, so only the closest Notifiers are found. Sometimes, * however, it makes more sense to continue searching for more Notifiers. The * correct behavior is Notifier-specific, and is controlled by this method. * When the search encounters a Notifier, it consults the Notifier's @a * op variable supplied to the constructor. It should equal one of * three SearchOp constants, which correspond to the following behavior: * * <dl> * <dt>SEARCH_STOP</dt> * <dd>Stop searching along this path. This is the default.</dd> * <dt>SEARCH_CONTINUE</dt> * <dd>Continue searching along this path.</dd> * <dt>SEARCH_CONTINUE_WAKE</dt> * <dd>Continue searching along this path, but any further Notifiers should * only be used for adding and removing listeners; ignore their NotifierSignal * objects. This operation is useful, for example, for schedulers that store * packets temporarily. Such schedulers provide their own NotifierSignal, * since the scheduler may still hold a packet even when all upstream sources * are empty, but since they aren't packet sources, they don't know when * new packets arrive and can't wake up sleeping listeners. During * initialization, such schedulers should call Notifier::upstream_empty_signal, * passing their own Notifier as the fourth argument. This will ensure that * their signal is turned on appropriately whenever an upstream queue becomes * nonempty.</dd> * </dl> */inlineNotifier::Notifier(SearchOp op) : _signal(NotifierSignal::uninitialized_signal()), _search_op(op){}/** @brief Constructs a Notifier associated with a given signal. * @param signal the associated NotifierSignal * @param op controls notifier path search * * This function constructs a Notifier object associated with a specific * NotifierSignal, such as NotifierSignal::idle_signal(). Calling * initialize() on this Notifier will not change the associated * NotifierSignal. The @a op argument is as in * Notifier::Notifier(SearchOp), above. */inlineNotifier::Notifier(const NotifierSignal &signal, SearchOp op) : _signal(signal), _search_op(op){}/** @brief Return this Notifier's associated NotifierSignal. * * Every Notifier object corresponds to one NotifierSignal; this method * returns it. The signal is @link NotifierSignal::idle idle() @endlink * before initialize() is called. */inline const NotifierSignal &Notifier::signal() const{ return _signal;}/** @brief Return this Notifier's search operation. * * @sa Notifier() for a detailed explanation of search operations. */inline Notifier::SearchOpNotifier::search_op() const{ return _search_op;}/** @brief Returns whether the associated signal is active. * * Same as signal().active(). */inline boolNotifier::active() const{ return _signal.active();}/** @brief Sets the associated signal's activity. * @param active true iff the signal should be active */inline voidNotifier::set_active(bool active){ _signal.set_active(active);}/** @brief Sets the associated signal to active. * @sa set_active */inline voidNotifier::wake(){ set_active(true);}/** @brief Sets the associated signal to inactive. * @sa set_active */inline voidNotifier::sleep(){ set_active(false);}/** @brief Sets the associated signal's activity, possibly scheduling any * listener tasks. * @param active true iff the signal should be active * @param schedule if true, wake up listener tasks * * If @a active and @a schedule are both true, and the signal was previously * inactive, then any listener Tasks are scheduled with Task::reschedule(). * * @sa wake, sleep, add_listener */inline voidActiveNotifier::set_active(bool active, bool schedule){ if (active != Notifier::active()) { // 2007.Sep.6: Perhaps there was a race condition here. Make sure // that we set the notifier to active BEFORE rescheduling downstream // tasks. This is because, in a multithreaded environment, a task we // reschedule might run BEFORE we set the notifier; after which it // would go to sleep forever. Notifier::set_active(active); if (active && schedule) { if (_listener1) _listener1->reschedule(); else if (task_or_signal_t *tos = _listeners) { for (; tos->t; tos++) tos->t->reschedule(); for (tos++; tos->s; tos++) tos->s->set_active(true); } } }}/** @brief Sets the associated signal to active and schedules any listener * tasks. * * If the signal was previously inactive, then any listener Tasks are * scheduled with Task::reschedule(). * * @sa set_active, add_listener */inline voidActiveNotifier::wake(){ set_active(true, true);}/** @brief Sets the associated signal to inactive. * @sa set_active */inline voidActiveNotifier::sleep(){ set_active(false, true);}CLICK_ENDDECLS#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -