ronantakizawa/codereview-bench huggingface dataset:
Repository: llvm/llvm-project
File: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp (C++)

Code before:

  OS << '\'' << toHex(Chars) << '\'';

  EmitEOL();
}

void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
                                              const MCSubtargetInfo &STI) {

  InstPrinter->printInst(&Inst, 0, "", STI, OS);
  EmitEOL();
}

static void emitXATTR(raw_ostream &OS, StringRef Name, bool IsIndirectReference,
                      GOFF::ESDLinkageType Linkage,
                      GOFF::ESDExecutable Executable,
                      GOFF::ESDBindingScope BindingScope) {
  llvm::ListSeparator Sep(",");
  OS << Name << " XATTR ";
  OS << Sep << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK")
     << ")";

  const bool NotUnspecified = (Executable != GOFF::ESD_EXE_Unspecified);
  if (NotUnspecified || IsIndirectReference) {
    OS << Sep << "REFERENCE(";
    bool RequiresComma = false;

    if (NotUnspecified) {
      OS << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");
      RequiresComma = true;
    }

    if (IsIndirectReference) {
      if (RequiresComma)
        OS << ",";
      OS << "INDIRECT";
    }

    OS << ")";
  }
  if (BindingScope != GOFF::ESD_BSC_Unspecified) {
    OS << Sep << "SCOPE(";
    switch (BindingScope) {
    case GOFF::ESD_BSC_Section:
      OS << "SECTION";
      break;
    case GOFF::ESD_BSC_Module:
      OS << "MODULE";
      break;
    case GOFF::ESD_BSC_Library:
      OS << "LIBRARY";

Review comment (suggestion):
Please use
```
llvm::ListSeparator SepRef(",");
```
instead. This encapsulates the boolean logic.

Code after:

  OS << '\'' << toHex(Chars) << '\'';

  EmitEOL();
}

void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
                                              const MCSubtargetInfo &STI) {

  InstPrinter->printInst(&Inst, 0, "", STI, OS);
  EmitEOL();
}

static void emitXATTR(raw_ostream &OS, StringRef Name, bool IsIndirectReference,
                      GOFF::ESDLinkageType Linkage,
                      GOFF::ESDExecutable Executable,
                      GOFF::ESDBindingScope BindingScope) {
  llvm::ListSeparator Sep(",");
  OS << Name << " XATTR ";
  OS << Sep << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK")
     << ")";

  const bool NotUnspecified = (Executable != GOFF::ESD_EXE_Unspecified);
  if (NotUnspecified || IsIndirectReference) {
    OS << Sep << "REFERENCE(";
    llvm::ListSeparator SepRef(",");

    if (NotUnspecified)
      OS << SepRef << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");

    if (IsIndirectReference)
      OS << SepRef << "INDIRECT";

    OS << ")";
  }
  if (BindingScope != GOFF::ESD_BSC_Unspecified) {
    OS << Sep << "SCOPE(";
    switch (BindingScope) {
    case GOFF::ESD_BSC_Section:
      OS << "SECTION";
      break;
    case GOFF::ESD_BSC_Module:
      OS << "MODULE";
      break;
    case GOFF::ESD_BSC_Library:
      OS << "LIBRARY";
      break;
    case GOFF::ESD_BSC_ImportExport:
      OS << "EXPORT";
      break;
    default:
Repository: llvm/llvm-project
File: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp (C++)

Code before:

void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
                                              const MCSubtargetInfo &STI) {

  InstPrinter->printInst(&Inst, 0, "", STI, OS);
  EmitEOL();
}

static void emitXATTR(raw_ostream &OS, StringRef Name, bool IsIndirectReference,
                      GOFF::ESDLinkageType Linkage,
                      GOFF::ESDExecutable Executable,
                      GOFF::ESDBindingScope BindingScope) {
  llvm::ListSeparator Sep(",");
  OS << Name << " XATTR ";
  OS << Sep << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK")
     << ")";

  const bool NotUnspecified = (Executable != GOFF::ESD_EXE_Unspecified);
  if (NotUnspecified || IsIndirectReference) {
    OS << Sep << "REFERENCE(";
    bool RequiresComma = false;

    if (NotUnspecified) {
      OS << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");
      RequiresComma = true;
    }

    if (IsIndirectReference) {
      if (RequiresComma)
        OS << ",";
      OS << "INDIRECT";
    }

    OS << ")";
  }
  if (BindingScope != GOFF::ESD_BSC_Unspecified) {
    OS << Sep << "SCOPE(";
    switch (BindingScope) {
    case GOFF::ESD_BSC_Section:
      OS << "SECTION";
      break;
    case GOFF::ESD_BSC_Module:
      OS << "MODULE";
      break;
    case GOFF::ESD_BSC_Library:
      OS << "LIBRARY";
      break;
    case GOFF::ESD_BSC_ImportExport:
      OS << "EXPORT";
      break;
    default:

Review comment (suggestion):
With `SepRef`, this becomes

```suggestion
    if (NotUnspecified)
      OS << SepRef << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");
```

Code after:

void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
                                              const MCSubtargetInfo &STI) {

  InstPrinter->printInst(&Inst, 0, "", STI, OS);
  EmitEOL();
}

static void emitXATTR(raw_ostream &OS, StringRef Name, bool IsIndirectReference,
                      GOFF::ESDLinkageType Linkage,
                      GOFF::ESDExecutable Executable,
                      GOFF::ESDBindingScope BindingScope) {
  llvm::ListSeparator Sep(",");
  OS << Name << " XATTR ";
  OS << Sep << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK")
     << ")";

  const bool NotUnspecified = (Executable != GOFF::ESD_EXE_Unspecified);
  if (NotUnspecified || IsIndirectReference) {
    OS << Sep << "REFERENCE(";
    llvm::ListSeparator SepRef(",");

    if (NotUnspecified)
      OS << SepRef << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");

    if (IsIndirectReference)
      OS << SepRef << "INDIRECT";

    OS << ")";
  }
  if (BindingScope != GOFF::ESD_BSC_Unspecified) {
    OS << Sep << "SCOPE(";
    switch (BindingScope) {
    case GOFF::ESD_BSC_Section:
      OS << "SECTION";
      break;
    case GOFF::ESD_BSC_Module:
      OS << "MODULE";
      break;
    case GOFF::ESD_BSC_Library:
      OS << "LIBRARY";
      break;
    case GOFF::ESD_BSC_ImportExport:
      OS << "EXPORT";
      break;
    default:
      break;
    }
    OS << ')';
  }
}
Repository: llvm/llvm-project
File: llvm/lib/MC/MCAsmInfoGOFF.cpp (C++)

Code before:
      emitCATTR(OS, Sec.getName(), Sec.EDAttributes.Rmode,
                Sec.EDAttributes.Alignment, Sec.EDAttributes.LoadBehavior,
                GOFF::ESD_EXE_Unspecified, Sec.EDAttributes.IsReadOnly, 0,
                Sec.EDAttributes.FillByteValue, StringRef());
      Sec.Emitted = true;
      if (Sec.hasExternalName())
        OS << Sec.getName() << " ALIAS \"" << Sec.getExternalName() << "\"\n";
    } else
      OS << Sec.getName() << " CATTR\n";
    break;
  }
  case GOFF::ESD_ST_PartReference: {
    MCSectionGOFF *ED = Sec.getParent();
    printSwitchToSection(*ED->getParent(), Subsection, T, OS);
    if (!Sec.Emitted) {
      emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode,
                ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior,
                Sec.PRAttributes.Executable, ED->EDAttributes.IsReadOnly,
                Sec.PRAttributes.SortKey, ED->EDAttributes.FillByteValue,
                Sec.getName());
      emitXATTR(OS, Sec.getName(), Sec.PRAttributes.Linkage,
                Sec.PRAttributes.Executable, Sec.PRAttributes.BindingScope);
      ED->Emitted = true;
      Sec.Emitted = true;
      if (Sec.hasExternalName())
        OS << Sec.getName() << " ALIAS \"" << Sec.getExternalName() << "\"\n";
    } else
      OS << ED->getName() << " CATTR PART(" << Sec.getName() << ")\n";
    break;
  }
  default:
    llvm_unreachable("Wrong section type");
  }
}


Review comment (suggestion):
Same.
Looks like using a lamba would avoid the repetition, e.g.

```
auto EmitExternalName = [&Sec]() {
  if (Sec.hasExternalName())
        OS << Sec.getName() << " ALIAS "C'" << Sec.getExternalName() << "'\n";
}
```

Code after:
  case GOFF::ESD_ST_ElementDefinition: {
    printSwitchToSection(*Sec.getParent(), Subsection, T, OS);
    if (!Sec.Emitted) {
      emitCATTR(OS, Sec.getName(), Sec.EDAttributes.Rmode,
                Sec.EDAttributes.Alignment, Sec.EDAttributes.LoadBehavior,
                GOFF::ESD_EXE_Unspecified, Sec.EDAttributes.IsReadOnly, 0,
                Sec.EDAttributes.FillByteValue, StringRef());
      Sec.Emitted = true;
      EmitExternalName();
    } else
      OS << Sec.getName() << " CATTR\n";
    break;
  }
  case GOFF::ESD_ST_PartReference: {
    MCSectionGOFF *ED = Sec.getParent();
    printSwitchToSection(*ED->getParent(), Subsection, T, OS);
    if (!Sec.Emitted) {
      emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode,
                ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior,
                Sec.PRAttributes.Executable, ED->EDAttributes.IsReadOnly,
                Sec.PRAttributes.SortKey, ED->EDAttributes.FillByteValue,
                Sec.getName());
      emitXATTR(OS, Sec.getName(), Sec.PRAttributes.Linkage,
                Sec.PRAttributes.Executable, Sec.PRAttributes.BindingScope);
      ED->Emitted = true;
      Sec.Emitted = true;
      EmitExternalName();
    } else
      OS << ED->getName() << " CATTR PART(" << Sec.getName() << ")\n";
    break;
  }
  default:
    llvm_unreachable("Wrong section type");
  }
}
Repository: llvm/llvm-project
File: libc/src/__support/math/f16sqrtf128.h (C/C++)

Code before:
//===-- Implementation header for f16sqrtf128 -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_F16SQRTF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_F16SQRTF128_H

#include "include/llvm-libc-macros/float16-macros.h"
#include "include/llvm-libc-types/float128.h"

#ifdef LIBC_TYPES_HAS_FLOAT128
#ifdef LIBC_TYPES_HAS_FLOAT16

#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {
namespace math {

LIBC_INLINE constexpr float16 f16sqrtf128(float128 x) {
  return fputil::sqrt<float16>(x);
}

} // namespace math
} // namespace LIBC_NAMESPACE_DECL

#endif // LIBC_TYPES_HAS_FLOAT16
#endif // LIBC_TYPES_HAS_FLOAT128

#endif // LLVM_LIBC_SRC___SUPPORT_MATH_F16SQRTF128_H


Review comment (suggestion):
```suggestion
LIBC_INLINE float16 f16sqrtf128(float128 x) {
```

Code after:
//===-- Implementation header for f16sqrtf128 -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_F16SQRTF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_F16SQRTF128_H

#include "include/llvm-libc-macros/float16-macros.h"
#include "include/llvm-libc-types/float128.h"

#ifdef LIBC_TYPES_HAS_FLOAT128
#ifdef LIBC_TYPES_HAS_FLOAT16

#include "src/__support/FPUtil/sqrt.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {
namespace math {

LIBC_INLINE float16 f16sqrtf128(float128 x) { return fputil::sqrt<float16>(x); }

} // namespace math
} // namespace LIBC_NAMESPACE_DECL

#endif // LIBC_TYPES_HAS_FLOAT16
#endif // LIBC_TYPES_HAS_FLOAT128

#endif // LLVM_LIBC_SRC___SUPPORT_MATH_F16SQRTF128_H
Repository: llvm/llvm-project
File: lldb/include/lldb/Utility/AnsiTerminal.h (C/C++)

Code before:
  // We will indent using the stream, so leading whitespace is not significant.
  text = text.ltrim();
  if (text.empty())
    return;

  // 1 column border on the right side.
  const uint32_t max_text_width =
      output_max_columns - strm.GetIndentLevel() - 1;
  bool first_line = true;
  const std::string ansi_indent =
      ANSI_CSI_CUF(std::to_string(strm.GetIndentLevel()));

  while (!text.empty()) {
    std::string split = TrimAtWordBoundary(text, max_text_width);
    if (!first_line)
      strm.EOL();
    first_line = false;

    if (use_color) {
      // If we are allowed to use colour (aka ANSI codes), we can indent using
      // ANSI cursor movement. This means that if an ANSI formatted range of
      // text is split across two lines, the indentation is not also formatted.
      // Which it would be if we just emitted spaces.
      strm << ansi_indent << split;
    } else
      strm.Indent(split);

    text = text.drop_front(split.size()).ltrim();
  }

  strm.EOL();
}

} // namespace ansi
} // namespace lldb_private

#endif


Review comment (suggestion):
```suggestion
    } else {
      strm.Indent(split);
    }
```

Code after:
  // We will indent using the stream, so leading whitespace is not significant.
  text = text.ltrim();
  if (text.empty())
    return;

  // 1 column border on the right side.
  const uint32_t max_text_width =
      output_max_columns - strm.GetIndentLevel() - 1;
  bool first_line = true;
  const std::string ansi_indent =
      ANSI_CSI_CUF(std::to_string(strm.GetIndentLevel()));

  while (!text.empty()) {
    std::string split = TrimAtWordBoundary(text, max_text_width);
    if (!first_line)
      strm.EOL();
    first_line = false;

    if (use_color) {
      // If we are allowed to use colour (aka ANSI codes), we can indent using
      // ANSI cursor movement. This means that if an ANSI formatted range of
      // text is split across two lines, the indentation is not also formatted.
      // Which it would be if we just emitted spaces.
      strm << ansi_indent << split;
    } else {
      strm.Indent(split);
    }

    text = text.drop_front(split.size()).ltrim();
  }

  strm.EOL();
}

} // namespace ansi
} // namespace lldb_private

#endif
Repository: llvm/llvm-project
File: clang/test/Analysis/malloc-annotations.c (C)

Code before:
void testMultipleFreeAnnotations(void) {
  int *p = malloc(12);
  int *q = malloc(12);
  my_freeBoth(p, q);
}

void testNoUninitAttr(void) {
  int *p = user_malloc(sizeof(int));
  int read = p[0]; // no-warning
  clang_analyzer_dump(p[0]); // expected-warning{{Unknown}}
  user_free(p);
}

// Regression test for GH#183344 — crash when a function has both
// ownership_returns and ownership_takes attributes.
typedef struct GH183344_X GH183344_X;
typedef struct GH183344_Y GH183344_Y;

GH183344_Y *GH183344_X_to_Y(GH183344_X *x)
    __attribute__((ownership_returns(GH183344_Y)))
    __attribute__((ownership_takes(GH183344_X, 1)));

void testGH183344(void) {
  GH183344_Y *y = GH183344_X_to_Y(0); // no-crash
  (void)y;
} // expected-warning{{Potential leak of memory pointed to by 'y'}}


Review comment (suggestion):
I think, it would be good to also test that `ownership_takes`  works in such weird combination of attributes.

thanks for fixing it, tho!

Code after:
void testMultipleFreeAnnotations(void) {
  int *p = malloc(12);
  int *q = malloc(12);
  my_freeBoth(p, q);
}

void testNoUninitAttr(void) {
  int *p = user_malloc(sizeof(int));
  int read = p[0]; // no-warning
  clang_analyzer_dump(p[0]); // expected-warning{{Unknown}}
  user_free(p);
}

// Regression test for GH#183344 — crash when a function has both
// ownership_returns and ownership_takes attributes.
typedef struct GH183344_X GH183344_X;
typedef struct GH183344_Y GH183344_Y;

GH183344_Y *GH183344_X_to_Y(GH183344_X *x)
    __attribute__((ownership_returns(GH183344_Y)))
    __attribute__((ownership_takes(GH183344_X, 1)));

void testGH183344(void) {
  GH183344_Y *y = GH183344_X_to_Y(0); // no-crash
  (void)y;
} // expected-warning{{Potential leak of memory pointed to by 'y'}}

// Extended regression tests for GH#183344 — additional combinations of
// ownership_returns, ownership_takes, and ownership_holds.

GH183344_X *GH183344_alloc_X(void)
    __attribute__((ownership_returns(GH183344_X)));
void GH183344_free_X(GH183344_X *)
    __attribute__((ownership_takes(GH183344_X, 1)));
void GH183344_free_Y(GH183344_Y *)
    __attribute__((ownership_takes(GH183344_Y, 1)));

// Returns + Holds variant: Y is allocated, X is held (not consumed) by callee.
GH183344_Y *GH183344_X_to_Y_hold(GH183344_X *x)
    __attribute__((ownership_returns(GH183344_Y)))
    __attribute__((ownership_holds(GH183344_X, 1)));

// Returns + two Takes (same pool): both X arguments are consumed, Y is
// returned. Multiple arg indices in one attribute (same pool) is valid;
// two ownership_takes attributes with *different* pool names are not.
GH183344_Y *GH183344_combine_XX(GH183344_X *x1, GH183344_X *x2)
    __attribute__((ownership_returns(GH183344_Y)))
    __attribute__((ownership_takes(GH183344_X, 1, 2)));

// No-crash for Returns+Holds with null input — same crash pattern as the
// original GH183344 bug but with ownership_holds instead of ownership_takes.
Repository: llvm/llvm-project
File: flang-rt/lib/cuda/stream.cpp (C++)

Code before:
#include "flang/Runtime/CUDA/allocator.h"
#include "flang/Runtime/CUDA/common.h"
#include "flang/Support/Fortran.h"

namespace Fortran::runtime::cuda {

static thread_local cudaStream_t defaultStream{nullptr};

extern "C" {

int RTDECL(CUFSetDefaultStream)(cudaStream_t stream) {
  defaultStream = stream;
  return StatOk;
}

cudaStream_t RTDECL(CUFGetDefaultStream)() { return defaultStream; }

int RTDECL(CUFStreamSynchronize)(cudaStream_t stream) {
  return cudaStreamSynchronize(stream);
}

int RTDECL(CUFStreamSynchronizeNull)() {
  return cudaStreamSynchronize(RTNAME(CUFGetDefaultStream)());
}

int RTDECL(CUFStreamDestroy)(cudaStream_t stream) {
  CUFResetStream(stream);
  return cudaStreamDestroy(stream);
}
}

} // namespace Fortran::runtime::cuda


Review comment (suggestion):
Please also fix other instances in this file. We should use `RTDEF` for definitions.
```suggestion
int RTDEF(CUFStreamDestroy)(cudaStream_t stream) {
```

Code after:
#include "flang/Runtime/CUDA/allocator.h"
#include "flang/Runtime/CUDA/common.h"
#include "flang/Support/Fortran.h"

namespace Fortran::runtime::cuda {

static thread_local cudaStream_t defaultStream{nullptr};

extern "C" {

int RTDEF(CUFSetDefaultStream)(cudaStream_t stream) {
  defaultStream = stream;
  return StatOk;
}

cudaStream_t RTDEF(CUFGetDefaultStream)() { return defaultStream; }

int RTDEF(CUFStreamSynchronize)(cudaStream_t stream) {
  return cudaStreamSynchronize(stream);
}

int RTDEF(CUFStreamSynchronizeNull)() {
  return cudaStreamSynchronize(RTNAME(CUFGetDefaultStream)());
}

int RTDEF(CUFStreamDestroy)(cudaStream_t stream) {
  CUFResetStream(stream);
  return cudaStreamDestroy(stream);
}
}

} // namespace Fortran::runtime::cuda
Repository: llvm/llvm-project
File: flang-rt/include/flang-rt/runtime/lock.h (C/C++)

Code before:
#define FLANG_RT_RUNTIME_LOCK_H_

#include "terminator.h"
#include "tools.h"

// Avoid <mutex> if possible to avoid introduction of C++ runtime
// library dependence.
#if !defined(_WIN32) && !RT_GPU_TARGET
#define USE_PTHREADS 1
#else
#undef USE_PTHREADS
#endif

#if USE_PTHREADS
#include <pthread.h>
#elif defined(_WIN32)
#include "flang/Common/windows-include.h"
#else
#include <mutex>
#endif

namespace Fortran::runtime {

class Lock {
public:
#if RT_USE_PSEUDO_LOCK || RT_GPU_TARGET
  // No lock implementation, e.g. for using together
  // with RT_USE_PSEUDO_FILE_UNIT.
  // The users of Lock class may use it under
  // USE_PTHREADS and otherwise, so it has to provide
  // all the interfaces.
  RT_API_ATTRS void Take() {}
  RT_API_ATTRS bool Try() { return true; }
  RT_API_ATTRS void Drop() {}
  RT_API_ATTRS bool TakeIfNoDeadlock() { return true; }
#elif USE_PTHREADS
  Lock() { pthread_mutex_init(&mutex_, nullptr); }
  ~Lock() { pthread_mutex_destroy(&mutex_); }
  void Take() {
    while (pthread_mutex_lock(&mutex_)) {
    }
    holder_ = pthread_self();
    isBusy_ = true;
  }
  bool TakeIfNoDeadlock() {
    if (isBusy_) {
      auto thisThread{pthread_self()};
      if (pthread_equal(thisThread, holder_)) {
        return false;
      }
    }

Review comment (suggestion):
nit: maybe consider setting `RT_USE_PSEUDO_LOCK` in CMake for the GPU build.

Code after:
#define FLANG_RT_RUNTIME_LOCK_H_

#include "terminator.h"
#include "tools.h"

// Avoid <mutex> if possible to avoid introduction of C++ runtime
// library dependence.
#if !defined(_WIN32) && !RT_GPU_TARGET
#define USE_PTHREADS 1
#else
#undef USE_PTHREADS
#endif

#if USE_PTHREADS
#include <pthread.h>
#elif defined(_WIN32)
#include "flang/Common/windows-include.h"
#else
#include <mutex>
#endif

namespace Fortran::runtime {

class Lock {
public:
#if RT_USE_PSEUDO_LOCK
  // No lock implementation, e.g. for using together
  // with RT_USE_PSEUDO_FILE_UNIT.
  // The users of Lock class may use it under
  // USE_PTHREADS and otherwise, so it has to provide
  // all the interfaces.
  RT_API_ATTRS void Take() {}
  RT_API_ATTRS bool Try() { return true; }
  RT_API_ATTRS void Drop() {}
  RT_API_ATTRS bool TakeIfNoDeadlock() { return true; }
#elif USE_PTHREADS
  Lock() { pthread_mutex_init(&mutex_, nullptr); }
  ~Lock() { pthread_mutex_destroy(&mutex_); }
  void Take() {
    while (pthread_mutex_lock(&mutex_)) {
    }
    holder_ = pthread_self();
    isBusy_ = true;
  }
  bool TakeIfNoDeadlock() {
    if (isBusy_) {
      auto thisThread{pthread_self()};
      if (pthread_equal(thisThread, holder_)) {
        return false;
      }
    }