diff --git a/CMakeLists.txt b/CMakeLists.txt index cdf0287..5ab2017 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -185,6 +185,7 @@ set(TILE_SRCS "tile/base/thread/rw_mutex.cc" "tile/base/thread/scoped_lock.cc" "tile/base/thread/spinlock.cc" + "tile/base/memory_barrier.cc" "tile/fiber/detail/fiber.cc" "tile/io/detail/eintr_safe.cc" "tile/io/native/acceptor.cc" diff --git a/tile/base/memory_barrier.cc b/tile/base/memory_barrier.cc new file mode 100644 index 0000000..df619ae --- /dev/null +++ b/tile/base/memory_barrier.cc @@ -0,0 +1,45 @@ +#include "tile/base/memory_barrier.h" + +#include +#include + +#include "tile/base/logging.h" +#include "tile/base/never_destroyed.h" + +namespace tile { +namespace internal { +namespace { +void * +CreateOneByteDummyPage() +{ + auto ptr = mmap(nullptr, 1, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + TILE_PCHECK(ptr, "Cannot create dummy page for asymmetric memory barrier."); + (void) mlock(ptr, 1); + return ptr; +} + +void +HomemadeMembarrier() +{ + static void *dummy_page = CreateOneByteDummyPage(); + MemoryBarrier(); + static NeverDestroyed lock; + std::lock_guard _(*lock); + + TILE_PCHECK(mprotect(dummy_page, 1, PROT_READ | PROT_WRITE) == 0, "Cannot protect dummy page."); + *static_cast(dummy_page) = 0; + TILE_PCHECK(mprotect(dummy_page, 1, PROT_READ) == 0); + + MemoryBarrier(); +} + +}// namespace + +void +AsymmetricBarrierHeavy() +{ + HomemadeMembarrier(); +} +}// namespace internal + +}// namespace tile diff --git a/tile/base/memory_barrier.h b/tile/base/memory_barrier.h new file mode 100644 index 0000000..41176c7 --- /dev/null +++ b/tile/base/memory_barrier.h @@ -0,0 +1,45 @@ +#ifndef DOWNLINK__3PARTY_TILE_TILE_BASE_MEMORY_BARRIER_H +#define DOWNLINK__3PARTY_TILE_TILE_BASE_MEMORY_BARRIER_H + +#pragma once + +#include + +namespace tile { +namespace internal { +inline void +CompilerBarrier() +{ + std::atomic_signal_fence(std::memory_order_seq_cst); +} + +inline void +ReadBarrier() +{ + std::atomic_thread_fence(std::memory_order_seq_cst); +} + +inline void +WriteBarrier() +{ + std::atomic_thread_fence(std::memory_order_seq_cst); +} + +inline void +MemoryBarrier() +{ + std::atomic_thread_fence(std::memory_order_seq_cst); +} + +inline void +AsymmetricBarrierLight() +{ + CompilerBarrier(); +} + +void AsymmetricBarrierHeavy(); + +}// namespace internal +}// namespace tile + +#endif// DOWNLINK__3PARTY_TILE_TILE_BASE_MEMORY_BARRIER_H