head	1.3;
access;
symbols
	netbsd-11-0-RELEASE:1.3
	netbsd-11-0-RC7:1.3
	netbsd-11-0-RC6:1.3
	netbsd-11-0-RC5:1.3
	netbsd-11-0-RC4:1.3
	netbsd-11-0-RC3:1.3
	netbsd-11-0-RC2:1.3
	netbsd-11-0-RC1:1.3
	gcc-14-3-0:1.1.1.2
	perseant-exfatfs-base-20250801:1.3
	netbsd-11:1.3.0.4
	netbsd-11-base:1.3
	gcc-12-5-0:1.1.1.2
	perseant-exfatfs-base-20240630:1.3
	gcc-12-4-0:1.1.1.2
	perseant-exfatfs:1.3.0.2
	perseant-exfatfs-base:1.3
	gcc-12-3-0:1.1.1.2
	gcc-10-5-0:1.1.1.1
	gcc-10-4-0:1.1.1.1
	cjep_sun2x:1.2.0.4
	cjep_sun2x-base:1.2
	cjep_staticlib_x-base1:1.2
	cjep_staticlib_x:1.2.0.2
	cjep_staticlib_x-base:1.2
	gcc-10-3-0:1.1.1.1
	FSF:1.1.1;
locks; strict;
comment	@// @;


1.3
date	2023.07.31.01.44.56;	author mrg;	state Exp;
branches;
next	1.2;
commitid	q79F5Opf0FLsyTyE;

1.2
date	2021.04.11.23.54.27;	author mrg;	state dead;
branches;
next	1.1;
commitid	wJn7ggfUTEMOWVOC;

1.1
date	2021.04.10.22.09.22;	author mrg;	state Exp;
branches
	1.1.1.1;
next	;
commitid	eC4g0MRpqTvEkNOC;

1.1.1.1
date	2021.04.10.22.09.22;	author mrg;	state Exp;
branches;
next	1.1.1.2;
commitid	eC4g0MRpqTvEkNOC;

1.1.1.2
date	2023.07.30.05.20.40;	author mrg;	state Exp;
branches;
next	;
commitid	tk6nV4mbc9nVEMyE;


desc
@@


1.3
log
@make this actually be GCC 12.3.0's libsanitizer.

the libsanitizer we used with GCC 9 and GCC 10 was significantly
ahead of the GCC 9 and GCC 10 provided versions.
@
text
@//===-- sanitizer_deadlock_detector1.cpp ----------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Deadlock detector implementation based on NxN adjacency bit matrix.
//
//===----------------------------------------------------------------------===//

#include "sanitizer_deadlock_detector_interface.h"
#include "sanitizer_deadlock_detector.h"
#include "sanitizer_allocator_internal.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_mutex.h"

#if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1

namespace __sanitizer {

typedef TwoLevelBitVector<> DDBV;  // DeadlockDetector's bit vector.

struct DDPhysicalThread {
};

struct DDLogicalThread {
  u64 ctx;
  DeadlockDetectorTLS<DDBV> dd;
  DDReport rep;
  bool report_pending;
};

struct DD final : public DDetector {
  SpinMutex mtx;
  DeadlockDetector<DDBV> dd;
  DDFlags flags;

  explicit DD(const DDFlags *flags);

  DDPhysicalThread *CreatePhysicalThread() override;
  void DestroyPhysicalThread(DDPhysicalThread *pt) override;

  DDLogicalThread *CreateLogicalThread(u64 ctx) override;
  void DestroyLogicalThread(DDLogicalThread *lt) override;

  void MutexInit(DDCallback *cb, DDMutex *m) override;
  void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) override;
  void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock,
                      bool trylock) override;
  void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) override;
  void MutexDestroy(DDCallback *cb, DDMutex *m) override;

  DDReport *GetReport(DDCallback *cb) override;

  void MutexEnsureID(DDLogicalThread *lt, DDMutex *m);
  void ReportDeadlock(DDCallback *cb, DDMutex *m);
};

DDetector *DDetector::Create(const DDFlags *flags) {
  (void)flags;
  void *mem = MmapOrDie(sizeof(DD), "deadlock detector");
  return new(mem) DD(flags);
}

DD::DD(const DDFlags *flags)
    : flags(*flags) {
  dd.clear();
}

DDPhysicalThread* DD::CreatePhysicalThread() {
  return nullptr;
}

void DD::DestroyPhysicalThread(DDPhysicalThread *pt) {
}

DDLogicalThread* DD::CreateLogicalThread(u64 ctx) {
  DDLogicalThread *lt = (DDLogicalThread*)InternalAlloc(sizeof(*lt));
  lt->ctx = ctx;
  lt->dd.clear();
  lt->report_pending = false;
  return lt;
}

void DD::DestroyLogicalThread(DDLogicalThread *lt) {
  lt->~DDLogicalThread();
  InternalFree(lt);
}

void DD::MutexInit(DDCallback *cb, DDMutex *m) {
  m->id = 0;
  m->stk = cb->Unwind();
}

void DD::MutexEnsureID(DDLogicalThread *lt, DDMutex *m) {
  if (!dd.nodeBelongsToCurrentEpoch(m->id))
    m->id = dd.newNode(reinterpret_cast<uptr>(m));
  dd.ensureCurrentEpoch(&lt->dd);
}

void DD::MutexBeforeLock(DDCallback *cb,
    DDMutex *m, bool wlock) {
  DDLogicalThread *lt = cb->lt;
  if (lt->dd.empty()) return;  // This will be the first lock held by lt.
  if (dd.hasAllEdges(&lt->dd, m->id)) return;  // We already have all edges.
  SpinMutexLock lk(&mtx);
  MutexEnsureID(lt, m);
  if (dd.isHeld(&lt->dd, m->id))
    return;  // FIXME: allow this only for recursive locks.
  if (dd.onLockBefore(&lt->dd, m->id)) {
    // Actually add this edge now so that we have all the stack traces.
    dd.addEdges(&lt->dd, m->id, cb->Unwind(), cb->UniqueTid());
    ReportDeadlock(cb, m);
  }
}

void DD::ReportDeadlock(DDCallback *cb, DDMutex *m) {
  DDLogicalThread *lt = cb->lt;
  uptr path[20];
  uptr len = dd.findPathToLock(&lt->dd, m->id, path, ARRAY_SIZE(path));
  if (len == 0U) {
    // A cycle of 20+ locks? Well, that's a bit odd...
    Printf("WARNING: too long mutex cycle found\n");
    return;
  }
  CHECK_EQ(m->id, path[0]);
  lt->report_pending = true;
  len = Min<uptr>(len, DDReport::kMaxLoopSize);
  DDReport *rep = &lt->rep;
  rep->n = len;
  for (uptr i = 0; i < len; i++) {
    uptr from = path[i];
    uptr to = path[(i + 1) % len];
    DDMutex *m0 = (DDMutex*)dd.getData(from);
    DDMutex *m1 = (DDMutex*)dd.getData(to);

    u32 stk_from = 0, stk_to = 0;
    int unique_tid = 0;
    dd.findEdge(from, to, &stk_from, &stk_to, &unique_tid);
    // Printf("Edge: %zd=>%zd: %u/%u T%d\n", from, to, stk_from, stk_to,
    //    unique_tid);
    rep->loop[i].thr_ctx = unique_tid;
    rep->loop[i].mtx_ctx0 = m0->ctx;
    rep->loop[i].mtx_ctx1 = m1->ctx;
    rep->loop[i].stk[0] = stk_to;
    rep->loop[i].stk[1] = stk_from;
  }
}

void DD::MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, bool trylock) {
  DDLogicalThread *lt = cb->lt;
  u32 stk = 0;
  if (flags.second_deadlock_stack)
    stk = cb->Unwind();
  // Printf("T%p MutexLock:   %zx stk %u\n", lt, m->id, stk);
  if (dd.onFirstLock(&lt->dd, m->id, stk))
    return;
  if (dd.onLockFast(&lt->dd, m->id, stk))
    return;

  SpinMutexLock lk(&mtx);
  MutexEnsureID(lt, m);
  if (wlock)  // Only a recursive rlock may be held.
    CHECK(!dd.isHeld(&lt->dd, m->id));
  if (!trylock)
    dd.addEdges(&lt->dd, m->id, stk ? stk : cb->Unwind(), cb->UniqueTid());
  dd.onLockAfter(&lt->dd, m->id, stk);
}

void DD::MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {
  // Printf("T%p MutexUnLock: %zx\n", cb->lt, m->id);
  dd.onUnlock(&cb->lt->dd, m->id);
}

void DD::MutexDestroy(DDCallback *cb,
    DDMutex *m) {
  if (!m->id) return;
  SpinMutexLock lk(&mtx);
  if (dd.nodeBelongsToCurrentEpoch(m->id))
    dd.removeNode(m->id);
  m->id = 0;
}

DDReport *DD::GetReport(DDCallback *cb) {
  if (!cb->lt->report_pending)
    return nullptr;
  cb->lt->report_pending = false;
  return &cb->lt->rep;
}

} // namespace __sanitizer
#endif // #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1
@


1.2
log
@revert sanitizer back to the version we were using with GCC 9, since
that one was already newer than the GCC 10 version.
@
text
@d35 1
a35 1
struct DD : public DDetector {
d139 1
a139 1
    u32 stk_from = -1U, stk_to = -1U;
@


1.1
log
@Initial revision
@
text
@@


1.1.1.1
log
@initial import of GCC 10.3.0.  main changes include:

caveats:
- ABI issue between c++14 and c++17 fixed
- profile mode is removed from libstdc++
- -fno-common is now the default

new features:
- new flags -fallocation-dce, -fprofile-partial-training,
  -fprofile-reproducible, -fprofile-prefix-path, and -fanalyzer
- many new compile and link time optimisations
- enhanced drive optimisations
- openacc 2.6 support
- openmp 5.0 features
- new warnings: -Wstring-compare and -Wzero-length-bounds
- extended warnings: -Warray-bounds, -Wformat-overflow,
  -Wrestrict, -Wreturn-local-addr, -Wstringop-overflow,
  -Warith-conversion, -Wmismatched-tags, and -Wredundant-tags
- some likely C2X features implemented
- more C++20 implemented
- many new arm & intel CPUs known

hundreds of reported bugs are fixed.  full list of changes
can be found at:

   https://gcc.gnu.org/gcc-10/changes.html
@
text
@@


1.1.1.2
log
@initial import of GCC 12.3.0.

major changes in GCC 11 included:

- The default mode for C++ is now -std=gnu++17 instead of -std=gnu++14.
- When building GCC itself, the host compiler must now support C++11,
  rather than C++98.
- Some short options of the gcov tool have been renamed: -i to -j and
  -j to -H.
- ThreadSanitizer improvements.
- Introduce Hardware-assisted AddressSanitizer support.
- For targets that produce DWARF debugging information GCC now defaults
  to DWARF version 5. This can produce up to 25% more compact debug
  information compared to earlier versions.
- Many optimisations.
- The existing malloc attribute has been extended so that it can be
  used to identify allocator/deallocator API pairs. A pair of new
  -Wmismatched-dealloc and -Wmismatched-new-delete warnings are added.
- Other new warnings:
  -Wsizeof-array-div, enabled by -Wall, warns about divisions of two
    sizeof operators when the first one is applied to an array and the
    divisor does not equal the size of the array element.
  -Wstringop-overread, enabled by default, warns about calls to string
    functions reading past the end of the arrays passed to them as
    arguments.
  -Wtsan, enabled by default, warns about unsupported features in
    ThreadSanitizer (currently std::atomic_thread_fence).
- Enchanced warnings:
  -Wfree-nonheap-object detects many more instances of calls to
    deallocation functions with pointers not returned from a dynamic
    memory allocation function.
  -Wmaybe-uninitialized diagnoses passing pointers or references to
    uninitialized memory to functions taking const-qualified arguments.
  -Wuninitialized detects reads from uninitialized dynamically
    allocated memory.
  -Warray-parameter warns about functions with inconsistent array forms.
  -Wvla-parameter warns about functions with inconsistent VLA forms.
- Several new features from the upcoming C2X revision of the ISO C
  standard are supported with -std=c2x and -std=gnu2x.
- Several C++20 features have been implemented.
- The C++ front end has experimental support for some of the upcoming
  C++23 draft.
- Several new C++ warnings.
- Enhanced Arm, AArch64, x86, and RISC-V CPU support.
- The implementation of how program state is tracked within
  -fanalyzer has been completely rewritten with many enhancements.

see https://gcc.gnu.org/gcc-11/changes.html for a full list.

major changes in GCC 12 include:

- An ABI incompatibility between C and C++ when passing or returning
  by value certain aggregates containing zero width bit-fields has
  been discovered on various targets. x86-64, ARM and AArch64
  will always ignore them (so there is a C ABI incompatibility
  between GCC 11 and earlier with GCC 12 or later), PowerPC64 ELFv2
  always take them into account (so there is a C++ ABI
  incompatibility, GCC 4.4 and earlier compatible with GCC 12 or
  later, incompatible with GCC 4.5 through GCC 11). RISC-V has
  changed the handling of these already starting with GCC 10. As
  the ABI requires, MIPS takes them into account handling function
  return values so there is a C++ ABI incompatibility with GCC 4.5
  through 11.
- STABS: Support for emitting the STABS debugging format is
  deprecated and will be removed in the next release. All ports now
  default to emit DWARF (version 2 or later) debugging info or are
  obsoleted.
- Vectorization is enabled at -O2 which is now equivalent to the
  original -O2 -ftree-vectorize -fvect-cost-model=very-cheap.
- GCC now supports the ShadowCallStack sanitizer.
- Support for __builtin_shufflevector compatible with the clang
  language extension was added.
- Support for attribute unavailable was added.
- Support for __builtin_dynamic_object_size compatible with the
  clang language extension was added.
- New warnings:
  -Wbidi-chars warns about potentially misleading UTF-8
    bidirectional control characters.
  -Warray-compare warns about comparisons between two operands of
    array type.
- Some new features from the upcoming C2X revision of the ISO C
  standard are supported with -std=c2x and -std=gnu2x.
- Several C++23 features have been implemented.
- Many C++ enhancements across warnings and -f options.

see https://gcc.gnu.org/gcc-12/changes.html for a full list.
@
text
@d35 1
a35 1
struct DD final : public DDetector {
d139 1
a139 1
    u32 stk_from = 0, stk_to = 0;
@

