Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(pkg/counter): finish making counter atomic #3276

Merged
merged 1 commit into from
Jun 28, 2023
Merged

fix(pkg/counter): finish making counter atomic #3276

merged 1 commit into from
Jun 28, 2023

Conversation

rafaeldtinoco
Copy link
Contributor

@rafaeldtinoco rafaeldtinoco commented Jun 27, 2023

a6817c1 fix(pkg/counter): finish making counter atomic _(2023/Jun/27) Rafael David Tinoco <raf>

Last changes renamed Increment/Decrement to Increase/Decrease. This was
reverted after discussions.

With this new approach:

- Overflow is detected in both cases (and proved by test).
- Thread safety is guaranteed by atomic Add/Sub operations.
- Unit tests prove all assumptions and thread safety for all cases.

NOTE: The issue is now fully fixed...

Originally, the bug was only about reading counter value in parallel to
atomic operation (multiple LOAD/STORE simultaneously, and some not
protected by atomics).

Previous fix, made by commit 1e54ce292, fixed data race but overflow errors
could be reported more than once. It also had atomic operations for each
given argument (if multiple arguments).

This version addresses all concerns.

Heavily influenced by conversations after #3265 (and offline).

pkg/counter/counter.go Outdated Show resolved Hide resolved
Copy link
Member

@geyslan geyslan left a comment

Choose a reason for hiding this comment

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

I reviewed and identified some corner cases to be checked. Also suggested a change in the zeroed value tests to contemplate slice of zeroes.

pkg/counter/counter.go Show resolved Hide resolved
pkg/counter/counter.go Show resolved Hide resolved
pkg/counter/counter.go Show resolved Hide resolved
pkg/counter/counter_test.go Show resolved Hide resolved
pkg/counter/counter_test.go Show resolved Hide resolved
@rafaeldtinoco
Copy link
Contributor Author

I've included benchmark tests, and removed the extra check for x > 0 that was a leftover. All the rest I believe we are good.

@rafaeldtinoco
Copy link
Contributor Author

rafaeldtinoco commented Jun 27, 2023

@geyslan Added tests for (0) and (0,0,0). Added benchmarks for all cases:

  • Inc()
  • Inc(x)
  • Inc(0)
  • Inc(0,0,0)

The extra cost for checking if val > 0 (about 200ns) is almost 1/2 of the cost of the function entirely (so unless > 50% of the calls of Increment are Increment(0) it wouldn't be worth adding a short circuit).

There is an extra cost of having "argument slice" as well (differences among benchmarks of Inc() and Inc(0) also sums that.

Hope that answers your concerns.

PS: I fixed the extra x > 0 check that was leftover.

Thanks for the review.

NOTE: IF we decide to remove the []uint64 as the argument of the API, I can change this PR.

Copy link
Collaborator

@NDStrahilevitz NDStrahilevitz left a comment

Choose a reason for hiding this comment

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

Simple and more importantly thread-safe, LGTM. Added some styling suggestions but nothing critical.

NOTE: IF we decide to remove the []uint64 as the argument of the API, I can change this PR.

That said, i'm definitely in favor of this.

pkg/counter/counter.go Outdated Show resolved Hide resolved
pkg/counter/counter_test.go Outdated Show resolved Hide resolved
pkg/counter/counter.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@yanivagman yanivagman left a comment

Choose a reason for hiding this comment

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

LGTM

Last changes renamed Increment/Decrement to Increase/Decrease. This was
reverted after discussions.

With this new approach:

- Overflow is detected in both cases (and proved by test).
- Thread safety is guaranteed by atomic Add/Sub operations.
- Unit tests prove all assumptions and thread safety for all cases.
- Benchmark tests can be used to test other approaches in the future.
- Overflow of a sum of all given arguments isn't detected (avoid overhead).

NOTE: The issue is now fully fixed...

Originally, the bug was only about reading counter value in parallel to
atomic operation (multiple LOAD/STORE simultaneously, and some not
protected by atomics).

Previous fix, made by commit 1e54ce2, fixed data race but overflow errors
could be reported more than once. It also had atomic operations for each
given argument (if multiple arguments).

This version addresses all concerns.
@rafaeldtinoco rafaeldtinoco dismissed geyslan’s stale review June 28, 2023 13:11

already got an approval, lero lero =D

@rafaeldtinoco rafaeldtinoco merged commit 0b97409 into aquasecurity:main Jun 28, 2023
@rafaeldtinoco rafaeldtinoco deleted the counter-final-set branch June 28, 2023 13:26
rafaeldtinoco added a commit that referenced this pull request Jun 28, 2023
Last changes renamed Increment/Decrement to Increase/Decrease. This was
reverted after discussions.

With this new approach:

- Overflow is detected in both cases (and proved by test).
- Thread safety is guaranteed by atomic Add/Sub operations.
- Unit tests prove all assumptions and thread safety for all cases.
- Benchmark tests can be used to test other approaches in the future.
- Overflow of a sum of all given arguments isn't detected (avoid overhead).

NOTE: The issue is now fully fixed...

Originally, the bug was only about reading counter value in parallel to
atomic operation (multiple LOAD/STORE simultaneously, and some not
protected by atomics).

Previous fix, made by commit 1e54ce2, fixed data race but overflow errors
could be reported more than once. It also had atomic operations for each
given argument (if multiple arguments).

This version addresses all concerns.

commit: 0b97409 (main), cherry-pick
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants