1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2020 Mellanox Technologies, Ltd
5 #include <rte_interrupts.h>
7 #include "eal_private.h"
8 #include "eal_windows.h"
10 static pthread_t intr_thread;
12 static HANDLE intr_iocp;
15 eal_intr_process(const OVERLAPPED_ENTRY *event)
21 eal_intr_thread_main(LPVOID arg __rte_unused)
24 OVERLAPPED_ENTRY events[16];
28 result = GetQueuedCompletionStatusEx(
29 intr_iocp, events, RTE_DIM(events), &event_count,
30 INFINITE, /* no timeout */
31 TRUE); /* alertable wait for alarm APCs */
34 DWORD error = GetLastError();
35 if (error != WAIT_IO_COMPLETION) {
36 RTE_LOG_WIN32_ERR("GetQueuedCompletionStatusEx()");
37 RTE_LOG(ERR, EAL, "Failed waiting for interrupts\n");
41 /* No I/O events, all work is done in completed APCs. */
45 for (i = 0; i < event_count; i++)
46 eal_intr_process(&events[i]);
51 CloseHandle(intr_iocp);
58 rte_eal_intr_init(void)
62 intr_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
63 if (intr_iocp == NULL) {
64 RTE_LOG_WIN32_ERR("CreateIoCompletionPort()");
65 RTE_LOG(ERR, EAL, "Cannot create interrupt IOCP\n");
69 ret = rte_ctrl_thread_create(&intr_thread, "eal-intr-thread", NULL,
70 eal_intr_thread_main, NULL);
73 RTE_LOG(ERR, EAL, "Cannot create interrupt thread\n");
80 rte_thread_is_intr(void)
82 return pthread_equal(intr_thread, pthread_self());
86 rte_intr_rx_ctl(__rte_unused struct rte_intr_handle *intr_handle,
87 __rte_unused int epfd, __rte_unused int op,
88 __rte_unused unsigned int vec, __rte_unused void *data)
94 eal_intr_thread_schedule(void (*func)(void *arg), void *arg)
98 handle = OpenThread(THREAD_ALL_ACCESS, FALSE, intr_thread);
100 RTE_LOG_WIN32_ERR("OpenThread(%llu)", intr_thread);
104 if (!QueueUserAPC((PAPCFUNC)(ULONG_PTR)func, handle, (ULONG_PTR)arg)) {
105 RTE_LOG_WIN32_ERR("QueueUserAPC()");
113 rte_intr_callback_register(
114 __rte_unused const struct rte_intr_handle *intr_handle,
115 __rte_unused rte_intr_callback_fn cb, __rte_unused void *cb_arg)
121 rte_intr_callback_unregister_pending(
122 __rte_unused const struct rte_intr_handle *intr_handle,
123 __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg,
124 __rte_unused rte_intr_unregister_callback_fn ucb_fn)
130 rte_intr_callback_unregister(
131 __rte_unused const struct rte_intr_handle *intr_handle,
132 __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg)
138 rte_intr_callback_unregister_sync(
139 __rte_unused const struct rte_intr_handle *intr_handle,
140 __rte_unused rte_intr_callback_fn cb_fn, __rte_unused void *cb_arg)
146 rte_intr_enable(__rte_unused const struct rte_intr_handle *intr_handle)
152 rte_intr_ack(__rte_unused const struct rte_intr_handle *intr_handle)
158 rte_intr_disable(__rte_unused const struct rte_intr_handle *intr_handle)
164 rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
166 RTE_SET_USED(intr_handle);
167 RTE_SET_USED(nb_efd);
173 rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
175 RTE_SET_USED(intr_handle);
179 rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
181 RTE_SET_USED(intr_handle);
187 rte_intr_allow_others(struct rte_intr_handle *intr_handle)
189 RTE_SET_USED(intr_handle);
195 rte_intr_cap_multiple(struct rte_intr_handle *intr_handle)
197 RTE_SET_USED(intr_handle);
203 rte_epoll_wait(int epfd, struct rte_epoll_event *events,
204 int maxevents, int timeout)
207 RTE_SET_USED(events);
208 RTE_SET_USED(maxevents);
209 RTE_SET_USED(timeout);
215 rte_epoll_wait_interruptible(int epfd, struct rte_epoll_event *events,
216 int maxevents, int timeout)
219 RTE_SET_USED(events);
220 RTE_SET_USED(maxevents);
221 RTE_SET_USED(timeout);
227 rte_epoll_ctl(int epfd, int op, int fd, struct rte_epoll_event *event)
238 rte_intr_tls_epfd(void)
244 rte_intr_free_epoll_fd(struct rte_intr_handle *intr_handle)
246 RTE_SET_USED(intr_handle);