From bab093ebbe392927a92ef201fe60344d5c1191dd Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 25 Dec 2018 09:53:52 +0100 Subject: compat/shm, proto/wine: remove duplication The X-Plane plugin is next and should build on win32 then. --- compat/macros1.h | 9 ++ compat/shm.c | 150 ++++++++++++++++++++++++++ compat/shm.cpp | 134 +++-------------------- compat/shm.h | 85 +++++++++------ compat/shm.hpp | 34 ++++++ proto-ft/ftnoir_protocol_ft.h | 8 +- proto-wine/ftnoir_protocol_wine.h | 4 +- proto-wine/opentrack-wrapper-wine-main.cxx | 114 ++++++++++---------- proto-wine/opentrack-wrapper-wine-posix.cxx | 9 +- proto-wine/opentrack-wrapper-wine-windows.cxx | 6 +- 10 files changed, 328 insertions(+), 225 deletions(-) create mode 100644 compat/shm.c create mode 100644 compat/shm.hpp diff --git a/compat/macros1.h b/compat/macros1.h index fd2d4585..56f8e978 100644 --- a/compat/macros1.h +++ b/compat/macros1.h @@ -39,3 +39,12 @@ # define PP_EXPAND__2(x) PP_EXPAND__3(x) x # define PP_EXPAND__3(x) x #endif + +#ifdef _MSC_VER +//# include +//# define FULL_BARRIER MemoryBarrier() +# define COMPILER_BARRIER() _ReadWriteBarrier() +#else +//# define FULL_BARRIER() __sync_synchronize() +# define COMPILER_BARRIER() asm volatile("" ::: "memory") +#endif diff --git a/compat/shm.c b/compat/shm.c new file mode 100644 index 00000000..d0c72781 --- /dev/null +++ b/compat/shm.c @@ -0,0 +1,150 @@ +#define BUILD_SHM +#include "shm.h" + +#ifdef SHM_WIN32 + +#include + +SHM_FUN(void, init, const char* shm_name, const char* mutex_name, int map_size) +{ + if (mutex_name != NULL) + { + self->mutex = CreateMutexA(NULL, false, mutex_name); + + if (!self->mutex) + goto fail; + } + + self->mapped_file = CreateFileMappingA( + INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + 0, + (unsigned)map_size, + shm_name); + + if (!self->mapped_file) + goto fail; + + self->mem = MapViewOfFile(self->mapped_file, + FILE_MAP_WRITE, + 0, + 0, + (unsigned) map_size); + + if (!self->mem) + goto fail; + + return; + +fail: + SHM_FUN_NAME(free)(self); +} + +SHM_FUN(void, free) +{ + if (self->mem) + (void) UnmapViewOfFile(self->mem); + + if (self->mapped_file) + (void) CloseHandle(self->mapped_file); + + if (self->mutex) + (void) CloseHandle(self->mutex); + + self->mem = NULL; + self->mapped_file = NULL; + self->mutex = NULL; +} + +SHM_FUN(void, lock) +{ + if (self->mutex) + (void)(WaitForSingleObject(self->mutex, INFINITE) == WAIT_OBJECT_0); +} + +SHM_FUN(void, unlock) +{ + (void) ReleaseMutex(self->mutex); +} + +SHM_FUN(bool, success) +{ + return self->mem != NULL; +} + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#pragma GCC diagnostic ignored "-Wunused-result" + +SHM_FUN(void, init, const char *shm_name, const char* mutex_name, int map_size) +{ + char* filename = alloca(strlen(shm_name)+2); + (void)mutex_name; + + self->mem = (void*)-1; + self->fd = -1; + self->size = 0; + + if (map_size <= 0) + goto fail; + + self->size = map_size; + strcpy(filename, "/"); + strcat(filename, shm_name); + self->fd = shm_open(filename, O_RDWR | O_CREAT, 0600); + (void)ftruncate(self->fd, (off_t)map_size); + self->mem = mmap(NULL, (size_t)map_size, PROT_READ|PROT_WRITE, MAP_SHARED, self->fd, (off_t)0); + + if (self->mem == (void*)-1) + goto fail; + + return; + +fail: + SHM_FUN_NAME(free)(self); +} + +SHM_FUN(void, free) +{ + if (self->mem != (void*)-1) + (void)munmap(self->mem, self->size); + if (self->fd != -1) + (void)close(self->fd); + + self->mem = (void*)-1; + self->fd = -1; + self->size = 0; +} + +SHM_FUN(void, lock) +{ + return flock(self->fd, LOCK_EX) == 0; +} + +SHM_FUN(void, unlock) +{ + return flock(self->fd, LOCK_UN) == 0; +} + +SHM_FUN(bool, success) +{ + return self->mem != (void*) -1; +} + +#endif + +SHM_FUN(void*, ptr) +{ + return self->mem; +} diff --git a/compat/shm.cpp b/compat/shm.cpp index 1f863190..ce01de2a 100644 --- a/compat/shm.cpp +++ b/compat/shm.cpp @@ -5,133 +5,23 @@ * copyright notice and this permission notice appear in all copies. */ -#include "shm.h" +#define BUILD_SHM +#include "shm.hpp" -#if defined _WIN32 +SHMXX_TYPE_NAME& SHMXX_TYPE_NAME::operator=(SHMXX_TYPE_NAME&&) noexcept = default; -#include -#include - -#include -#include - -#ifdef QT_CORE_LIB -# include -# define warn(str, ...) (qDebug() << "shm:" str ": " << __VA_ARGS__) -#else -# define warn(str, ...) (void)0 -#endif - -shm_wrapper::shm_wrapper(const char* shm_name, const char* mutex_name, int map_size) -{ - if (mutex_name == nullptr) - mutex = nullptr; - else - { - mutex = CreateMutexA(nullptr, false, mutex_name); - - if (!mutex) - { - warn("CreateMutexA", (int) GetLastError()); - return; - } - } - - mapped_file = CreateFileMappingA( - INVALID_HANDLE_VALUE, - nullptr, - PAGE_READWRITE, - 0, - map_size, - shm_name); - - if (!mapped_file) - { - warn("CreateFileMappingA", (int) GetLastError()); - - return; - } - - mem = MapViewOfFile(mapped_file, - FILE_MAP_WRITE, - 0, - 0, - map_size); - - if (!mem) - warn("MapViewOfFile:", (int) GetLastError()); -} - -shm_wrapper::~shm_wrapper() -{ - if (mem && !UnmapViewOfFile(mem)) - goto fail; - - if (mapped_file && !CloseHandle(mapped_file)) - goto fail; - - if (mutex && !CloseHandle(mutex)) - goto fail; - - return; - -fail: - warn("failed to close mapping", (int) GetLastError()); -} - -bool shm_wrapper::lock() -{ - if (mutex) - return WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0; - else - return false; -} - -bool shm_wrapper::unlock() -{ - if (mutex) - return ReleaseMutex(mutex); - else - return false; -} -#else - -#include - -#pragma GCC diagnostic ignored "-Wunused-result" -shm_wrapper::shm_wrapper(const char *shm_name, const char* /*mutex_name*/, int map_size) : size(map_size) -{ - char filename[PATH_MAX+2] {}; - strcpy(filename, "/"); - strcat(filename, shm_name); - fd = shm_open(filename, O_RDWR | O_CREAT, 0600); - (void) ftruncate(fd, map_size); - mem = mmap(NULL, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t)0); -} - -shm_wrapper::~shm_wrapper() -{ - (void) munmap(mem, size); - (void) close(fd); -} - -bool shm_wrapper::lock() -{ - return flock(fd, LOCK_EX) == 0; -} - -bool shm_wrapper::unlock() +// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) +SHMXX_TYPE_NAME::SHMXX_TYPE_NAME(const char* shm_name, const char* mutex_name, int map_size) { - return flock(fd, LOCK_UN) == 0; + shm_mem_impl_init(&impl, shm_name, mutex_name, map_size); } -#endif -bool shm_wrapper::success() +SHMXX_TYPE_NAME::~SHMXX_TYPE_NAME() { -#ifndef _WIN32 - return mem != (void*) -1; -#else - return mem != nullptr; -#endif + shm_mem_impl_free(&impl); } +bool SHMXX_TYPE_NAME::success() noexcept { return shm_mem_impl_success(&impl); } +void SHMXX_TYPE_NAME::lock() noexcept { shm_mem_impl_lock(&impl); } +void SHMXX_TYPE_NAME::unlock() noexcept { shm_mem_impl_unlock(&impl); } +void* SHMXX_TYPE_NAME::ptr() noexcept { return shm_mem_impl_ptr(&impl); } diff --git a/compat/shm.h b/compat/shm.h index 814ce90c..7cd7693d 100644 --- a/compat/shm.h +++ b/compat/shm.h @@ -1,41 +1,66 @@ -/* Copyright (c) 2013 Stanislaw Halik +#ifndef SHM_HEADER_GUARD +#define SHM_HEADER_GUARD - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ -#pragma once +#include "macros1.h" -#if defined(_WIN32) -#include +#ifndef SHM_WIN32_INIT +# ifdef _WIN32 +# define SHM_WIN32 +# else +# undef SHM_WIN32 +# endif #else -#include -#include -#include -#include -#include -#include -#include -#include +# if SHM_WIN32_INIT +# define SHM_WIN32 +# else +# undef SHM_WIN32 +# endif #endif -#include "macros.hpp" -#include "export.hpp" +#ifndef SHM_TYPE_NAME +# define SHM_TYPE_NAME shm_mem_impl +#endif + +#ifndef SHM_FUN_PREFIX +# define SHM_FUN_PREFIX shm_mem_impl_ +#endif + +#ifndef SHM_EXPORT +# define SHM_EXPORT +#endif + +#ifndef __cplusplus +# define SHM_EXTERN +# include +struct SHM_TYPE_NAME; +typedef struct SHM_TYPE_NAME SHM_TYPE_NAME; +#else +# define SHM_EXTERN extern "C" +#endif -class OTR_COMPAT_EXPORT shm_wrapper final -{ +struct SHM_TYPE_NAME { void* mem; -#if defined(_WIN32) - HANDLE mutex, mapped_file; +#ifdef SHM_WIN32 + void* mutex; + void* mapped_file; #else int fd, size; #endif - -public: - cc_noinline shm_wrapper(const char *shm_name, const char *mutex_name, int map_size); - cc_noinline ~shm_wrapper(); - cc_noinline bool lock(); - cc_noinline bool unlock(); - cc_noinline bool success(); - inline void* ptr() { return mem; } }; + +#define SHM_FUN_NAME(f) PP_CAT(SHM_FUN_PREFIX, f) +#define SHM_FUN(r, f, ...) SHM_EXTERN SHM_EXPORT r SHM_FUN_NAME(f)(SHM_TYPE_NAME* __restrict self, __VA_ARGS__) + +SHM_FUN(void, init, const char* shm_name, const char* mutex_name, int map_size); +SHM_FUN(void, free); +SHM_FUN(void, lock); +SHM_FUN(void, unlock); +SHM_FUN(void*,ptr); +SHM_FUN(bool, success); + +#ifndef BUILD_SHM +# undef SHM_FUN +# undef SHM_FUN_NAME +#endif + +#endif // SHM_HEADER_GUARD diff --git a/compat/shm.hpp b/compat/shm.hpp new file mode 100644 index 00000000..a8e0965b --- /dev/null +++ b/compat/shm.hpp @@ -0,0 +1,34 @@ +/* Copyright (c) 2013 Stanislaw Halik + + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ +#ifndef SHMXX_HEADER_GUARD +#define SHMXX_HEADER_GUARD + +#include "export.hpp" +#include "shm.h" + +#ifndef SHMXX_TYPE_NAME +# define SHMXX_TYPE_NAME mem +#endif + +class OTR_COMPAT_EXPORT SHMXX_TYPE_NAME final +{ + shm_mem_impl impl; + +public: + SHMXX_TYPE_NAME(const char* shm_name, const char* mutex_name, int map_size); + ~SHMXX_TYPE_NAME(); + + bool success() noexcept; + void* ptr() noexcept; + void lock() noexcept; + void unlock() noexcept; + + SHMXX_TYPE_NAME& operator=(const SHMXX_TYPE_NAME&) = delete; + SHMXX_TYPE_NAME& operator=(SHMXX_TYPE_NAME&&) noexcept; +}; + +#endif // SHMXX_HEADER_GUARD diff --git a/proto-ft/ftnoir_protocol_ft.h b/proto-ft/ftnoir_protocol_ft.h index 0056721c..a01ff722 100644 --- a/proto-ft/ftnoir_protocol_ft.h +++ b/proto-ft/ftnoir_protocol_ft.h @@ -19,7 +19,7 @@ #include #include "freetrackclient/fttypes.h" -#include "compat/shm.h" +#include "compat/shm.hpp" #include "options/options.hpp" #include @@ -46,7 +46,7 @@ public: QString game_name() override; private: settings s; - shm_wrapper shm { FREETRACK_HEAP, FREETRACK_MUTEX, sizeof(FTHeap) }; + mem shm { FREETRACK_HEAP, FREETRACK_MUTEX, sizeof(FTHeap) }; FTHeap* pMemData { (FTHeap*) shm.ptr() }; QProcess dummyTrackIR; @@ -66,8 +66,8 @@ class FTControls: public IProtocolDialog Q_OBJECT public: FTControls(); - void register_protocol(IProtocol *) {} - void unregister_protocol() {} + void register_protocol(IProtocol *) override {} + void unregister_protocol() override {} private: Ui::UICFTControls ui; settings s; diff --git a/proto-wine/ftnoir_protocol_wine.h b/proto-wine/ftnoir_protocol_wine.h index b4cbd305..8feaf0de 100644 --- a/proto-wine/ftnoir_protocol_wine.h +++ b/proto-wine/ftnoir_protocol_wine.h @@ -1,7 +1,7 @@ #pragma once #include "api/plugin-api.hpp" -#include "compat/shm.h" +#include "compat/shm.hpp" #include "wine-shm.h" #include "ui_ftnoir_winecontrols.h" @@ -33,7 +33,7 @@ public: #endif } private: - shm_wrapper lck_shm { WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM) }; + mem lck_shm { WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM) }; WineSHM* shm = nullptr; #ifndef OTR_WINE_NO_WRAPPER diff --git a/proto-wine/opentrack-wrapper-wine-main.cxx b/proto-wine/opentrack-wrapper-wine-main.cxx index 6370e7f4..491cc917 100644 --- a/proto-wine/opentrack-wrapper-wine-main.cxx +++ b/proto-wine/opentrack-wrapper-wine-main.cxx @@ -1,80 +1,74 @@ #include +#include // usleep -// OSX sdk 10.8 build error otherwise -#undef _LIBCPP_MSVCRT -#include - +#include "compat/macros1.h" #include "freetrackclient/fttypes.h" #include "wine-shm.h" -#include "compat/export.hpp" enum Axis { TX = 0, TY, TZ, Yaw, Pitch, Roll }; -#include "compat/shm.h" - -void create_registry_key(void); +#undef SHM_HEADER_GUARD +#undef SHMXX_HEADER_GUARD +#undef SHM_TYPE_NAME +#undef SHM_FUN_PREFIX +#undef SHMXX_TYPE_NAME +#undef SHM_WIN32_INIT +#define SHM_TYPE_NAME shm_impl_winelib +#define SHM_FUN_PREFIX shm_impl_winelib_ +#define SHMXX_TYPE_NAME mem_winelib +#define SHM_WIN32_INIT 1 +#include "compat/shm.hpp" -class ShmPosix { -public: - ShmPosix(const char *shmName, const char *mutexName, int mapSize); - ~ShmPosix(); - void lock(); - void unlock(); - bool success(); - inline void* ptr() { return mem; } -private: - void* mem; - int fd, size; -}; +#undef SHM_HEADER_GUARD +#undef SHMXX_HEADER_GUARD +#undef SHM_TYPE_NAME +#undef SHM_FUN_PREFIX +#undef SHMXX_TYPE_NAME +#undef SHM_WIN32_INIT +#define SHM_TYPE_NAME shm_impl_unix +#define SHM_FUN_PREFIX shm_impl_unix_ +#define SHMXX_TYPE_NAME mem_unix +#define SHM_WIN32_INIT +#include "compat/shm.hpp" -class ShmWine { -public: - ShmWine(const char *shmName, const char *mutexName, int mapSize); - ~ShmWine(); - void lock(); - void unlock(); - bool success(); - inline void* ptr() { return mem; } -private: - void* mem; - void *hMutex, *hMapFile; -}; -#include +void create_registry_key(void); int main(void) { - ShmPosix lck_posix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)); - ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap)); - if(!lck_posix.success()) { - fprintf(stderr, "Can't open posix map: %d\n", errno); + mem_unix lck_unix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)); + mem_winelib lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap)); + + if(!lck_unix.success()) return 1; - } - if(!lck_wine.success()) { - fprintf(stderr, "Can't open Wine map\n"); + if(!lck_wine.success()) return 1; - } - WineSHM* shm_posix = (WineSHM*) lck_posix.ptr(); - FTHeap* shm_wine = (FTHeap*) lck_wine.ptr(); - FTData* data = &shm_wine->data; + create_registry_key(); - while (1) { - if (shm_posix->stop) - break; - data->Yaw = -shm_posix->data[Yaw]; - data->Pitch = -shm_posix->data[Pitch]; - data->Roll = shm_posix->data[Roll]; - data->X = shm_posix->data[TX]; - data->Y = shm_posix->data[TY]; - data->Z = shm_posix->data[TZ]; - data->DataID++; - data->CamWidth = 250; - data->CamHeight = 100; - shm_wine->GameID2 = shm_posix->gameid2; - shm_posix->gameid = shm_wine->GameID; + + WineSHM& mem_unix = *(WineSHM*) lck_unix.ptr(); + FTHeap& mem_wine = *(FTHeap*) lck_wine.ptr(); + FTData& data = mem_wine.data; + + data.CamWidth = 250; + data.CamHeight = 100; + + while (!mem_unix.stop) + { + MEMBAR(); + data.Yaw = -mem_unix.data[Yaw]; + data.Pitch = -mem_unix.data[Pitch]; + data.Roll = mem_unix.data[Roll]; + data.X = mem_unix.data[TX]; + data.Y = mem_unix.data[TY]; + data.Z = mem_unix.data[TZ]; + data.DataID = 1; + mem_wine.GameID2 = mem_unix.gameid2; + mem_unix.gameid = mem_wine.GameID; for (int i = 0; i < 8; i++) - shm_wine->table[i] = shm_posix->table[i]; - (void) Sleep(4); + mem_wine.table[i] = mem_wine.table[i]; + MEMBAR(); + (void)usleep(4 * 1000); } } diff --git a/proto-wine/opentrack-wrapper-wine-posix.cxx b/proto-wine/opentrack-wrapper-wine-posix.cxx index e36407a9..17a74b66 100644 --- a/proto-wine/opentrack-wrapper-wine-posix.cxx +++ b/proto-wine/opentrack-wrapper-wine-posix.cxx @@ -1,7 +1,6 @@ -#ifdef _WIN32 -# undef _WIN32 -#endif +#undef _WIN32 -#define shm_wrapper ShmPosix -#include "compat/shm.h" +#define SHM_TYPE_NAME shm_impl_unix +#define SHM_FUN_PREFIX shm_impl_unix_ +#define SHMXX_TYPE_NAME mem_unix #include "compat/shm.cpp" diff --git a/proto-wine/opentrack-wrapper-wine-windows.cxx b/proto-wine/opentrack-wrapper-wine-windows.cxx index d464cf6c..a18900c3 100644 --- a/proto-wine/opentrack-wrapper-wine-windows.cxx +++ b/proto-wine/opentrack-wrapper-wine-windows.cxx @@ -2,9 +2,11 @@ # error "bad cross" #endif -#define shm_wrapper ShmWine -#include "compat/shm.h" +#define SHM_TYPE_NAME shm_impl_winelib +#define SHM_FUN_PREFIX shm_impl_winelib_ +#define SHMXX_TYPE_NAME mem_winelib #include "compat/shm.cpp" + #include "wine-shm.h" #include "compat/library-path.hpp" #include -- cgit v1.2.3