1 /* 2 * Copyright (C) 2011 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 ART_LIBARTBASE_BASE_UTILS_H_ 18 #define ART_LIBARTBASE_BASE_UTILS_H_ 19 20 #include <pthread.h> 21 #include <stdlib.h> 22 23 #include <random> 24 #include <string> 25 26 #include <android-base/logging.h> 27 #include <android-base/parseint.h> 28 29 #include "casts.h" 30 #include "enums.h" 31 #include "globals.h" 32 #include "macros.h" 33 34 namespace art { 35 36 static inline uint32_t PointerToLowMemUInt32(const void* p) { 37 uintptr_t intp = reinterpret_cast<uintptr_t>(p); 38 DCHECK_LE(intp, 0xFFFFFFFFU); 39 return intp & 0xFFFFFFFFU; 40 } 41 42 // Returns a human-readable size string such as "1MB". 43 std::string PrettySize(int64_t size_in_bytes); 44 45 // Splits a string using the given separator character into a vector of 46 // strings. Empty strings will be omitted. 47 void Split(const std::string& s, char separator, std::vector<std::string>* result); 48 49 // Returns the calling thread's tid. (The C libraries don't expose this.) 50 pid_t GetTid(); 51 52 // Returns the given thread's name. 53 std::string GetThreadName(pid_t tid); 54 55 // Sets the name of the current thread. The name may be truncated to an 56 // implementation-defined limit. 57 void SetThreadName(const char* thread_name); 58 59 // Reads data from "/proc/self/task/${tid}/stat". 60 void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu); 61 62 class VoidFunctor { 63 public: 64 template <typename A> 65 inline void operator() (A a ATTRIBUTE_UNUSED) const { 66 } 67 68 template <typename A, typename B> 69 inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED) const { 70 } 71 72 template <typename A, typename B, typename C> 73 inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED, C c ATTRIBUTE_UNUSED) const { 74 } 75 }; 76 77 inline bool TestBitmap(size_t idx, const uint8_t* bitmap) { 78 return ((bitmap[idx / kBitsPerByte] >> (idx % kBitsPerByte)) & 0x01) != 0; 79 } 80 81 static inline constexpr bool ValidPointerSize(size_t pointer_size) { 82 return pointer_size == 4 || pointer_size == 8; 83 } 84 85 static inline const void* EntryPointToCodePointer(const void* entry_point) { 86 uintptr_t code = reinterpret_cast<uintptr_t>(entry_point); 87 // TODO: Make this Thumb2 specific. It is benign on other architectures as code is always at 88 // least 2 byte aligned. 89 code &= ~0x1; 90 return reinterpret_cast<const void*>(code); 91 } 92 93 #if defined(__BIONIC__) 94 struct Arc4RandomGenerator { 95 typedef uint32_t result_type; 96 static constexpr uint32_t min() { return std::numeric_limits<uint32_t>::min(); } 97 static constexpr uint32_t max() { return std::numeric_limits<uint32_t>::max(); } 98 uint32_t operator() () { return arc4random(); } 99 }; 100 using RNG = Arc4RandomGenerator; 101 #else 102 using RNG = std::random_device; 103 #endif 104 105 template <typename T> 106 static T GetRandomNumber(T min, T max) { 107 CHECK_LT(min, max); 108 std::uniform_int_distribution<T> dist(min, max); 109 RNG rng; 110 return dist(rng); 111 } 112 113 // Sleep forever and never come back. 114 NO_RETURN void SleepForever(); 115 116 // Flush CPU caches. Returns true on success, false if flush failed. 117 WARN_UNUSED bool FlushCpuCaches(void* begin, void* end); 118 119 template <typename T> 120 constexpr PointerSize ConvertToPointerSize(T any) { 121 if (any == 4 || any == 8) { 122 return static_cast<PointerSize>(any); 123 } else { 124 LOG(FATAL); 125 UNREACHABLE(); 126 } 127 } 128 129 // Return -1 if <, 0 if ==, 1 if >. 130 template <typename T> 131 inline static int32_t Compare(T lhs, T rhs) { 132 return (lhs < rhs) ? -1 : ((lhs == rhs) ? 0 : 1); 133 } 134 135 // Return -1 if < 0, 0 if == 0, 1 if > 0. 136 template <typename T> 137 inline static int32_t Signum(T opnd) { 138 return (opnd < 0) ? -1 : ((opnd == 0) ? 0 : 1); 139 } 140 141 template <typename Func, typename... Args> 142 static inline void CheckedCall(const Func& function, const char* what, Args... args) { 143 int rc = function(args...); 144 if (UNLIKELY(rc != 0)) { 145 PLOG(FATAL) << "Checked call failed for " << what; 146 } 147 } 148 149 // Lookup value for a given key in /proc/self/status. Keys and values are separated by a ':' in 150 // the status file. Returns value found on success and "<unknown>" if the key is not found or 151 // there is an I/O error. 152 std::string GetProcessStatus(const char* key); 153 154 } // namespace art 155 156 #endif // ART_LIBARTBASE_BASE_UTILS_H_ 157