-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#25538] docdb: Add mechanism for reserving virtual addresses
Summary: This diff adds `ReservedAddressSpace`, which is a manager for a reserved virtual address space, and `AddressSpaceNegotiator`, which finds a segment of virtual memory that is unused in both parent and child process for use with `ReservedAddressSpace`. Since we call `exec()` (or `posix_spawn()`) when starting up postmaster, all memory mappings created by tserver beforehand are lost. In order to have a reserved virtual address space at the same address for both tserver and postmaster, `AddressSpaceNegotiator` has the parent process propose addresses to start the reserved address space at that work for the parent, and has the child accept or reject it depending on whether or not it works for the child. The block of virtual addresses is reserved with `mmap(..., PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE)` . The negotiated address space is then passed to `ReservedAddressSpace`, which provides methods to lay out `mmap` calls on fixed addresses in the space with `MAP_FIXED`. Since the reserved segment is at the same address in both child and parent, this provides us with a building block for having pointers that are meaningful in both processes. This is needed for future changes to move the table locks lock manager into shared memory. For more context: D40272. Jira: DB-14793 Test Plan: Added unit tests: `./yb_build.sh --cxx-test 'util_reserved_address_space-test'` Reviewers: sergei, bkolagani Reviewed By: sergei Subscribers: ybase, rthallam, zdrudi, amitanand Differential Revision: https://phorge.dev.yugabyte.com/D41083
- Loading branch information
Showing
12 changed files
with
974 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright (c) YugaByte, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
// in compliance with the License. You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software distributed under the License | ||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
// or implied. See the License for the specific language governing permissions and limitations | ||
// under the License. | ||
// | ||
|
||
#pragma once | ||
|
||
#include <semaphore.h> | ||
|
||
#include <boost/interprocess/sync/interprocess_semaphore.hpp> | ||
|
||
#include "yb/util/result.h" | ||
#include "yb/util/status.h" | ||
|
||
namespace yb { | ||
|
||
#if defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) | ||
class InterprocessSemaphore { | ||
public: | ||
explicit InterprocessSemaphore(unsigned int initial_count) { | ||
int ret = sem_init(&impl_, 1, initial_count); | ||
CHECK_NE(ret, -1); | ||
} | ||
|
||
InterprocessSemaphore(const InterprocessSemaphore&) = delete; | ||
void operator=(const InterprocessSemaphore&) = delete; | ||
|
||
~InterprocessSemaphore() { | ||
CHECK_EQ(sem_destroy(&impl_), 0); | ||
} | ||
|
||
Status Post() { | ||
return ResToStatus(sem_post(&impl_), "Post"); | ||
} | ||
|
||
Status Wait() { | ||
return ResToStatus(sem_wait(&impl_), "Wait"); | ||
} | ||
|
||
template<class TimePoint> | ||
Status TimedWait(const TimePoint &abs_time) { | ||
// Posix does not support infinity absolute time so handle it here | ||
if (boost::interprocess::ipcdetail::is_pos_infinity(abs_time)) { | ||
return Wait(); | ||
} | ||
|
||
auto tspec = boost::interprocess::ipcdetail::timepoint_to_timespec(abs_time); | ||
int res = sem_timedwait(&impl_, &tspec); | ||
if (res == 0) { | ||
return Status::OK(); | ||
} | ||
if (res > 0) { | ||
// buggy glibc, copy the returned error code to errno | ||
errno = res; | ||
} | ||
if (errno == ETIMEDOUT) { | ||
static const Status timed_out_status = STATUS(TimedOut, "Timed out waiting semaphore"); | ||
return timed_out_status; | ||
} | ||
if (errno == EINTR) { | ||
return Status::OK(); | ||
} | ||
return ResToStatus(res, "TimedWait"); | ||
} | ||
|
||
private: | ||
static Status ResToStatus(int res, const char* op) { | ||
if (res == 0) { | ||
return Status::OK(); | ||
} | ||
return STATUS_FORMAT(RuntimeError, "$0 on semaphore failed: $1", op, errno); | ||
} | ||
|
||
sem_t impl_; | ||
}; | ||
#else | ||
class InterprocessSemaphore { | ||
public: | ||
explicit InterprocessSemaphore(unsigned int initial_count) : impl_(initial_count) { | ||
} | ||
|
||
Status Post() { | ||
impl_.post(); | ||
return Status::OK(); | ||
} | ||
|
||
Status Wait() { | ||
impl_.wait(); | ||
return Status::OK(); | ||
} | ||
|
||
template<class TimePoint> | ||
Status TimedWait(const TimePoint &abs_time) { | ||
if (!impl_.timed_wait(abs_time)) { | ||
static const Status timed_out_status = STATUS(TimedOut, "Timed out waiting semaphore"); | ||
return timed_out_status; | ||
} | ||
return Status::OK(); | ||
} | ||
|
||
private: | ||
boost::interprocess::interprocess_semaphore impl_; | ||
}; | ||
#endif | ||
|
||
} // namespace yb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.