21 #include "gmock/gmock.h"
22 #include "absl/base/thread_annotations.h"
23 #include "absl/synchronization/internal/thread_pool.h"
24 #include "absl/synchronization/mutex.h"
25 #include "absl/synchronization/notification.h"
26 #include "absl/time/time.h"
30 namespace profiling_internal {
33 using ::absl::synchronization_internal::ThreadPool;
37 struct Info :
public Sample<Info> {
44 std::vector<size_t> GetSizes(SampleRecorder<Info>* s) {
45 std::vector<size_t> res;
46 s->Iterate([&](
const Info& info) {
47 res.push_back(info.size.load(std::memory_order_acquire));
52 std::vector<int64_t> GetWeights(SampleRecorder<Info>* s) {
53 std::vector<int64_t> res;
54 s->Iterate([&](
const Info& info) { res.push_back(info.weight); });
59 auto* info =
s->Register(
weight);
60 assert(info !=
nullptr);
61 info->size.store(
size);
65 TEST(SampleRecorderTest, Registration) {
66 SampleRecorder<Info> sampler;
67 auto* info1 = Register(&sampler, 31, 1);
71 auto* info2 = Register(&sampler, 32, 2);
77 sampler.Unregister(info1);
78 sampler.Unregister(info2);
81 TEST(SampleRecorderTest, Unregistration) {
82 SampleRecorder<Info> sampler;
83 std::vector<Info*> infos;
84 for (
size_t i = 0;
i < 3; ++
i) {
85 infos.push_back(Register(&sampler, 33 + i, i));
90 sampler.Unregister(infos[1]);
94 infos.push_back(Register(&sampler, 36, 3));
95 infos.push_back(Register(&sampler, 37, 4));
98 sampler.Unregister(infos[3]);
102 sampler.Unregister(infos[0]);
103 sampler.Unregister(infos[2]);
104 sampler.Unregister(infos[4]);
108 TEST(SampleRecorderTest, MultiThreaded) {
109 SampleRecorder<Info> sampler;
113 for (
int i = 0;
i < 10; ++
i) {
114 pool.Schedule([&sampler, &
stop, i]() {
115 std::random_device rd;
116 std::mt19937
gen(rd());
118 std::vector<Info*> infoz;
119 while (!
stop.HasBeenNotified()) {
121 infoz.push_back(sampler.Register(i));
123 switch (std::uniform_int_distribution<>(0, 2)(
gen)) {
125 infoz.push_back(sampler.Register(i));
130 std::uniform_int_distribution<>(0, infoz.size() - 1)(
gen);
131 Info* info = infoz[
p];
132 infoz[
p] = infoz.back();
135 sampler.Unregister(info);
140 sampler.Iterate([&](
const Info& info) {
156 TEST(SampleRecorderTest, Callback) {
157 SampleRecorder<Info> sampler;
159 auto* info1 = Register(&sampler, 39, 1);
160 auto* info2 = Register(&sampler, 40, 2);
162 static const Info* expected;
164 auto callback = [](
const Info& info) {
173 sampler.Unregister(info1);
178 sampler.Unregister(info2);