This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 1/4] Cherry-pick fprofile-generate-atomic from google/gcc-4_9 branch


On 08/04/16 12:43, Nathan Sidwell wrote:

How about:
gcov_t expected;
atomic_load (&counter[0],  val, ...);
gcov_t delta = val == value ? 1 : -1;
atomic_add (&counter[1], delta);   <-- or atomic_add_fetch
if (delta < 0) {
  /* can we set counter[0]? */
  atomic_load (&counter[1], &expected, ...);
  if (expected < 0) {
    atomic_store (&counter[0], value, ...);
    atomic_add (&counter[1], 2, ...);
  }
}
atomic_add (&counter[2], 1, ...);

we could do better by using compare_exchange storing value, and detect the race I mentioned:

gcov_t expected, val;
atomic_load (&counter[0],  &val, ...);
gcov_t delta = val == value ? 1 : -1;
atomic_add (&counter[1], delta);
if (delta < 0) {
   retry:
    /* can we set counter[0]? */
    atomic_load (&counter[1], &expected, ...);
    if (expected < 0) {
      bool stored = atomic_compare_exchange (&counter[0], &val, &value, ...);
      if (!stored && val != value)
        goto retry;
      atomic_add (&counter[1], 2, ...);
  }
}
atomic_add (&counter[2], 1, ...);

This  corrects the off-by one issue.

nathan


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]