| 1938 | }; |
| 1939 | |
| 1940 | static void MTThreadBody(void* arg) { |
| 1941 | MTThread* t = reinterpret_cast<MTThread*>(arg); |
| 1942 | int id = t->id; |
| 1943 | DB* db = t->state->test->db_; |
| 1944 | int counter = 0; |
| 1945 | fprintf(stderr, "... starting thread %d\n", id); |
| 1946 | Random rnd(1000 + id); |
| 1947 | std::string value; |
| 1948 | char valbuf[1500]; |
| 1949 | while (!t->state->stop.load(std::memory_order_acquire)) { |
| 1950 | t->state->counter[id].store(counter, std::memory_order_release); |
| 1951 | |
| 1952 | int key = rnd.Uniform(kNumKeys); |
| 1953 | char keybuf[20]; |
| 1954 | snprintf(keybuf, sizeof(keybuf), "%016d", key); |
| 1955 | |
| 1956 | if (rnd.OneIn(2)) { |
| 1957 | // Write values of the form <key, my id, counter>. |
| 1958 | // We add some padding for force compactions. |
| 1959 | snprintf(valbuf, sizeof(valbuf), "%d.%d.%-1000d", key, id, |
| 1960 | static_cast<int>(counter)); |
| 1961 | ASSERT_OK(db->Put(WriteOptions(), Slice(keybuf), Slice(valbuf))); |
| 1962 | } else { |
| 1963 | // Read a value and verify that it matches the pattern written above. |
| 1964 | Status s = db->Get(ReadOptions(), Slice(keybuf), &value); |
| 1965 | if (s.IsNotFound()) { |
| 1966 | // Key has not yet been written |
| 1967 | } else { |
| 1968 | // Check that the writer thread counter is >= the counter in the value |
| 1969 | ASSERT_OK(s); |
| 1970 | int k, w, c; |
| 1971 | ASSERT_EQ(3, sscanf(value.c_str(), "%d.%d.%d", &k, &w, &c)) << value; |
| 1972 | ASSERT_EQ(k, key); |
| 1973 | ASSERT_GE(w, 0); |
| 1974 | ASSERT_LT(w, kNumThreads); |
| 1975 | ASSERT_LE(c, t->state->counter[w].load(std::memory_order_acquire)); |
| 1976 | } |
| 1977 | } |
| 1978 | counter++; |
| 1979 | } |
| 1980 | t->state->thread_done[id].store(true, std::memory_order_release); |
| 1981 | fprintf(stderr, "... stopping thread %d after %d ops\n", id, counter); |
| 1982 | } |
| 1983 | |
| 1984 | } // namespace |
| 1985 |
nothing calls this directly
no test coverage detected