1 /* SPDX-License-Identifier: Apache-2.0
2 * Copyright (c) 2023 Cisco Systems, Inc.
5 #ifndef included_clib_interrupt_h
6 #define included_clib_interrupt_h
8 #include <vppinfra/clib.h>
9 #include <vppinfra/vec.h>
13 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
19 } clib_interrupt_header_t;
21 void clib_interrupt_init (void **data, u32 n_interrupts);
22 void clib_interrupt_resize (void **data, u32 n_interrupts);
24 static_always_inline void
25 clib_interrupt_free (void **data)
29 clib_mem_free (data[0]);
34 static_always_inline int
35 clib_interrupt_get_n_int (void *d)
37 clib_interrupt_header_t *h = d;
43 static_always_inline void
44 clib_interrupt_set (void *in, int int_num)
46 clib_interrupt_header_t *h = in;
47 u32 off = int_num >> log2_uword_bits;
48 uword bit = 1ULL << (int_num & pow2_mask (log2_uword_bits));
50 ASSERT (int_num < h->n_int);
55 static_always_inline void
56 clib_interrupt_set_atomic (void *in, int int_num)
58 clib_interrupt_header_t *h = in;
59 u32 off = int_num >> log2_uword_bits;
60 uword bit = 1ULL << (int_num & pow2_mask (log2_uword_bits));
62 ASSERT (int_num < h->n_int);
64 __atomic_fetch_or (h->remote + off, bit, __ATOMIC_RELAXED);
67 static_always_inline void
68 clib_interrupt_clear (void *in, int int_num)
70 clib_interrupt_header_t *h = in;
71 u32 off = int_num >> log2_uword_bits;
72 uword bit = 1ULL << (int_num & pow2_mask (log2_uword_bits));
73 uword *loc = h->local;
74 uword *rem = h->remote;
77 ASSERT (int_num < h->n_int);
79 v = loc[off] | __atomic_exchange_n (rem + off, 0, __ATOMIC_SEQ_CST);
83 static_always_inline int
84 clib_interrupt_get_next_and_clear (void *in, int last)
86 clib_interrupt_header_t *h = in;
88 uword *loc = h->local;
89 uword *rem = h->remote;
90 u32 off, n_uwords = h->uwords_used;
92 ASSERT (last >= -1 && last < (int) h->n_int);
94 off = (last + 1) >> log2_uword_bits;
99 v = loc[off] | __atomic_exchange_n (rem + off, 0, __ATOMIC_SEQ_CST);
102 v &= ~pow2_mask ((last + 1) & pow2_mask (log2_uword_bits));
106 if (++off == n_uwords)
109 v = loc[off] | __atomic_exchange_n (rem + off, 0, __ATOMIC_SEQ_CST);
113 bit = get_lowest_set_bit (v);
115 return get_lowest_set_bit_index (bit) + (int) (off << log2_uword_bits);
118 static_always_inline int
119 clib_interrupt_is_any_pending (void *in)
121 clib_interrupt_header_t *h = in;
122 u32 n_uwords = h->uwords_used;
123 uword *loc = h->local;
124 uword *rem = h->remote;
126 for (u32 i = 0; i < n_uwords; i++)
130 for (u32 i = 0; i < n_uwords; i++)
137 #endif /* included_clib_interrupt_h */