| /* | |
| * Copyright (C) 2011 The Android Open Source Project | |
| * | |
| * 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. | |
| */ | |
| #ifndef ART_LIBARTBASE_BASE_UTILS_H_ | |
| #define ART_LIBARTBASE_BASE_UTILS_H_ | |
| #include <pthread.h> | |
| #include <stdlib.h> | |
| #include <random> | |
| #include <string> | |
| #include <android-base/logging.h> | |
| #include <android-base/parseint.h> | |
| #include "casts.h" | |
| #include "globals.h" | |
| #include "macros.h" | |
| #include "pointer_size.h" | |
| #if defined(__linux__) | |
| #include <sys/utsname.h> | |
| #endif | |
| namespace art { | |
| static inline uint32_t PointerToLowMemUInt32(const void* p) { | |
| uintptr_t intp = reinterpret_cast<uintptr_t>(p); | |
| DCHECK_LE(intp, 0xFFFFFFFFU); | |
| return intp & 0xFFFFFFFFU; | |
| } | |
| // Returns a human-readable size string such as "1MB". | |
| std::string PrettySize(uint64_t size_in_bytes); | |
| // Splits a string using the given separator character into a vector of | |
| // strings. Empty strings will be omitted. | |
| template<typename StrIn, typename Str> | |
| void Split(const StrIn& s, char separator, std::vector<Str>* out_result); | |
| template<typename Str> | |
| void Split(const Str& s, char separator, size_t len, Str* out_result); | |
| template<typename StrIn, typename Str, size_t kLen> | |
| void Split(const StrIn& s, char separator, std::array<Str, kLen>* out_result) { | |
| Split<Str>(Str(s), separator, kLen, &((*out_result)[0])); | |
| } | |
| // Returns the calling thread's tid. (The C libraries don't expose this.) | |
| uint32_t GetTid(); | |
| // Returns the given thread's name. | |
| std::string GetThreadName(pid_t tid); | |
| // Sets the pthread name of the current thread. The name may be truncated to an | |
| // implementation-defined limit. | |
| void SetThreadName(const char* thread_name); | |
| // Sets the pthread name of the given thread. The name may be truncated to an | |
| // implementation-defined limit. Does nothing if not supported by the OS. | |
| void SetThreadName(pthread_t thr, const char* thread_name); | |
| // Reads data from "/proc/self/task/${tid}/stat". | |
| void GetTaskStats(pid_t tid, char* state, int* utime, int* stime, int* task_cpu); | |
| class VoidFunctor { | |
| public: | |
| template <typename A> | |
| inline void operator()([[maybe_unused]] A a) const {} | |
| template <typename A, typename B> | |
| inline void operator()([[maybe_unused]] A a, [[maybe_unused]] B b) const {} | |
| template <typename A, typename B, typename C> | |
| inline void operator()([[maybe_unused]] A a, [[maybe_unused]] B b, [[maybe_unused]] C c) const {} | |
| }; | |
| static inline const void* EntryPointToCodePointer(const void* entry_point) { | |
| uintptr_t code = reinterpret_cast<uintptr_t>(entry_point); | |
| // TODO: Make this Thumb2 specific. It is benign on other architectures as code is always at | |
| // least 2 byte aligned. | |
| code &= ~0x1; | |
| return reinterpret_cast<const void*>(code); | |
| } | |
| #if defined(__BIONIC__) | |
| struct Arc4RandomGenerator { | |
| using result_type = uint32_t; | |
| static constexpr uint32_t min() { return std::numeric_limits<uint32_t>::min(); } | |
| static constexpr uint32_t max() { return std::numeric_limits<uint32_t>::max(); } | |
| uint32_t operator() () { return arc4random(); } | |
| }; | |
| using RNG = Arc4RandomGenerator; | |
| #else | |
| using RNG = std::random_device; | |
| #endif | |
| template <typename T> | |
| static T GetRandomNumber(T min, T max) { | |
| CHECK_LT(min, max); | |
| std::uniform_int_distribution<T> dist(min, max); | |
| RNG rng; | |
| return dist(rng); | |
| } | |
| // Sleep forever and never come back. | |
| NO_RETURN void SleepForever(); | |
| // Flush CPU caches. Returns true on success, false if flush failed. | |
| WARN_UNUSED bool FlushCpuCaches(void* begin, void* end); | |
| #if defined(__linux__) | |
| bool IsKernelVersionAtLeast(int reqd_major, int reqd_minor); | |
| #endif | |
| // On some old kernels, a cache operation may segfault. | |
| WARN_UNUSED bool CacheOperationsMaySegFault(); | |
| // Is the execution environment on a virtual machine? See ART_TEST_ON_VM. | |
| WARN_UNUSED bool RunningOnVM(); | |
| template <typename Func, typename... Args> | |
| static inline void CheckedCall(const Func& function, const char* what, Args... args) { | |
| int rc = function(args...); | |
| if (UNLIKELY(rc != 0)) { | |
| PLOG(FATAL) << "Checked call failed for " << what; | |
| } | |
| } | |
| // Forces the compiler to emit a load instruction, but discards the value. | |
| // Useful when dealing with memory paging. | |
| template <typename T> | |
| inline void ForceRead(const T* pointer) { | |
| static_cast<void>(*const_cast<volatile T*>(pointer)); | |
| } | |
| // Lookup value for a given key in /proc/self/status. Keys and values are separated by a ':' in | |
| // the status file. Returns value found on success and "<unknown>" if the key is not found or | |
| // there is an I/O error. | |
| std::string GetProcessStatus(const char* key); | |
| // Copy a prefix of /proc/pid/task/tid/stat of the given length into buf. Return the number of | |
| // bytes actually read, 0 on error. | |
| size_t GetOsThreadStat(pid_t tid, char* buf, size_t len); | |
| // Return a short prefix of /proc/pid/task/tid/stat as quickly and robustly as possible. Used for | |
| // debugging timing issues and possibly issues with /proc itself. Always atomic. | |
| std::string GetOsThreadStatQuick(pid_t tid); | |
| // Given a /proc/.../stat string or prefix, such as those returned by the above, return the single | |
| // character representation of the thread state from that string, or '?' if it can't be found. | |
| char GetStateFromStatString(const std::string& stat_output); | |
| // Return a concatenation of the output of GetOsThreadStatQuick(tid) for all other tids. | |
| // Less robust against concurrent change, but individual stat strings should still always | |
| // be consistent. Called only when we are nearly certain to crash anyway. | |
| std::string GetOtherThreadOsStats(); | |
| } // namespace art | |
| #endif // ART_LIBARTBASE_BASE_UTILS_H_ |