• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
18 #define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
19 
20 #include "perfetto/base/build_config.h"
21 #include "perfetto/base/compiler.h"
22 
23 #include <errno.h>
24 #include <stddef.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <sys/types.h>
28 
29 #include <atomic>
30 #include <string>
31 
32 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
33 // Even if Windows has errno.h, the all syscall-restart behavior does not apply.
34 // Trying to handle EINTR can cause more harm than good if errno is left stale.
35 // Chromium does the same.
36 #define PERFETTO_EINTR(x) (x)
37 #else
38 #define PERFETTO_EINTR(x)                                   \
39   ([&] {                                                    \
40     decltype(x) eintr_wrapper_result;                       \
41     do {                                                    \
42       eintr_wrapper_result = (x);                           \
43     } while (eintr_wrapper_result == -1 && errno == EINTR); \
44     return eintr_wrapper_result;                            \
45   }())
46 #endif
47 
48 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
49 using uid_t = unsigned int;
50 #if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
51 using pid_t = unsigned int;
52 #endif
53 #if defined(_WIN64)
54 using ssize_t = int64_t;
55 #else
56 using ssize_t = long;
57 #endif
58 #endif
59 
60 namespace perfetto {
61 namespace base {
62 
63 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
64 constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
65 
66 // Do not add new usages of kPageSize, consider using GetSysPageSize() below.
67 // TODO(primiano): over time the semantic of kPageSize became too ambiguous.
68 // Strictly speaking, this constant is incorrect on some new devices where the
69 // page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
70 // ended up depending on kPageSize for purposes that are not strictly related
71 // with the kernel's mm subsystem.
72 constexpr size_t kPageSize = 4096;
73 
74 // Returns the system's page size. Use this when dealing with mmap, madvise and
75 // similar mm-related syscalls.
76 uint32_t GetSysPageSize();
77 
78 template <typename T>
ArraySize(const T & array)79 constexpr size_t ArraySize(const T& array) {
80   return sizeof(array) / sizeof(array[0]);
81 }
82 
83 // Function object which invokes 'free' on its parameter, which must be
84 // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
85 //
86 // std::unique_ptr<int, base::FreeDeleter> foo_ptr(
87 //     static_cast<int*>(malloc(sizeof(int))));
88 struct FreeDeleter {
operatorFreeDeleter89   inline void operator()(void* ptr) const { free(ptr); }
90 };
91 
92 template <typename T>
AssumeLittleEndian(T value)93 constexpr T AssumeLittleEndian(T value) {
94 #if !PERFETTO_IS_LITTLE_ENDIAN()
95   static_assert(false, "Unimplemented on big-endian archs");
96 #endif
97   return value;
98 }
99 
100 // Round up |size| to a multiple of |alignment| (must be a power of two).
101 template <size_t alignment>
AlignUp(size_t size)102 constexpr size_t AlignUp(size_t size) {
103   static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
104   return (size + alignment - 1) & ~(alignment - 1);
105 }
106 
IsAgain(int err)107 inline bool IsAgain(int err) {
108   return err == EAGAIN || err == EWOULDBLOCK;
109 }
110 
111 // setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
112 void SetEnv(const std::string& key, const std::string& value);
113 
114 // Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms.
115 // This forces the allocator to release freed memory. This is used to work
116 // around various Scudo inefficiencies. See b/170217718.
117 void MaybeReleaseAllocatorMemToOS();
118 
119 // geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc).
120 uid_t GetCurrentUserId();
121 
122 // Forks the process.
123 // Parent: prints the PID of the child and exit(0).
124 // Child: redirects stdio onto /dev/null and chdirs into .
125 void Daemonize();
126 
127 }  // namespace base
128 }  // namespace perfetto
129 
130 #endif  // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
131