Changeset View
Changeset View
Standalone View
Standalone View
src/leveldb/util/env_test.cc
// Copyright (c) 2011 The LevelDB Authors. All rights reserved. | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. | ||||
// Use of this source code is governed by a BSD-style license that can be | // Use of this source code is governed by a BSD-style license that can be | ||||
// found in the LICENSE file. See the AUTHORS file for names of contributors. | // found in the LICENSE file. See the AUTHORS file for names of contributors. | ||||
#include "leveldb/env.h" | #include "leveldb/env.h" | ||||
#include "port/port.h" | #include "port/port.h" | ||||
#include "util/testharness.h" | #include "util/testharness.h" | ||||
namespace leveldb { | namespace leveldb { | ||||
static const int kDelayMicros = 100000; | static const int kDelayMicros = 100000; | ||||
static const int kReadOnlyFileLimit = 4; | |||||
static const int kMMapLimit = 4; | |||||
class EnvPosixTest { | class EnvTest { | ||||
private: | private: | ||||
port::Mutex mu_; | port::Mutex mu_; | ||||
std::string events_; | std::string events_; | ||||
public: | public: | ||||
Env* env_; | Env* env_; | ||||
EnvPosixTest() : env_(Env::Default()) { } | EnvTest() : env_(Env::Default()) { } | ||||
}; | }; | ||||
static void SetBool(void* ptr) { | static void SetBool(void* ptr) { | ||||
reinterpret_cast<port::AtomicPointer*>(ptr)->NoBarrier_Store(ptr); | reinterpret_cast<port::AtomicPointer*>(ptr)->NoBarrier_Store(ptr); | ||||
} | } | ||||
TEST(EnvPosixTest, RunImmediately) { | TEST(EnvTest, RunImmediately) { | ||||
port::AtomicPointer called (NULL); | port::AtomicPointer called (NULL); | ||||
env_->Schedule(&SetBool, &called); | env_->Schedule(&SetBool, &called); | ||||
Env::Default()->SleepForMicroseconds(kDelayMicros); | env_->SleepForMicroseconds(kDelayMicros); | ||||
ASSERT_TRUE(called.NoBarrier_Load() != NULL); | ASSERT_TRUE(called.NoBarrier_Load() != NULL); | ||||
} | } | ||||
TEST(EnvPosixTest, RunMany) { | TEST(EnvTest, RunMany) { | ||||
port::AtomicPointer last_id (NULL); | port::AtomicPointer last_id (NULL); | ||||
struct CB { | struct CB { | ||||
port::AtomicPointer* last_id_ptr; // Pointer to shared slot | port::AtomicPointer* last_id_ptr; // Pointer to shared slot | ||||
uintptr_t id; // Order# for the execution of this callback | uintptr_t id; // Order# for the execution of this callback | ||||
CB(port::AtomicPointer* p, int i) : last_id_ptr(p), id(i) { } | CB(port::AtomicPointer* p, int i) : last_id_ptr(p), id(i) { } | ||||
Show All 10 Lines | TEST(EnvTest, RunMany) { | ||||
CB cb2(&last_id, 2); | CB cb2(&last_id, 2); | ||||
CB cb3(&last_id, 3); | CB cb3(&last_id, 3); | ||||
CB cb4(&last_id, 4); | CB cb4(&last_id, 4); | ||||
env_->Schedule(&CB::Run, &cb1); | env_->Schedule(&CB::Run, &cb1); | ||||
env_->Schedule(&CB::Run, &cb2); | env_->Schedule(&CB::Run, &cb2); | ||||
env_->Schedule(&CB::Run, &cb3); | env_->Schedule(&CB::Run, &cb3); | ||||
env_->Schedule(&CB::Run, &cb4); | env_->Schedule(&CB::Run, &cb4); | ||||
Env::Default()->SleepForMicroseconds(kDelayMicros); | env_->SleepForMicroseconds(kDelayMicros); | ||||
void* cur = last_id.Acquire_Load(); | void* cur = last_id.Acquire_Load(); | ||||
ASSERT_EQ(4, reinterpret_cast<uintptr_t>(cur)); | ASSERT_EQ(4, reinterpret_cast<uintptr_t>(cur)); | ||||
} | } | ||||
struct State { | struct State { | ||||
port::Mutex mu; | port::Mutex mu; | ||||
int val; | int val; | ||||
int num_running; | int num_running; | ||||
}; | }; | ||||
static void ThreadBody(void* arg) { | static void ThreadBody(void* arg) { | ||||
State* s = reinterpret_cast<State*>(arg); | State* s = reinterpret_cast<State*>(arg); | ||||
s->mu.Lock(); | s->mu.Lock(); | ||||
s->val += 1; | s->val += 1; | ||||
s->num_running -= 1; | s->num_running -= 1; | ||||
s->mu.Unlock(); | s->mu.Unlock(); | ||||
} | } | ||||
TEST(EnvPosixTest, StartThread) { | TEST(EnvTest, StartThread) { | ||||
State state; | State state; | ||||
state.val = 0; | state.val = 0; | ||||
state.num_running = 3; | state.num_running = 3; | ||||
for (int i = 0; i < 3; i++) { | for (int i = 0; i < 3; i++) { | ||||
env_->StartThread(&ThreadBody, &state); | env_->StartThread(&ThreadBody, &state); | ||||
} | } | ||||
while (true) { | while (true) { | ||||
state.mu.Lock(); | state.mu.Lock(); | ||||
int num = state.num_running; | int num = state.num_running; | ||||
state.mu.Unlock(); | state.mu.Unlock(); | ||||
if (num == 0) { | if (num == 0) { | ||||
break; | break; | ||||
} | } | ||||
Env::Default()->SleepForMicroseconds(kDelayMicros); | env_->SleepForMicroseconds(kDelayMicros); | ||||
} | } | ||||
ASSERT_EQ(state.val, 3); | ASSERT_EQ(state.val, 3); | ||||
} | } | ||||
} // namespace leveldb | } // namespace leveldb | ||||
int main(int argc, char** argv) { | int main(int argc, char** argv) { | ||||
return leveldb::test::RunAllTests(); | return leveldb::test::RunAllTests(); | ||||
} | } |