PypeBros
PypeBros

Reputation: 2646

what can I do about GNU ld 'legacy __sync_synchronize' warning?

I have some C++ code that uses a local-scope, program-lifetime object, e.g.

void testFunction(int arg) {
   static Tested tested(0);
   tested.use(arg);
}

which built fine with older versions of GCC. With GCC 8.2.0, I get a puzzling warning at link time:

warning: legacy compatible __sync_synchronize used. Not suitable for multi-threaded applications

It points the line defining tested, and indeed there is a call to __sync_synchronize() that has been generated by the compiler. I guess it is there to ensure that no two threads could run the initializing code at the same time and have the lazy initialization produce the same result as if there was load-time initialization.

Issue is reproduced with this implementation of the Tested class:

class Tested {
  int sum;
public:
  Tested(int init) : sum(init) {}
  void use(int arg) {
    sum += arg;
  }
  int current() const {
    return sum;
  }
};

This code is expected to run on a mono-thread embedded platform.

Am I right believing that the warning is not relevant for me ?

What can I do (beside stopping using the static object) to get rid of the warning message ?

Upvotes: 1

Views: 1008

Answers (2)

WinterMute
WinterMute

Reputation: 347

It would have been better for you to wait on a reply at https://devkitpro.org/viewtopic.php?f=13&t=8822#p16213 rather than asking on a site where most people aren't familiar with devkitARM.

tl;dr; compile your code with -fno-threadsafe-statics & don't worry about it.

Upvotes: -2

Jonathan Wakely
Jonathan Wakely

Reputation: 171263

You're getting a linker warning, generated by that version of newlib, to tell you that your application has calls to __sync_synchronize and that there is no implementation of that function that actually synchronizes. The implementation of that function in newlib is a stub that does nothing (it probably just exists to ensure there are no undefined references to that function).

Those calls probably come from within libstdc++.so, as GCC on ARM will emit calls to __sync_synchronize for some atomic operations that happen inside the library (e.g. reference count updates in std::string or shared_ptr objects).

To get a working __sync_synchronize that makes the atomics correct you probably need to link to libatomic (using -latomic) which will have an implementation of that function. Because you aren't linking to that, you get the fallback stub implementation in newlib. If you don't need synchronized atomics (because your application is single-threaded and never tries to update atomics in signal handlers) then I think you can ignore the warning.

Another option would be to use a build of libstdc++.so that explicitly disables all threading, and in theory that wouldn't have any references to __sync_synchronize. But that build of libstdc++.so could only ever be used for single-threaded applications. The build you're using now can be used for both single-threaded and multi-threaded code (even if you get this warning that isn't very relevant for single-threaded cases).

Upvotes: 5

Related Questions