]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/src/core/posix.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / src / core / posix.cc
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18 /*
19 * Copyright (C) 2014 Cloudius Systems, Ltd.
20 */
21
22 #include <seastar/core/posix.hh>
23 #include <seastar/core/align.hh>
24 #include <sys/mman.h>
25
26 namespace seastar {
27
28 file_desc
29 file_desc::temporary(sstring directory) {
30 // FIXME: add O_TMPFILE support one day
31 directory += "/XXXXXX";
32 std::vector<char> templat(directory.c_str(), directory.c_str() + directory.size() + 1);
33 int fd = ::mkstemp(templat.data());
34 throw_system_error_on(fd == -1);
35 int r = ::unlink(templat.data());
36 throw_system_error_on(r == -1); // leaks created file, but what can we do?
37 return file_desc(fd);
38 }
39
40 void mmap_deleter::operator()(void* ptr) const {
41 ::munmap(ptr, _size);
42 }
43
44 mmap_area mmap_anonymous(void* addr, size_t length, int prot, int flags) {
45 auto ret = ::mmap(addr, length, prot, flags | MAP_ANONYMOUS, -1, 0);
46 throw_system_error_on(ret == MAP_FAILED);
47 return mmap_area(reinterpret_cast<char*>(ret), mmap_deleter{length});
48 }
49
50 void* posix_thread::start_routine(void* arg) noexcept {
51 auto pfunc = reinterpret_cast<std::function<void ()>*>(arg);
52 (*pfunc)();
53 return nullptr;
54 }
55
56 posix_thread::posix_thread(std::function<void ()> func)
57 : posix_thread(attr{}, std::move(func)) {
58 }
59
60 posix_thread::posix_thread(attr a, std::function<void ()> func)
61 : _func(std::make_unique<std::function<void ()>>(std::move(func))) {
62 pthread_attr_t pa;
63 auto r = pthread_attr_init(&pa);
64 if (r) {
65 throw std::system_error(r, std::system_category());
66 }
67
68 #ifndef SEASTAR_ASAN_ENABLED
69 auto stack_size = a._stack_size.size;
70 if (!stack_size) {
71 stack_size = 2 << 20;
72 }
73 // allocate guard area as well
74 _stack = mmap_anonymous(nullptr, stack_size + (4 << 20),
75 PROT_NONE, MAP_PRIVATE | MAP_NORESERVE);
76 auto stack_start = align_up(_stack.get() + 1, 2 << 20);
77 mmap_area real_stack = mmap_anonymous(stack_start, stack_size,
78 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_STACK);
79 real_stack.release(); // protected by @_stack
80 ::madvise(stack_start, stack_size, MADV_HUGEPAGE);
81 r = pthread_attr_setstack(&pa, stack_start, stack_size);
82 if (r) {
83 throw std::system_error(r, std::system_category());
84 }
85 #endif
86
87 r = pthread_create(&_pthread, &pa,
88 &posix_thread::start_routine, _func.get());
89 if (r) {
90 throw std::system_error(r, std::system_category());
91 }
92 }
93
94 posix_thread::posix_thread(posix_thread&& x)
95 : _func(std::move(x._func)), _pthread(x._pthread), _valid(x._valid)
96 , _stack(std::move(x._stack)) {
97 x._valid = false;
98 }
99
100 posix_thread::~posix_thread() {
101 assert(!_valid);
102 }
103
104 void posix_thread::join() {
105 assert(_valid);
106 pthread_join(_pthread, NULL);
107 _valid = false;
108 }
109
110 }
111