https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66842
Bug ID: 66842 Summary: libatomic uses multiple locks for locked atomics Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: bin.x.fan at oracle dot com Target Milestone: --- Hi GCC folks, I'm opening this bug to report an issue that may or may not be a real bug. I notice that GCC libatomic uses multiple locks for a locked atomic object whose size is greater than 64 bytes. The granularity seems to be 64 because for every 64 bytes added to the size, one more lock is added. It seems that this is to protect overlapping locked atomic object. If locked atomic objects never overlap, then a more efficient way to do locked atomic operations would be each object being protected by just one lock that is hashed from its address. Accessing a member of an atomic struct object is undefined behavior in C11 standard. So, does GCC support it as an extension or using multiple locks is unnecessary therefore it’s a performance bug? Here is my code to illustrate the issue. I interpose pthread_mutex_lock to count how many times it is called. My GCC version is 4.9.2, and its target is x86_64-unknown-linux-gnu. The libatomic.so I use comes with the GCC 4.9.2 installation. -bash-4.2$ cat libmythread.c #define _GNU_SOURCE #include <pthread.h> #include <dlfcn.h> #include <stdio.h> #include <assert.h> static int counter = 0; int pthread_mutex_lock (pthread_mutex_t *mutex) { static int (*real_pthread_mutex_lock)(pthread_mutex_t *) = NULL; if (real_pthread_mutex_lock == NULL) { real_pthread_mutex_lock = dlsym (RTLD_NEXT, "pthread_mutex_lock"); } assert (real_pthread_mutex_lock); counter++; return real_pthread_mutex_lock (mutex); } void display_nlocks () { printf ("pthread_mutex_lock is called %d times\n", counter); return; } -bash-4.2$ cat c11_locked_atomics.c #include <stdatomic.h> #ifndef SIZE #define SIZE 1024 #endif typedef struct { char a[SIZE]; } lock_obj_t; extern void display_nlocks (); int main() { lock_obj_t v2 = {0}; _Atomic lock_obj_t v1 = ATOMIC_VAR_INIT(v2); v2 = atomic_load (&v1); display_nlocks (); return 0; } -bash-4.2$ gcc -shared -ldl -fPIC libmythread.c -o libmythread.so -bash-4.2$ gcc -latomic c11_locked_atomics.c -DSIZE=2048 -L./ -Wl,-rpath=./ -lmythread -bash-4.2$ LD_PRELOAD=./libmythread.so a.out pthread_mutex_lock is called 32 times