Skip to content

Keep a segment's time and position math from overflowing in a run of months - #96

Merged
kahrendt merged 2 commits into
mainfrom
issue-94-segment-math-split
Oct 16, 2026
Merged

kahrendt merged 2 commits into
mainfrom
issue-94-segment-math-split

Conversation

@kahrendt

Copy link
Copy Markdown
Contributor

Summary

Within one segment of an anchor, offset_us() and time_position() multiplied a sample count by 10^6 and a microsecond count by the rate in int64. Both overflowed (undefined behavior) once one segment had run about 278 days at 384 kHz, or about 6 years at 48 kHz, so a long-running live input would map positions and cells to wrong times.

Change

  • scaled_floor(), scaled_ceil() and scaled_round() in sched/timeline.h, next to floor_div(): n * mul / div with n split at a multiple of div, so only the remainder's product (below div * mul) is formed. Same results as before wherever the old products fit.
  • offset_us() and time_position() use them. This adds one 64-bit divide per call, per cell or frame, never per sample.
  • Folded in: two products of the same kind in GroupAudio, a resampled instance's start position ((first - origin) * in.rate, undefined after about 4 years at 192 kHz in, 384 kHz out) and finish_drain()'s output count (span * 2 * out_rate, which wrapped in uint64 at the same point). Both run once per instance start or drain.
  • segment_output_index() is unchanged: its picosecond term never exceeds a second, so splitting it would add a divide for nothing.

Tests

  • SchedTimeline.TimeAndPositionYearsIntoOneSegment: one segment of 300 days at 384 kHz and 7 years at 48 and 44.1 kHz maps positions, times and cells as the Control rows at a second (and before p0) do. The 300-day row trips UBSan without the change.
  • SchedTimeline.ScaledDivisionRounding: floor, ceil and half-up rounding of the helpers, negative inputs, and rows whose unsplit product passes 2^63.
  • Gap: the GroupAudio call sites' overflow region is covered only through the helper table, since the pipeline harness cannot reach a segment years long; their wiring is pinned by the existing GroupAudio tests at ordinary durations.

Closes #94

…months

offset_us() and time_position() formed a sample count times 10^6 and a
microsecond count times the rate in int64, which overflowed once one
segment had run about 278 days at 384 kHz or 6 years at 48 kHz. Both now
split the count at a multiple of the divisor (scaled_floor() and
scaled_ceil() in sched/timeline.h), so only the remainder's product is
formed. A resampled instance's start position and a drain's output count
in GroupAudio had the same kind of product and use them too.
@kahrendt
kahrendt marked this pull request as ready for review October 16, 2026 12:04
Copilot AI balanced review requested due to automatic review settings October 16, 2026 12:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new helpers still have intermediate overflows for valid boundary inputs whose results fit int64.

1 open finding
What changed in this PR

Addresses #94 by reducing intermediate overflow in timeline and resampling calculations for long-running audio streams.

Changes:

  • Adds scaled floor, ceiling, and rounding helpers.
  • Applies them to timeline mappings and resampling start/drain calculations.
  • Adds rounding and months-to-years regression cases.
File Description
tests/​test_sched_timeline.cpp Adds scaled-arithmetic and long-duration mapping tests.
src/​sched/​timeline.h Defines the scaled division helpers.
src/​sched/​timeline.cpp Uses helpers for position/time conversions.
src/​group_audio.cpp Uses helpers for resampling start and drain counts.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/sched/timeline.h
The bound covers scaled_round()'s numerator, and the doc no longer
claims that only a result past int64 can overflow.
@kahrendt
kahrendt merged commit 92e811d into main Oct 16, 2026
13 checks passed
@kahrendt
kahrendt deleted the issue-94-segment-math-split branch October 16, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Keep a segment's time and position math from overflowing in a run of months

2 participants