#include <rte_interrupts.h>
+#include "eal_private.h"
+#include "eal_windows.h"
+
+static pthread_t intr_thread;
+
+static HANDLE intr_iocp;
+
+static void
+eal_intr_process(const OVERLAPPED_ENTRY *event)
+{
+ RTE_SET_USED(event);
+}
+
+static void *
+eal_intr_thread_main(LPVOID arg __rte_unused)
+{
+ while (1) {
+ OVERLAPPED_ENTRY events[16];
+ ULONG event_count, i;
+ BOOL result;
+
+ result = GetQueuedCompletionStatusEx(
+ intr_iocp, events, RTE_DIM(events), &event_count,
+ INFINITE, /* no timeout */
+ TRUE); /* alertable wait for alarm APCs */
+
+ if (!result) {
+ DWORD error = GetLastError();
+ if (error != WAIT_IO_COMPLETION) {
+ RTE_LOG_WIN32_ERR("GetQueuedCompletionStatusEx()");
+ RTE_LOG(ERR, EAL, "Failed waiting for interrupts\n");
+ break;
+ }
+
+ /* No I/O events, all work is done in completed APCs. */
+ continue;
+ }
+
+ for (i = 0; i < event_count; i++)
+ eal_intr_process(&events[i]);
+ }
+
+ CloseHandle(intr_iocp);
+ intr_iocp = NULL;
+ return NULL;
+}
+
+int
+rte_eal_intr_init(void)
+{
+ int ret = 0;
+
+ intr_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
+ if (intr_iocp == NULL) {
+ RTE_LOG_WIN32_ERR("CreateIoCompletionPort()");
+ RTE_LOG(ERR, EAL, "Cannot create interrupt IOCP\n");
+ return -1;
+ }
+
+ ret = rte_ctrl_thread_create(&intr_thread, "eal-intr-thread", NULL,
+ eal_intr_thread_main, NULL);
+ if (ret != 0) {
+ rte_errno = -ret;
+ RTE_LOG(ERR, EAL, "Cannot create interrupt thread\n");
+ }
+
+ return ret;
+}
+
+int
+rte_thread_is_intr(void)
+{
+ return pthread_equal(intr_thread, pthread_self());
+}
+
int
rte_intr_rx_ctl(__rte_unused struct rte_intr_handle *intr_handle,
__rte_unused int epfd, __rte_unused int op,
{
return -ENOTSUP;
}
+
+int
+eal_intr_thread_schedule(void (*func)(void *arg), void *arg)
+{
+ HANDLE handle;
+
+ handle = OpenThread(THREAD_ALL_ACCESS, FALSE, intr_thread);
+ if (handle == NULL) {
+ RTE_LOG_WIN32_ERR("OpenThread(%llu)", intr_thread);
+ return -ENOENT;
+ }
+
+ if (!QueueUserAPC((PAPCFUNC)(ULONG_PTR)func, handle, (ULONG_PTR)arg)) {
+ RTE_LOG_WIN32_ERR("QueueUserAPC()");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int
+rte_intr_callback_register(
+ __rte_unused const struct rte_intr_handle *intr_handle,
+ __rte_unused rte_intr_callback_fn cb, __rte_unused void *cb_arg)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_intr_callback_unregister_pending(
+ __rte_unused const struct rte_intr_handle *intr_handle,
+ __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg,
+ __rte_unused rte_intr_unregister_callback_fn ucb_fn)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_intr_callback_unregister(
+ __rte_unused const struct rte_intr_handle *intr_handle,
+ __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg)
+{
+ return 0;
+}
+
+int
+rte_intr_callback_unregister_sync(
+ __rte_unused const struct rte_intr_handle *intr_handle,
+ __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg)
+{
+ return 0;
+}
+
+int
+rte_intr_enable(__rte_unused const struct rte_intr_handle *intr_handle)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_intr_ack(__rte_unused const struct rte_intr_handle *intr_handle)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_intr_disable(__rte_unused const struct rte_intr_handle *intr_handle)
+{
+ return -ENOTSUP;
+}
+
+int
+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
+{
+ RTE_SET_USED(intr_handle);
+ RTE_SET_USED(nb_efd);
+
+ return 0;
+}
+
+void
+rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+}
+
+int
+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+
+ return 0;
+}
+
+int
+rte_intr_allow_others(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+
+ return 1;
+}
+
+int
+rte_intr_cap_multiple(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+
+ return 0;
+}
+
+int
+rte_epoll_wait(int epfd, struct rte_epoll_event *events,
+ int maxevents, int timeout)
+{
+ RTE_SET_USED(epfd);
+ RTE_SET_USED(events);
+ RTE_SET_USED(maxevents);
+ RTE_SET_USED(timeout);
+
+ return -ENOTSUP;
+}
+
+int
+rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events,
+ int maxevents, int timeout)
+{
+ RTE_SET_USED(epfd);
+ RTE_SET_USED(events);
+ RTE_SET_USED(maxevents);
+ RTE_SET_USED(timeout);
+
+ return -ENOTSUP;
+}
+
+int
+rte_epoll_ctl(int epfd, int op, int fd, struct rte_epoll_event *event)
+{
+ RTE_SET_USED(epfd);
+ RTE_SET_USED(op);
+ RTE_SET_USED(fd);
+ RTE_SET_USED(event);
+
+ return -ENOTSUP;
+}
+
+int
+rte_intr_tls_epfd(void)
+{
+ return -ENOTSUP;
+}
+
+void
+rte_intr_free_epoll_fd(struct rte_intr_handle *intr_handle)
+{
+ RTE_SET_USED(intr_handle);
+}