1//===-- tsan_sync_test.cc -------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of ThreadSanitizer (TSan), a race detector.
11//
12//===----------------------------------------------------------------------===//
13#include "tsan_sync.h"
14#include "tsan_rtl.h"
15#include "tsan_mman.h"
16#include "gtest/gtest.h"
17
18#include <stdlib.h>
19#include <stdint.h>
20#include <map>
21
22namespace __tsan {
23
24TEST(Sync, Table) {
25  const uintptr_t kIters = 512*1024;
26  const uintptr_t kRange = 10000;
27
28  ScopedInRtl in_rtl;
29  ThreadState *thr = cur_thread();
30  uptr pc = 0;
31
32  SyncTab tab;
33  SyncVar *golden[kRange] = {};
34  unsigned seed = 0;
35  for (uintptr_t i = 0; i < kIters; i++) {
36    uintptr_t addr = rand_r(&seed) % (kRange - 1) + 1;
37    if (rand_r(&seed) % 2) {
38      // Get or add.
39      SyncVar *v = tab.GetOrCreateAndLock(thr, pc, addr, true);
40      EXPECT_TRUE(golden[addr] == 0 || golden[addr] == v);
41      EXPECT_EQ(v->addr, addr);
42      golden[addr] = v;
43      v->mtx.Unlock();
44    } else {
45      // Remove.
46      SyncVar *v = tab.GetAndRemove(thr, pc, addr);
47      EXPECT_EQ(golden[addr], v);
48      if (v) {
49        EXPECT_EQ(v->addr, addr);
50        golden[addr] = 0;
51        DestroyAndFree(v);
52      }
53    }
54  }
55  for (uintptr_t addr = 0; addr < kRange; addr++) {
56    if (golden[addr] == 0)
57      continue;
58    SyncVar *v = tab.GetAndRemove(thr, pc, addr);
59    EXPECT_EQ(v, golden[addr]);
60    EXPECT_EQ(v->addr, addr);
61    DestroyAndFree(v);
62  }
63}
64
65}  // namespace __tsan
66