Pppd896engsub Convert015838 | Min Exclusive

| Situation | Result | |-----------|--------| | raw_counter == min && min_exclusive == true | Error (-EINVAL). | | raw_counter < min && min_exclusive == false | out_converted = min. | | raw_counter > max | out_converted = max. | | max < min | Error (-ERANGE). | | raw_counter == UINT64_MAX | Returns the exact max value (no overflow). | | max‑min does not fit in 64‑bits | Compile‑time static assertion fails; the API cannot be used on that platform. |


The expression raw_counter * range produces a 128‑bit product. Shifting right by 64 bits is mathematically equivalent to dividing by 2⁶⁴ (the size of the source space). This yields a perfectly rounded‑down linear mapping, which matches the historic behavior of the original PPPD firmware. pppd896engsub convert015838 min exclusive

For high‑throughput line cards the function is inlined into a vectorised loop: | Situation | Result | |-----------|--------| | raw_counter

    // Pseudo‑assembly – process 4 counters per iteration
    LD4    v0.2d, v1.2d, v2.2d, v3.2d, [x0], #64   // load raw counters
    SUB    v0.2d, v0.2d, v4.2d                     // subtract min
    UMULL  v0.4s, v0.2d, v5.2d                     // 64×64→128 mul (Neon)
    ...   // shift, add min, store

The SIMD version yields a ~2.2× throughput gain on Cortex‑A78 cores when processing 64‑bit counters in bulk. The expression raw_counter * range produces a 128‑bit


convert015838 takes a raw 64‑bit counter (e.g., a cumulative number of transmitted octets) and maps it onto a target range [min, max]. The conversion obeys the following rules:

# pppd.conf – example fragment
[interface "dsl0"]
min_counter      = 1000          ; lower bound for the exported metric
max_counter      = 5000000000    ; upper bound
min_exclusive    = true          ; treat the lower bound as exclusive

The PPPD daemon reads these values on start‑up and passes them to the conversion routine each time a counter is harvested.