REORG: fd: move the speculative I/O management from ev_sepoll
The speculative I/O will need to be ported to all pollers, so move
this to fd.c.
diff --git a/include/proto/fd.h b/include/proto/fd.h
index 240a2e2..f0265b7 100644
--- a/include/proto/fd.h
+++ b/include/proto/fd.h
@@ -30,6 +30,12 @@
#include <common/config.h>
#include <types/fd.h>
+/* public variables */
+extern int fd_nbspec; // number of speculative events in the list
+extern int fd_nbupdt; // number of updates in the list
+extern unsigned int *fd_spec; // speculative I/O list
+extern unsigned int *fd_updt; // FD updates list
+
/* Deletes an FD from the fdsets, and recomputes the maxfd limit.
* The file descriptor is also closed.
*/
@@ -70,7 +76,49 @@
*/
void run_poller();
+/* Mark fd <fd> as updated and allocate an entry in the update list for this if
+ * it was not already there. This can be done at any time.
+ */
+static inline void updt_fd(const int fd)
+{
+ if (fdtab[fd].updated)
+ /* already scheduled for update */
+ return;
+ fd_updt[fd_nbupdt++] = fd;
+ fdtab[fd].updated = 1;
+}
+
+
+/* allocate an entry for a speculative event. This can be done at any time. */
+static inline void alloc_spec_entry(const int fd)
+{
+ if (fdtab[fd].spec_p)
+ /* FD already in speculative I/O list */
+ return;
+ fd_spec[fd_nbspec++] = fd;
+ fdtab[fd].spec_p = fd_nbspec;
+}
+
+/* Removes entry used by fd <fd> from the spec list and replaces it with the
+ * last one. The fdtab.spec is adjusted to match the back reference if needed.
+ * If the fd has no entry assigned, return immediately.
+ */
+static inline void release_spec_entry(int fd)
+{
+ unsigned int pos;
+
-#define EV_FD_ISSET(fd, ev) (cur_poller.is_set((fd), (ev)))
+ pos = fdtab[fd].spec_p;
+ if (!pos)
+ return;
+ fdtab[fd].spec_p = 0;
+ fd_nbspec--;
+ if (pos <= fd_nbspec) {
+ /* was not the last entry */
+ fd = fd_spec[fd_nbspec];
+ fd_spec[pos - 1] = fd;
+ fdtab[fd].spec_p = pos;
+ }
+}
/* event manipulation primitives for use by I/O callbacks */
static inline void fd_want_recv(int fd)
diff --git a/include/types/fd.h b/include/types/fd.h
index a99c6bf..fab0c6c 100644
--- a/include/types/fd.h
+++ b/include/types/fd.h
@@ -25,13 +25,13 @@
#include <common/config.h>
#include <types/port_range.h>
+/* Direction for each FD event update */
enum {
DIR_RD=0,
DIR_WR=1,
- DIR_SIZE
};
-/*
+/* Polling status flags returned in fdtab[].ev :
* FD_POLL_IN remains set as long as some data is pending for read.
* FD_POLL_OUT remains set as long as the fd accepts to write data.
* FD_POLL_ERR and FD_POLL_ERR remain set forever (until processed).
@@ -45,6 +45,26 @@
#define FD_POLL_DATA (FD_POLL_IN | FD_POLL_OUT)
#define FD_POLL_STICKY (FD_POLL_ERR | FD_POLL_HUP)
+/* Event state for an FD in each direction, as found in the 4 lower bits of
+ * fdtab[].spec_e, and in the 4 next bits.
+ */
+#define FD_EV_ACTIVE 1U
+#define FD_EV_POLLED 4U
+#define FD_EV_STATUS (FD_EV_ACTIVE | FD_EV_POLLED)
+#define FD_EV_STATUS_R (FD_EV_STATUS)
+#define FD_EV_STATUS_W (FD_EV_STATUS << 1)
+
+#define FD_EV_POLLED_R (FD_EV_POLLED)
+#define FD_EV_POLLED_W (FD_EV_POLLED << 1)
+#define FD_EV_POLLED_RW (FD_EV_POLLED_R | FD_EV_POLLED_W)
+
+#define FD_EV_ACTIVE_R (FD_EV_ACTIVE)
+#define FD_EV_ACTIVE_W (FD_EV_ACTIVE << 1)
+#define FD_EV_ACTIVE_RW (FD_EV_ACTIVE_R | FD_EV_ACTIVE_W)
+
+#define FD_EV_CURR_MASK 0x0FU
+#define FD_EV_PREV_MASK 0xF0U
+
/* info about one given fd */
struct fdtab {
int (*iocb)(int fd); /* I/O handler, returns FD_WAIT_* */