diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f208680c..54a57a6c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - Bugfixes: - FIXED: collapsing of ExitRoundabout instructions [#5114](https://github.com/Project-OSRM/osrm-backend/issues/5114) - FIXED: negative distances in table plugin annotation [#5106](https://github.com/Project-OSRM/osrm-backend/issues/5106) + - Misc: + - CHANGED: Support up to 512 named shared memory regions [#5185](https://github.com/Project-OSRM/osrm-backend/pull/5185) # 5.18.0 - Changes from 5.17.0: diff --git a/include/storage/shared_datatype.hpp b/include/storage/shared_datatype.hpp index 720a37d46..926ca1ded 100644 --- a/include/storage/shared_datatype.hpp +++ b/include/storage/shared_datatype.hpp @@ -26,7 +26,7 @@ namespace serialization inline void read(io::BufferReader &reader, DataLayout &layout); inline void write(io::BufferWriter &writer, const DataLayout &layout); -} +} // namespace serialization namespace detail { @@ -52,7 +52,7 @@ inline std::string trimName(const std::string &name_prefix, const std::string &n return name; } } -} +} // namespace detail class DataLayout { @@ -165,7 +165,7 @@ struct SharedRegion static constexpr const int MAX_NAME_LENGTH = 254; SharedRegion() : name{0}, timestamp{0} {} - SharedRegion(const std::string &name_, std::uint64_t timestamp, std::uint8_t shm_key) + SharedRegion(const std::string &name_, std::uint64_t timestamp, std::uint16_t shm_key) : name{0}, timestamp{timestamp}, shm_key{shm_key} { std::copy_n(name_.begin(), std::min(MAX_NAME_LENGTH, name_.size()), name); @@ -175,14 +175,14 @@ struct SharedRegion char name[MAX_NAME_LENGTH + 1]; std::uint64_t timestamp; - std::uint8_t shm_key; + std::uint16_t shm_key; }; // Keeps a list of all shared regions in a fixed-sized struct // for fast access and deserialization. struct SharedRegionRegister { - using RegionID = std::uint8_t; + using RegionID = std::uint16_t; static constexpr const RegionID INVALID_REGION_ID = std::numeric_limits::max(); using ShmKey = decltype(SharedRegion::shm_key); @@ -250,12 +250,11 @@ struct SharedRegionRegister void ReleaseKey(ShmKey key) { shm_key_in_use[key] = false; } - static constexpr const std::uint8_t MAX_SHARED_REGIONS = - std::numeric_limits::max() - 1; + static constexpr const std::size_t MAX_SHARED_REGIONS = 512; static_assert(MAX_SHARED_REGIONS < std::numeric_limits::max(), "Number of shared memory regions needs to be less than the region id size."); - static constexpr const std::uint8_t MAX_SHM_KEYS = std::numeric_limits::max() - 1; + static constexpr const std::size_t MAX_SHM_KEYS = MAX_SHARED_REGIONS * 2; static constexpr const char *name = "osrm-region"; @@ -263,7 +262,7 @@ struct SharedRegionRegister std::array regions; std::array shm_key_in_use; }; -} -} +} // namespace storage +} // namespace osrm #endif /* SHARED_DATA_TYPE_HPP */ diff --git a/include/storage/shared_memory.hpp b/include/storage/shared_memory.hpp index 6fdedfcef..3b558238d 100644 --- a/include/storage/shared_memory.hpp +++ b/include/storage/shared_memory.hpp @@ -34,10 +34,10 @@ namespace storage struct OSRMLockFile { - boost::filesystem::path operator()() + template boost::filesystem::path operator()(const IdentifierT &id) { boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path(); - boost::filesystem::path lock_file = temp_dir / "osrm.lock"; + boost::filesystem::path lock_file = temp_dir / ("osrm-" + std::to_string(id) + ".lock"); return lock_file; } }; @@ -93,7 +93,7 @@ class SharedMemory try { OSRMLockFile lock_file; - boost::interprocess::xsi_key key(lock_file().string().c_str(), id); + boost::interprocess::xsi_key key(lock_file(id).string().c_str(), id); result = RegionExists(key); } catch (...) @@ -106,7 +106,7 @@ class SharedMemory template static bool Remove(const IdentifierT id) { OSRMLockFile lock_file; - boost::interprocess::xsi_key key(lock_file().string().c_str(), id); + boost::interprocess::xsi_key key(lock_file(id).string().c_str(), id); return Remove(key); } @@ -287,10 +287,11 @@ class SharedMemory template std::unique_ptr makeSharedMemory(const IdentifierT &id, const uint64_t size = 0) { + static_assert(sizeof(id) == sizeof(std::uint16_t), "Key type is not 16 bits"); try { LockFileT lock_file; - if (!boost::filesystem::exists(lock_file())) + if (!boost::filesystem::exists(lock_file(id))) { if (0 == size) { @@ -298,10 +299,10 @@ std::unique_ptr makeSharedMemory(const IdentifierT &id, const uint } else { - boost::filesystem::ofstream ofs(lock_file()); + boost::filesystem::ofstream ofs(lock_file(id)); } } - return std::make_unique(lock_file(), id, size); + return std::make_unique(lock_file(id), id, size); } catch (const boost::interprocess::interprocess_exception &e) { @@ -310,7 +311,7 @@ std::unique_ptr makeSharedMemory(const IdentifierT &id, const uint throw util::exception(e.what() + SOURCE_REF); } } -} -} +} // namespace storage +} // namespace osrm #endif // SHARED_MEMORY_HPP diff --git a/include/storage/shared_monitor.hpp b/include/storage/shared_monitor.hpp index 46048e487..2084112d4 100644 --- a/include/storage/shared_monitor.hpp +++ b/include/storage/shared_monitor.hpp @@ -33,7 +33,7 @@ template class InvertedLock InvertedLock(Lock &lock) : lock(lock) { lock.unlock(); } ~InvertedLock() { lock.lock(); } }; -} +} // namespace // The shared monitor implementation based on a semaphore and mutex template struct SharedMonitor @@ -146,7 +146,9 @@ template struct SharedMonitor // like two-turnstile reusable barrier or boost/interprocess/sync/spin/condition.hpp // fail if a waiter is killed. - static constexpr int buffer_size = 256; + // Buffer size needs to be large enough to hold all the semaphores for every + // listener you want to support. + static constexpr int buffer_size = 4096 * 4; struct InternalData { @@ -232,8 +234,8 @@ template struct SharedMonitor bi::shared_memory_object shmem; bi::mapped_region region; }; -} -} +} // namespace storage +} // namespace osrm #undef USE_BOOST_INTERPROCESS_CONDITION diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index bcdf03252..213217425 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -66,7 +66,7 @@ struct RegionHandle { std::unique_ptr memory; char *data_ptr; - std::uint8_t shm_key; + std::uint16_t shm_key; }; auto setupRegion(SharedRegionRegister &shared_register, const DataLayout &layout) diff --git a/src/tools/store.cpp b/src/tools/store.cpp index cf9d96526..bd21c9b4b 100644 --- a/src/tools/store.cpp +++ b/src/tools/store.cpp @@ -82,7 +82,8 @@ void springClean() } else { - for (auto key : util::irange(0, storage::SharedRegionRegister::MAX_SHM_KEYS)) + for (auto key : util::irange( + 0, storage::SharedRegionRegister::MAX_SHM_KEYS)) { deleteRegion(key); }