Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3342092
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T00:47:53+00:00 2026-05-18T00:47:53+00:00

I must be just having a moment, because this should be easy but I

  • 0

I must be just having a moment, because this should be easy but I can’t seem to get it working right.

Whats the correct way to implement an atomic counter in GCC?

i.e. I want a counter that runs from zero to 4 and is thread safe.

I was doing this (which is further wrapped in a class, but not here)

static volatile int _count = 0;
const int limit = 4;

int get_count(){
  // Create a local copy of diskid
  int save_count = __sync_fetch_and_add(&_count, 1);
  if (save_count >= limit){
      __sync_fetch_and_and(&_count, 0); // Set it back to zero
  }
  return save_count;
}

But it’s running from 1 through from 1 – 4 inclusive then around to zero.
It should go from 0 – 3. Normally I’d do a counter with a mod operator but I don’t
know how to do that safely.

Perhaps this version is better. Can you see any problems with it, or offer
a better solution.

int get_count(){
   // Create a local copy of diskid
   int save_count = _count;
   if (save_count >= limit){
      __sync_fetch_and_and(&_count, 0); // Set it back to zero
      return 0;
   }

   return save_count;
 }

Actually, I should point out that it’s not absolutely critical that each thread get a different value. If two threads happened to read the same value at the same time that wouldn’t be a problem. But they can’t exceed limit at any time.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T00:47:54+00:00Added an answer on May 18, 2026 at 12:47 am

    Your code isn’t atomic (and your second get_count doesn’t even increment the counter value)!

    Say count is 3 at the start and two threads simultaneously call get_count. One of them will get his atomic add done first and increments count to 4. If the second thread is fast enough, it can increment it to 5 before the first thread resets it to zero.

    Also, in your wraparound processing, you reset count to 0 but not save_count. This is clearly not what’s intended.

    This is easiest if limit is a power of 2. Don’t ever do the reduction yourself, just use

    return (unsigned) __sync_fetch_and_add(&count, 1) % (unsigned) limit;
    

    or alternatively

    return __sync_fetch_and_add(&count, 1) & (limit - 1);
    

    This only does one atomic operation per invocation, is safe and very cheap. For generic limits, you can still use %, but that will break the sequence if the counter ever overflows. You can try using a 64-bit value (if your platform supports 64-bit atomics) and just hope it never overflows; this is a bad idea though. The proper way to do this is using an atomic compare-exchange operation. You do this:

    int old_count, new_count;
    do {
      old_count = count;
      new_count = old_count + 1;
      if (new_count >= limit) new_count = 0; // or use %
    } while (!__sync_bool_compare_and_swap(&count, old_count, new_count));
    

    This approach generalizes to more complicated sequences and update operations too.

    That said, this type of lockless operation is tricky to get right, relies on undefined behavior to some degree (all current compilers get this right, but no C/C++ standard before C++0x actually has a well-defined memory model) and is easy to break. I recommend using a simple mutex/lock unless you’ve profiled it and found it to be a bottleneck.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

There must be an easy way to do this, but somehow I can wrap
I must be getting daft, but I can't seem to find how to read
I'm just having this trouble with Wordpress: I use to have a Blog with
OK, I'm probably just having a bad Monday, but I have the following need
I'm just having a play with the code contracts in .Net 4.0 and must
How can I get this query to work where it goes through the checks
I assume there must be a system and language independent way to just stick
This must be a classic .NET question for anyone migrating from Java. .NET does
I am working on a project at the moment, that allows the user to
Well I'm having a hell of a time trying to get my CPU down

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.