Add single-bit test and iterator over set cids in an scx_cmask. v2: Bound scx_cmask_for_each_cid() to the active span. (sashiko AI)
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -225,4 +225,47 @@ static inline void __scx_cmask_set(u32 cid, struct scx_cmask *m) · 224 unmodified lines | |||
| 225 | *__scx_cmask_word(cid, m) |= BIT_U64(cid & 63); | 225 | *__scx_cmask_word(cid, m) |= BIT_U64(cid & 63); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | /** | ||
| 229 | * scx_cmask_test - test whether @cid is set in @m | ||
| 230 | * @cid: cid to test | ||
| 231 | * @m: cmask to test | ||
| 232 | * | ||
| 233 | * Return %false if @cid is outside @m's active range. Otherwise return the | ||
| 234 | * bit's value. Read via READ_ONCE so callers can race set/clear writers. | ||
| 235 | */ | ||
| 236 | static inline bool scx_cmask_test(u32 cid, const struct scx_cmask *m) | ||
| 237 | { | ||
| 238 | if (!__scx_cmask_contains(cid, m)) | ||
| 239 | return false; | ||
| 240 | return READ_ONCE(*__scx_cmask_word(cid, m)) & BIT_U64(cid & 63); | ||
| 241 | } | ||
| 242 | |||
| 243 | /* | ||
| 244 | * Words of bits[] the active range spans, 0 if empty. Tighter than the storage | ||
| 245 | * SCX_CMASK_NR_WORDS() sizes for the worst-case base alignment. | ||
| 246 | */ | ||
| 247 | static inline u32 scx_cmask_nr_used_words(const struct scx_cmask *m) | ||
| 248 | { | ||
| 249 | if (!m->nr_cids) | ||
| 250 | return 0; | ||
| 251 | return ((m->base & 63) + m->nr_cids - 1) / 64 + 1; | ||
| 252 | } | ||
| 253 | |||
| 254 | /** | ||
| 255 | * scx_cmask_for_each_cid - iterate set cids in @m | ||
| 256 | * @cid: s32 loop var that receives each set cid in turn | ||
| 257 | * @m: cmask to iterate | ||
| 258 | * | ||
| 259 | * Visits set bits within @m's active range in ascending order. Scans only the | ||
| 260 | * words the active range spans, where head and tail padding is kept zero, so | ||
| 261 | * no per-cid range check is needed. | ||
| 262 | */ | ||
| 263 | #define scx_cmask_for_each_cid(cid, m) \ | ||
| 264 | for (u64 __bs = (m)->base & ~63u, __wi = 0, \ | ||
| 265 | __nw = scx_cmask_nr_used_words(m); \ | ||
| 266 | __wi < __nw; __wi++) \ | ||
| 267 | for (u64 __w = READ_ONCE((m)->bits[__wi]); \ | ||
| 268 | __w && ((cid) = __bs + __wi * 64 + __ffs64(__w), true); \ | ||
| 269 | __w &= __w - 1) | ||
| 270 | |||
| 228 | #endif /* _KERNEL_SCHED_EXT_CID_H */ | 271 | #endif /* _KERNEL_SCHED_EXT_CID_H */ |