#include <assert.h>
#include <urcu/uatomic.h>
+/*
+ * Using attribute "weak" for __rcu_cas_avail and
+ * __urcu_x86_compat_mutex. Those are globally visible by the entire
+ * program, even though many shared objects may have their own version.
+ * The first version that gets loaded will be used by the entire
+ * program (executable and all shared objects).
+ */
+
/*
* It does not really matter if the constructor is called before using
* the library, as long as the caller checks if __rcu_cas_avail < 0 and calls
* 1: available
* 0: unavailable
*/
+__attribute__((weak))
int __rcu_cas_avail = -1;
-static pthread_mutex_t compat_mutex = PTHREAD_MUTEX_INITIALIZER;
+__attribute__((weak))
+pthread_mutex_t __urcu_x86_compat_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* get_eflags/set_eflags/compare_and_swap_is_available imported from glibc
assert(!ret);
ret = pthread_sigmask(SIG_BLOCK, &newmask, oldmask);
assert(!ret);
- ret = pthread_mutex_lock(&compat_mutex);
+ ret = pthread_mutex_lock(&__urcu_x86_compat_mutex);
assert(!ret);
}
{
int ret;
- ret = pthread_mutex_unlock(&compat_mutex);
+ ret = pthread_mutex_unlock(&__urcu_x86_compat_mutex);
assert(!ret);
ret = pthread_sigmask(SIG_SETMASK, oldmask, NULL);
assert(!ret);
sigset_t mask;
unsigned long result;
- mutex_lock_signal_save(&compat_mutex, &mask);
+ mutex_lock_signal_save(&__urcu_x86_compat_mutex, &mask);
switch (len) {
case 1:
*(unsigned char *)addr = (unsigned char)_new;
result = 0;
__asm__ __volatile__("ud2");
}
- mutex_lock_signal_restore(&compat_mutex, &mask);
+ mutex_lock_signal_restore(&__urcu_x86_compat_mutex, &mask);
return result;
}
sigset_t mask;
unsigned long retval;
- mutex_lock_signal_save(&compat_mutex, &mask);
+ mutex_lock_signal_save(&__urcu_x86_compat_mutex, &mask);
switch (len) {
case 1:
retval = *(unsigned char *)addr;
retval = 0; /* silence gcc warnings */
__asm__ __volatile__("ud2");
}
- mutex_lock_signal_restore(&compat_mutex, &mask);
+ mutex_lock_signal_restore(&__urcu_x86_compat_mutex, &mask);
return retval;
}
unsigned long retval;
sigset_t mask;
- mutex_lock_signal_save(&compat_mutex, &mask);
+ mutex_lock_signal_save(&__urcu_x86_compat_mutex, &mask);
switch (len) {
case 1:
{
retval = 0; /* silence gcc warnings */
__asm__ __volatile__("ud2");
}
- mutex_lock_signal_restore(&compat_mutex, &mask);
+ mutex_lock_signal_restore(&__urcu_x86_compat_mutex, &mask);
return retval;
}
{
sigset_t mask;
- mutex_lock_signal_save(&compat_mutex, &mask);
+ mutex_lock_signal_save(&__urcu_x86_compat_mutex, &mask);
switch (len) {
case 1:
*(unsigned char *)addr |= (unsigned char)v;
*/
__asm__ __volatile__("ud2");
}
- mutex_lock_signal_restore(&compat_mutex, &mask);
+ mutex_lock_signal_restore(&__urcu_x86_compat_mutex, &mask);
}
void _compat_uatomic_and(void *addr, unsigned long v, int len)
{
sigset_t mask;
- mutex_lock_signal_save(&compat_mutex, &mask);
+ mutex_lock_signal_save(&__urcu_x86_compat_mutex, &mask);
switch (len) {
case 1:
*(unsigned char *)addr &= (unsigned char)v;
*/
__asm__ __volatile__("ud2");
}
- mutex_lock_signal_restore(&compat_mutex, &mask);
+ mutex_lock_signal_restore(&__urcu_x86_compat_mutex, &mask);
}
unsigned long _compat_uatomic_add_return(void *addr, unsigned long v, int len)
sigset_t mask;
unsigned long result;
- mutex_lock_signal_save(&compat_mutex, &mask);
+ mutex_lock_signal_save(&__urcu_x86_compat_mutex, &mask);
switch (len) {
case 1:
*(unsigned char *)addr += (unsigned char)v;
result = 0; /* silence gcc warnings */
__asm__ __volatile__("ud2");
}
- mutex_lock_signal_restore(&compat_mutex, &mask);
+ mutex_lock_signal_restore(&__urcu_x86_compat_mutex, &mask);
return result;
}