From: Grigory Vasilyev h0tc0d3@gmail.com
--- include/Makefile.in | 1 + include/wine/mutex.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 include/wine/mutex.h
diff --git a/include/Makefile.in b/include/Makefile.in index bbf28cfc87e..84742dded5c 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -920,6 +920,7 @@ SOURCES = \ wine/mmsystem16.h \ wine/mscvpdb.h \ wine/mssign.h \ + wine/mutex.h \ wine/nsi.h \ wine/orpc.idl \ wine/plugplay.idl \ diff --git a/include/wine/mutex.h b/include/wine/mutex.h new file mode 100644 index 00000000000..94e35ec8e4d --- /dev/null +++ b/include/wine/mutex.h @@ -0,0 +1,63 @@ +#ifndef __WINE_WINE_MUTEX_H +#define __WINE_WINE_MUTEX_H + +#if defined(WINE_USE_ATOMIC_LOCKS) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#ifndef __STDC_NO_ATOMICS__ + +#include <stdatomic.h> +#include <stdint.h> +#include <unistd.h> +#include <linux/futex.h> +#include <sys/syscall.h> + +#define WINE_MUTEX_TYPE _Atomic unsigned int +#define WINE_MUTEX_INIT ATOMIC_VAR_INIT(0) +#define WINE_MUTEX_LOCK(RESOURCE) do { \ + unsigned int expected = 0; \ + while(!atomic_compare_exchange_weak(RESOURCE, &expected, 1)) { \ + syscall(SYS_futex, RESOURCE, FUTEX_WAIT, 1, NULL, NULL, 0); \ + } \ +} while(0) +#define WINE_MUTEX_UNLOCK(RESOURCE) do { \ + atomic_store(RESOURCE, 0); \ + syscall(SYS_futex, RESOURCE, FUTEX_WAKE, 1, NULL, NULL, 0); \ +} while(0) +#define WINE_MUTEX_DESTROY(RESOURCE) do { \ + atomic_store(RESOURCE, 0); \ + syscall(SYS_futex, RESOURCE, FUTEX_WAKE, 1, NULL, NULL, 0); \ +} while(0) +#define WINE_MUTEX_RECURSIVE_TYPE pthread_mutex_t +#define WINE_MUTEX_RECURSIVE_INIT(RESOURCE) do { \ + pthread_mutexattr_t attr; \ + pthread_mutexattr_init( &attr ); \ + pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); \ + pthread_mutex_init( RESOURCE, &attr ); \ + pthread_mutexattr_destroy( &attr ); \ +} while(0) +#define WINE_MUTEX_RECURSIVE_LOCK(RESOURCE) pthread_mutex_lock(RESOURCE) +#define WINE_MUTEX_RECURSIVE_UNLOCK(RESOURCE) pthread_mutex_unlock(RESOURCE) +#define WINE_MUTEX_RECURSIVE_DESTROY(RESOURCE) pthread_mutex_destroy(RESOURCE) +#else +#error C11 Atomic operations not supported. Compiler defined __STDC_NO_ATOMICS__. +#endif +#else +#error C11 Atomic operations not supported. C version is lower than C11 or WINE_USE_ATOMIC_LOCKS not defined. +#define WINE_MUTEX_TYPE pthread_mutex_t +#define WINE_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +#define WINE_MUTEX_LOCK(RESOURCE) pthread_mutex_lock(RESOURCE) +#define WINE_MUTEX_UNLOCK(RESOURCE) pthread_mutex_unlock(RESOURCE) +#define WINE_MUTEX_DESTROY(RESOURCE) pthread_mutex_destroy(RESOURCE) +#define WINE_MUTEX_RECURSIVE_TYPE pthread_mutex_t +#define WINE_MUTEX_RECURSIVE_INIT(RESOURCE) do { \ + pthread_mutexattr_t attr; \ + pthread_mutexattr_init( &attr ); \ + pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); \ + pthread_mutex_init( RESOURCE, &attr ); \ + pthread_mutexattr_destroy( &attr ); \ +} while(0) +#define WINE_MUTEX_RECURSIVE_LOCK(RESOURCE) pthread_mutex_lock(RESOURCE) +#define WINE_MUTEX_RECURSIVE_UNLOCK(RESOURCE) pthread_mutex_unlock(RESOURCE) +#define WINE_MUTEX_RECURSIVE_DESTROY(RESOURCE) pthread_mutex_destroy(RESOURCE) +#endif + +#endif /* __WINE_WINE_MUTEX_H */