Welcome back to my hello-ebpf series. Last week, we learned about lottery schedulers and how to implement one with sched-ext and hello-ebpf. But there was one major issue when writing the scheduler in Java: hello-ebpf lacked support for the bpf_for_each macro. This is what this weeks short blog post is all about.
To loop over all elements in the scheduling queue, to pick a random one, we had to write inline C code. A simplified version without scheduling priorities looks like the following:
@Override
public void dispatch(int cpu, Ptr<TaskDefinitions.task_struct> prev) {
String CODE = """
// pick a random task struct index
s32 random = bpf_get_prandom_u32() %
scx_bpf_dsq_nr_queued(SHARED_DSQ_ID);
struct task_struct *p = NULL;
bpf_for_each(scx_dsq, p, SHARED_DSQ_ID, 0) {
// iterate till we get to this number
random = random - 1;
// and try to dispatch it
if (random <= 0 &&
tryDispatching(BPF_FOR_EACH_ITER, p, cpu)) {
return 0;
}
};
return 0;
""";
}
This surely works, but inline C code is not the most readable and writing it is error-prone. I’ve written on this topic in my post Hello eBPF: Write your eBPF application in Pure Java (12) before. So what was keeping us from supporting the bpf_for_each macro? Support for lambdas as arguments to built-in bpf functions.
Lottery Scheduler in Pure Java
May I introduce you know the support for directly passed lambda expressions: This let’s us define a bpf_for_each_dsq function and to write a simple lottery scheduler in pure Java:

