1#ifndef TAMER_DINTERNAL_HH
2#define TAMER_DINTERNAL_HH 1
11struct driver_fd :
public T {
15 template <
typename O>
inline driver_fd(O owner,
int fd);
16 inline bool empty()
const;
22 inline driver_fdset();
23 inline ~driver_fdset();
25 template <
typename O>
inline void expand(O owner,
int need_fd);
26 inline void push_change(
int fd);
27 inline int pop_change();
28 inline bool has_change()
const;
30 inline int size()
const;
31 inline const driver_fd<T>& operator[](
int fd)
const;
32 inline driver_fd<T>& operator[](
int fd);
35 enum { fdblksiz = 256 };
36 driver_fd<T>** fdblk_;
37 driver_fd<T>* fdblk0_;
39 unsigned fdcap_ = fdblksiz;
40 unsigned changedfd1_ = 0;
41 struct alignas(driver_fd<T>) dfdspace {
42 unsigned char padding[
sizeof(driver_fd<T>)];
44 dfdspace fdspace_[fdblksiz];
46 inline driver_fd<T>& at(
unsigned fd);
47 inline const driver_fd<T>& at(
unsigned fd)
const;
48 template <
typename O>
void hard_expand(O owner,
int need_fd);
51struct driver_asapset {
52 inline ~driver_asapset();
54 inline bool empty()
const;
55 inline void push(simple_event* se);
56 inline void pop_trigger();
60 simple_event** ses_ =
nullptr;
63 unsigned capmask_ = ~0U;
68struct driver_timerset {
69 inline ~driver_timerset();
71 inline bool empty()
const;
72 inline bool has_foreground()
const;
73 inline const timeval& expiry()
const;
75 void push(timeval when, simple_event* se,
bool bg);
76 inline void pop_trigger();
86 inline bool operator<(
const trec &x)
const;
92 mutable unsigned nts_ = 0;
93 mutable unsigned nfg_ = 0;
94 unsigned rand_ = 8173;
98 static inline unsigned heap_parent(
unsigned i);
99 static inline unsigned heap_first_child(
unsigned i);
100 inline unsigned heap_last_child(
unsigned i)
const;
101 void hard_cull(
unsigned pos)
const;
106template <
typename T>
template <
typename O>
107inline driver_fd<T>::driver_fd(O owner,
int fd)
108 : T(owner, fd), next_changedfd1(0) {
112inline bool driver_fd<T>::empty()
const {
113 return e[0].empty() && e[1].empty() && e[2].empty();
117inline void driver_fd<T>::clear() {
118 e[0].trigger(outcome::destroy);
119 e[1].trigger(outcome::destroy);
120 e[2].trigger(outcome::destroy);
124inline driver_fd<T>& driver_fdset<T>::at(
unsigned fd) {
125 return fdblk_[fd / fdblksiz][fd % fdblksiz];
129inline const driver_fd<T>& driver_fdset<T>::at(
unsigned fd)
const {
130 return fdblk_[fd / fdblksiz][fd % fdblksiz];
134inline driver_fdset<T>::driver_fdset()
135 : fdblk_(&fdblk0_), fdblk0_(reinterpret_cast<driver_fd<T>*>(fdspace_)) {
139inline driver_fdset<T>::~driver_fdset() {
140 for (
unsigned i = 0; i < nfds_; ++i) {
141 at(i).~driver_fd<T>();
143 for (
unsigned i = 1; i < fdcap_ / fdblksiz; ++i) {
144 delete[]
reinterpret_cast<dfdspace*
>(fdblk_[i]);
146 if (fdcap_ > fdblksiz) {
151template <
typename T>
template <
typename O>
152void driver_fdset<T>::expand(O owner,
int need_fd) {
153 if (need_fd >= (
int) nfds_) {
154 hard_expand(owner, need_fd);
158template <
typename T>
template <
typename O>
159void driver_fdset<T>::hard_expand(O owner,
int need_fd) {
160 if (need_fd >= (
int) fdcap_) {
161 unsigned newfdcap = (need_fd | (fdblksiz - 1)) + 1;
162 driver_fd<T>** newfdblk =
new driver_fd<T>*[newfdcap / fdblksiz];
163 for (
unsigned i = 0; i < newfdcap / fdblksiz; ++i) {
164 if (i < fdcap_ / fdblksiz) {
165 newfdblk[i] = fdblk_[i];
167 newfdblk[i] =
reinterpret_cast<driver_fd<T>*
>(
new dfdspace[fdblksiz]);
170 if (fdcap_ > fdblksiz) {
177 while (need_fd >= (
int) nfds_) {
178 new((
void*) &at(nfds_)) driver_fd<T>(owner, nfds_);
184inline bool driver_fdset<T>::has_change()
const {
185 return changedfd1_ != 0;
189inline void driver_fdset<T>::push_change(
int fd) {
190 assert(fd >= 0 && (
unsigned) fd < nfds_);
191 if (at(fd).next_changedfd1 == 0) {
192 at(fd).next_changedfd1 = changedfd1_;
193 changedfd1_ = fd + 1;
198inline int driver_fdset<T>::pop_change() {
199 int fd = changedfd1_ - 1;
201 changedfd1_ = at(fd).next_changedfd1;
202 at(fd).next_changedfd1 = 0;
208inline int driver_fdset<T>::size()
const {
213inline const driver_fd<T>& driver_fdset<T>::operator[](
int fd)
const {
214 assert((
unsigned) fd < nfds_);
219inline driver_fd<T>& driver_fdset<T>::operator[](
int fd) {
220 assert((
unsigned) fd < nfds_);
224inline void* make_fd_callback(
const driver* d,
int fd) {
225 uintptr_t x = d->index() + fd * driver::capacity;
226 return reinterpret_cast<void*
>(x);
229inline driver* fd_callback_driver(
void* callback) {
230 uintptr_t x =
reinterpret_cast<uintptr_t
>(callback);
231 return driver::by_index(x % driver::capacity);
234inline int fd_callback_fd(
void* callback) {
235 uintptr_t x =
reinterpret_cast<uintptr_t
>(callback);
236 return x / driver::capacity;
239inline driver_asapset::~driver_asapset() {
244inline bool driver_asapset::empty()
const {
245 return head_ == tail_;
248inline void driver_asapset::push(simple_event *se) {
249 if (tail_ - head_ == capmask_ + 1) {
252 ses_[tail_ & capmask_] = se;
256inline void driver_asapset::pop_trigger() {
257 assert(head_ != tail_);
258 simple_event* se = ses_[head_ & capmask_];
260 se->simple_trigger(
false);
263inline driver_timerset::~driver_timerset() {
268inline bool driver_timerset::empty()
const {
272inline bool driver_timerset::has_foreground()
const {
276inline const timeval &driver_timerset::expiry()
const {
281inline void driver_timerset::cull() {
282 while (nts_ != 0 && ts_[0].se->empty()) {
287inline bool driver_timerset::trec::operator<(
const trec &x)
const {
288 return when.tv_sec < x.when.tv_sec
289 || (when.tv_sec == x.when.tv_sec
290 && (when.tv_usec < x.when.tv_usec
291 || (when.tv_usec == x.when.tv_usec
292 && (int) (order - x.order) < 0)));
295inline void driver_timerset::trec::clean() {
296 simple_event::unuse_clean(se);
299inline unsigned driver_timerset::heap_parent(
unsigned i) {
300 return (i - (arity == 2)) / arity;
303inline unsigned driver_timerset::heap_first_child(
unsigned i) {
304 return i * arity + (arity == 2 || i == 0);
307inline unsigned driver_timerset::heap_last_child(
unsigned i)
const {
308 unsigned p = i * arity + arity + (arity == 2);
309 return p < nts_ ? p : nts_;
312inline void driver_timerset::pop_trigger() {
313 hard_cull((
unsigned) -1);
Functions for registering primitive events and managing the event loop.
The event template classes and helper functions.
Namespace containing public Tamer classes and functions for the Tamer core.
Definition adapter.hh:17