GLIB: g_atomic_int_get becomes NO-OP?
The architecture you are on does not require a memory barrier for atomic integer set/get operations, so the transformation is valid.
Here's where it's defined: http://git.gnome.org/browse/glib/tree/glib/gatomic.h#n60
This is a good thing, because otherwise you'd need to lock a global mutex for every atomic operation.
g_atomic_int_get guarantees visibility into another thread?
What most architecture ensures (included) is atomicity and coherence of reads and writes of suitably sized and aligned read/write (so every processors see a subsequence of the same master sequence of values for a given memory adress (*)), and int
is most probably suitably size and compilers generally ensure that they are also correctly aligned.
But compilers rarely ensures that they aren't optimizing out some reads or writes if they aren't marked in a way or another. I've tried to compile:
int f(int* ptr)
{
int i, r=0;
*ptr = 5;
for (i = 0; i < 100; ++i) {
r += i*i;
}
*ptr = r;
return *ptr;
}
with gcc 4.1.2 gcc optimized out without problem the first write to *ptr
, something you probably don't want for an atomic write.
(*) Coherence is not to be confused with consistency: the relationship between reads and writes at different address is often relaxed with respect to the intuitive, but costly to implement, sequential consistency. That's why memory barriers are needed.
atomic increment and return counter
Simply use:
std::atomic<int> id{};
int create_id() {
return id++;
}
See http://en.cppreference.com/w/cpp/atomic/atomic/operator_arith
How can I link to a specific glibc version?
You are correct in that glibc uses symbol versioning. If you are curious, the symbol versioning implementation introduced in glibc 2.1 is described here and is an extension of Sun's symbol versioning scheme described here.
One option is to statically link your binary. This is probably the easiest option.
You could also build your binary in a chroot build environment, or using a glibc-new => glibc-old cross-compiler.
According to the http://www.trevorpounds.com blog post Linking to Older Versioned Symbols (glibc), it is possible to to force any symbol to be linked against an older one so long as it is valid by using the same .symver
pseudo-op that is used for defining versioned symbols in the first place. The following example is excerpted from the blog post.
The following example makes use of glibc’s realpath, but makes sure it is linked against an older 2.2.5 version.
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
__asm__(".symver realpath,realpath@GLIBC_2.2.5");
int main()
{
const char* unresolved = "/lib64";
char resolved[PATH_MAX+1];
if(!realpath(unresolved, resolved))
{ return 1; }
printf("%s\n", resolved);
return 0;
}
Multiple glibc libraries on a single host
It is very possible to have multiple versions of glibc on the same system (we do that every day).
However, you need to know that glibc consists of many pieces (200+ shared libraries) which all must match. One of the pieces is ld-linux.so.2, and it must match libc.so.6, or you'll see the errors you are seeing.
The absolute path to ld-linux.so.2 is hard-coded into the executable at link time, and can not be easily changed after the link is done (Update: can be done with patchelf; see this answer below).
To build an executable that will work with the new glibc, do this:
g++ main.o -o myapp ... \
-Wl,--rpath=/path/to/newglibc \
-Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2
The -rpath
linker option will make the runtime loader search for libraries in /path/to/newglibc
(so you wouldn't have to set LD_LIBRARY_PATH
before running it), and the -dynamic-linker
option will "bake" path to correct ld-linux.so.2
into the application.
If you can't relink the myapp
application (e.g. because it is a third-party binary), not all is lost, but it gets trickier. One solution is to set a proper chroot
environment for it. Another possibility is to use rtldi and a binary editor. Update: or you can use patchelf.
Related Topics
How Does The Os Know Disk Address of an Absent Page
Listening for New Processes in Linux Kernel Module
How to Find The Byte Position of Specific Line in a File
Can 'Vim' Open a Large File in Read Only Mode as Fast as 'Less'
Elk Not Passing Metadata from Filebeat into Logstash
Why Does The Same Executable Use Different Runpaths for Different Library Lookups
Raspberry Pi: Spi Not Working, Spi_Bcm2835 Not Showing with Lsmod
How to Make Library Installed from Opam Available to Ocaml
Capturing User-Space Assembly with Ftrace and Kprobes (By Using Virtual Address Translation)
Using Source to Include Part of a File in a Bash Script
Producer Consumer Implementation in a Block Device Driver
PHPmyadmin Mcrypt Extension Is Missing
Home Directory Is Not Created with Adding User Resource with Chef
How to Write on Serial Port Using Qextserialport
Statically Linked Shared Object? or a Corrupt File
Split and Rename The Splitted Files in Shell Script