]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: haload: split the rate exactly across threads
authorFrederic Lecaille <flecaille@haproxy.com>
Fri, 21 Aug 2026 16:26:38 +0000 (18:26 +0200)
committerFrederic Lecaille <flecaille@haproxy.com>
Mon, 24 Aug 2026 17:16:05 +0000 (19:16 +0200)
hld_usr_schedule() and hld_rate_task() gave every thread ceil(rate /
arg_thrd), so a low rate on a machine with many threads was quietly
served several times over (e.g. rate=1 on 200 threads gave ~200 req/s
instead of 1). Use the same exact split already used elsewhere in
haload (thread <tid> gets (rate + tid) / arg_thrd): most threads then
get 0 and only <rate> of them get 1, so the total always matches
<rate> regardless of the thread count.

A thread with no budget now just checks back in 1s instead of being
bumped to 1 by the old max ? max : 1 fallback.

src/haload.c

index fa44cd931a60ecc166c4ca95714e803cb82dee47..0dbae94c657103873f977304fdb4b5a37f2efd1a 100644 (file)
@@ -1413,11 +1413,19 @@ static inline void hld_usr_schedule(struct hld_usr *usr, int rate)
        if (ti->curusrs < maxusrs && throttle)
                max = 0;
        else if (throttle)
-               max = (mul32hi(rate, throttle) + arg_thrd - 1) / arg_thrd;
+               max = (mul32hi(rate, throttle) + tid) / arg_thrd;
        else
-               max = (rate + arg_thrd - 1) / arg_thrd;
+               max = (rate + tid) / arg_thrd;
+
+       if (!max) {
+               /* this thread has no budget right now (its exact share of
+                * <rate> is 0, or it's still ramping up under -s): nothing
+                * to send from here, just check back shortly.
+                */
+               task_schedule(usr->task, tick_add(now_ms, MS_TO_TICKS(1000)));
+               return;
+       }
 
-       max = max ? max : 1;
        wait = hld_next_event_delay(&ti->req_rate, max,
                                    ti->curusrs - ti->cur_req, date);
        task_schedule(usr->task, tick_add(now_ms, MS_TO_TICKS(wait)));