Hone logo
Hone
Problems

Concurrent Counter with Atomic Operations in Rust

This challenge focuses on implementing a thread-safe counter using Rust's atomic operations. Understanding and utilizing atomic operations is crucial for writing correct and efficient concurrent code, preventing data races and ensuring predictable behavior in multi-threaded environments. You'll be building a simple counter that can be incremented by multiple threads simultaneously without introducing race conditions.

Problem Description

You are tasked with creating a ConcurrentCounter struct that encapsulates an integer value and provides an atomic increment method. The counter should be thread-safe, meaning multiple threads can concurrently call the increment method without corrupting the counter's value. The increment method should atomically increment the counter's internal value by 1. You must use Rust's AtomicI32 type to achieve this. The ConcurrentCounter should also provide a method to retrieve the current value of the counter.

Key Requirements:

  • Thread Safety: The counter must be safe for concurrent access from multiple threads.
  • Atomic Increment: The increment method must use atomic operations to ensure that increments are indivisible and prevent race conditions.
  • Value Retrieval: A method to retrieve the current counter value must be provided.
  • Use AtomicI32: The internal counter must be of type AtomicI32.

Expected Behavior:

When multiple threads concurrently call the increment method, the final counter value should be equal to the total number of increments performed across all threads. The get_value method should return the current atomic value of the counter.

Edge Cases to Consider:

  • Very high increment rates from multiple threads.
  • The counter starting at a non-zero value.
  • Retrieving the value while increments are in progress (should return a consistent, albeit potentially slightly outdated, value).

Examples

Example 1:

Input: Two threads, each incrementing the counter 1000 times.
Output: 2000
Explanation: Both threads increment the counter 1000 times each, resulting in a final value of 2000.

Example 2:

Input: Five threads, each incrementing the counter a different number of times (10, 20, 30, 40, 50).
Output: 150
Explanation: The sum of the increments from each thread (10 + 20 + 30 + 40 + 50) is 150.

Example 3:

Input: One thread increments the counter 100 times, then another thread retrieves the value.
Output: 100
Explanation: The first thread increments the counter to 100, and the second thread retrieves this value.

Constraints

  • The increment method must use AtomicI32's atomic operations (e.g., fetch_add).
  • The get_value method should return the current value as an i32.
  • The solution must compile and run without panics or undefined behavior.
  • Performance is not a primary concern, but the solution should be reasonably efficient.

Notes

  • Rust's AtomicI32 provides methods like fetch_add for atomic addition. Explore these methods to implement the increment function.
  • Consider using a Mutex if you need to perform more complex operations on the counter that cannot be easily expressed with atomic operations alone. However, for this specific problem, atomic operations are sufficient and preferred.
  • Think about how to ensure that the get_value method returns a consistent snapshot of the counter's value, even while increments are happening. The load() method of AtomicI32 is useful for this.
  • Testing with multiple threads and a high number of increments is crucial to verify the thread safety of your solution.
Loading editor...
rust