Daily bump.
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_thread_arg_retval.cpp
blobbddb2852140854c684e14a1e17e74f76ec32fe65
1 //===-- sanitizer_thread_arg_retval.cpp -------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is shared between sanitizer tools.
11 // Tracks thread arguments and return value for leak checking.
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_thread_arg_retval.h"
16 #include "sanitizer_placement_new.h"
18 namespace __sanitizer {
20 void ThreadArgRetval::CreateLocked(uptr thread, bool detached,
21 const Args& args) {
22 CheckLocked();
23 Data& t = data_[thread];
24 t = {};
25 t.gen = gen_++;
26 t.detached = detached;
27 t.args = args;
30 ThreadArgRetval::Args ThreadArgRetval::GetArgs(uptr thread) const {
31 __sanitizer::Lock lock(&mtx_);
32 auto t = data_.find(thread);
33 CHECK(t);
34 if (t->second.done)
35 return {};
36 return t->second.args;
39 void ThreadArgRetval::Finish(uptr thread, void* retval) {
40 __sanitizer::Lock lock(&mtx_);
41 auto t = data_.find(thread);
42 if (!t)
43 return;
44 if (t->second.detached) {
45 // Retval of detached thread connot be retrieved.
46 data_.erase(t);
47 return;
49 t->second.done = true;
50 t->second.args.arg_retval = retval;
53 u32 ThreadArgRetval::BeforeJoin(uptr thread) const {
54 __sanitizer::Lock lock(&mtx_);
55 auto t = data_.find(thread);
56 CHECK(t);
57 CHECK(!t->second.detached);
58 return t->second.gen;
61 void ThreadArgRetval::AfterJoin(uptr thread, u32 gen) {
62 __sanitizer::Lock lock(&mtx_);
63 auto t = data_.find(thread);
64 if (!t || gen != t->second.gen) {
65 // Thread was reused and erased by any other event.
66 return;
68 CHECK(!t->second.detached);
69 data_.erase(t);
72 void ThreadArgRetval::DetachLocked(uptr thread) {
73 CheckLocked();
74 auto t = data_.find(thread);
75 CHECK(t);
76 CHECK(!t->second.detached);
77 if (t->second.done) {
78 // We can't retrive retval after detached thread finished.
79 data_.erase(t);
80 return;
82 t->second.detached = true;
85 void ThreadArgRetval::GetAllPtrsLocked(InternalMmapVector<uptr>* ptrs) {
86 CheckLocked();
87 CHECK(ptrs);
88 data_.forEach([&](DenseMap<uptr, Data>::value_type& kv) -> bool {
89 ptrs->push_back((uptr)kv.second.args.arg_retval);
90 return true;
91 });
94 } // namespace __sanitizer