Path: blob/main/contrib/llvm-project/compiler-rt/lib/tsan/benchmarks/mop.cpp
35266 views
// Synthetic benchmark for __tsan_read/write{1,2,4,8}.1// As compared to mini_bench_local/shared.cc this benchmark passes through2// deduplication logic (ContainsSameAccess).3// First argument is access size (1, 2, 4, 8). Second optional arg switches4// from writes to reads.56#include <pthread.h>7#include <stdlib.h>8#include <stdio.h>9#include <unistd.h>10#include <linux/futex.h>11#include <sys/syscall.h>12#include <sys/time.h>1314template<typename T, bool write>15void* thread(void *arg) {16const int kSize = 2 << 10;17static volatile long data[kSize];18static volatile long turn;19const int kRepeat = 1 << 17;20const int id = !!arg;21for (int i = 0; i < kRepeat; i++) {22for (;;) {23int t = __atomic_load_n(&turn, __ATOMIC_ACQUIRE);24if (t == id)25break;26syscall(SYS_futex, &turn, FUTEX_WAIT, t, 0, 0, 0);27}28for (int j = 0; j < kSize; j++) {29if (write) {30((volatile T*)&data[j])[0] = 1;31((volatile T*)&data[j])[sizeof(T) == 8 ? 0 : 1] = 1;32} else {33T v0 = ((volatile T*)&data[j])[0];34T v1 = ((volatile T*)&data[j])[sizeof(T) == 8 ? 0 : 1];35(void)v0;36(void)v1;37}38}39__atomic_store_n(&turn, 1 - id, __ATOMIC_RELEASE);40syscall(SYS_futex, &turn, FUTEX_WAKE, 0, 0, 0, 0);41}42return 0;43}4445template<typename T, bool write>46void test() {47pthread_t th;48pthread_create(&th, 0, thread<T, write>, (void*)1);49thread<T, write>(0);50pthread_join(th, 0);51}5253template<bool write>54void testw(int size) {55switch (size) {56case 1: return test<char, write>();57case 2: return test<short, write>();58case 4: return test<int, write>();59case 8: return test<long long, write>();60}61}6263int main(int argc, char** argv) {64int size = 8;65bool write = true;66if (argc > 1) {67size = atoi(argv[1]);68if (size != 1 && size != 2 && size != 4 && size != 8)69size = 8;70}71if (argc > 2)72write = false;73printf("%s%d\n", write ? "write" : "read", size);74if (write)75testw<true>(size);76else77testw<false>(size);78return 0;79}808182