10b57cec5SDimitry Andric //===-- xray_utils.h --------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file is a part of XRay, a dynamic runtime instrumentation system.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // Some shared utilities for the XRay runtime implementation.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric #ifndef XRAY_UTILS_H
150b57cec5SDimitry Andric #define XRAY_UTILS_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include <cstddef>
180b57cec5SDimitry Andric #include <cstdint>
190b57cec5SDimitry Andric #include <sys/types.h>
200b57cec5SDimitry Andric #include <utility>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_common.h"
230b57cec5SDimitry Andric #if SANITIZER_FUCHSIA
240b57cec5SDimitry Andric #include <zircon/types.h>
250b57cec5SDimitry Andric #endif
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace __xray {
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric class LogWriter {
300b57cec5SDimitry Andric public:
310b57cec5SDimitry Andric #if SANITIZER_FUCHSIA
LogWriter(zx_handle_t Vmo)320b57cec5SDimitry Andric  LogWriter(zx_handle_t Vmo) : Vmo(Vmo) {}
330b57cec5SDimitry Andric #else
340b57cec5SDimitry Andric   explicit LogWriter(int Fd) : Fd(Fd) {}
350b57cec5SDimitry Andric #endif
360b57cec5SDimitry Andric  ~LogWriter();
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric  // Write a character range into a log.
390b57cec5SDimitry Andric  void WriteAll(const char *Begin, const char *End);
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric  void Flush();
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric  // Returns a new log instance initialized using the flag-provided values.
440b57cec5SDimitry Andric  static LogWriter *Open();
450b57cec5SDimitry Andric  // Closes and deallocates the log instance.
460b57cec5SDimitry Andric  static void Close(LogWriter *LogWriter);
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric private:
490b57cec5SDimitry Andric #if SANITIZER_FUCHSIA
500b57cec5SDimitry Andric  zx_handle_t Vmo = ZX_HANDLE_INVALID;
510b57cec5SDimitry Andric  uint64_t Offset = 0;
520b57cec5SDimitry Andric #else
530b57cec5SDimitry Andric  int Fd = -1;
540b57cec5SDimitry Andric #endif
550b57cec5SDimitry Andric };
560b57cec5SDimitry Andric 
gcd(size_t a,size_t b)570b57cec5SDimitry Andric constexpr size_t gcd(size_t a, size_t b) {
580b57cec5SDimitry Andric   return (b == 0) ? a : gcd(b, a % b);
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
lcm(size_t a,size_t b)610b57cec5SDimitry Andric constexpr size_t lcm(size_t a, size_t b) { return a * b / gcd(a, b); }
620b57cec5SDimitry Andric 
nearest_boundary(size_t number,size_t multiple)630b57cec5SDimitry Andric constexpr size_t nearest_boundary(size_t number, size_t multiple) {
640b57cec5SDimitry Andric   return multiple * ((number / multiple) + (number % multiple ? 1 : 0));
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
next_pow2_helper(size_t num,size_t acc)670b57cec5SDimitry Andric constexpr size_t next_pow2_helper(size_t num, size_t acc) {
680b57cec5SDimitry Andric   return (1u << acc) >= num ? (1u << acc) : next_pow2_helper(num, acc + 1);
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
next_pow2(size_t number)710b57cec5SDimitry Andric constexpr size_t next_pow2(size_t number) {
720b57cec5SDimitry Andric   return next_pow2_helper(number, 1);
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric 
max(T & A,T & B)750b57cec5SDimitry Andric template <class T> constexpr T &max(T &A, T &B) { return A > B ? A : B; }
760b57cec5SDimitry Andric 
min(T & A,T & B)770b57cec5SDimitry Andric template <class T> constexpr T &min(T &A, T &B) { return A <= B ? A : B; }
780b57cec5SDimitry Andric 
diff(uintptr_t A,uintptr_t B)790b57cec5SDimitry Andric constexpr ptrdiff_t diff(uintptr_t A, uintptr_t B) {
800b57cec5SDimitry Andric   return max(A, B) - min(A, B);
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric } // namespace __xray
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric #endif // XRAY_UTILS_H
86