作者: 谢瑞阳 10225101483 徐翔宇 10225101535
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

104 Zeilen
2.5 KiB

  1. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. #include "leveldb/env.h"
  5. #include "port/port.h"
  6. #include "util/testharness.h"
  7. namespace leveldb {
  8. static const int kDelayMicros = 100000;
  9. class EnvPosixTest {
  10. private:
  11. port::Mutex mu_;
  12. std::string events_;
  13. public:
  14. Env* env_;
  15. EnvPosixTest() : env_(Env::Default()) { }
  16. };
  17. static void SetBool(void* ptr) {
  18. reinterpret_cast<port::AtomicPointer*>(ptr)->NoBarrier_Store(ptr);
  19. }
  20. TEST(EnvPosixTest, RunImmediately) {
  21. port::AtomicPointer called (NULL);
  22. env_->Schedule(&SetBool, &called);
  23. Env::Default()->SleepForMicroseconds(kDelayMicros);
  24. ASSERT_TRUE(called.NoBarrier_Load() != NULL);
  25. }
  26. TEST(EnvPosixTest, RunMany) {
  27. port::AtomicPointer last_id (NULL);
  28. struct CB {
  29. port::AtomicPointer* last_id_ptr; // Pointer to shared slot
  30. uintptr_t id; // Order# for the execution of this callback
  31. CB(port::AtomicPointer* p, int i) : last_id_ptr(p), id(i) { }
  32. static void Run(void* v) {
  33. CB* cb = reinterpret_cast<CB*>(v);
  34. void* cur = cb->last_id_ptr->NoBarrier_Load();
  35. ASSERT_EQ(cb->id-1, reinterpret_cast<uintptr_t>(cur));
  36. cb->last_id_ptr->Release_Store(reinterpret_cast<void*>(cb->id));
  37. }
  38. };
  39. // Schedule in different order than start time
  40. CB cb1(&last_id, 1);
  41. CB cb2(&last_id, 2);
  42. CB cb3(&last_id, 3);
  43. CB cb4(&last_id, 4);
  44. env_->Schedule(&CB::Run, &cb1);
  45. env_->Schedule(&CB::Run, &cb2);
  46. env_->Schedule(&CB::Run, &cb3);
  47. env_->Schedule(&CB::Run, &cb4);
  48. Env::Default()->SleepForMicroseconds(kDelayMicros);
  49. void* cur = last_id.Acquire_Load();
  50. ASSERT_EQ(4, reinterpret_cast<uintptr_t>(cur));
  51. }
  52. struct State {
  53. port::Mutex mu;
  54. int val;
  55. int num_running;
  56. };
  57. static void ThreadBody(void* arg) {
  58. State* s = reinterpret_cast<State*>(arg);
  59. s->mu.Lock();
  60. s->val += 1;
  61. s->num_running -= 1;
  62. s->mu.Unlock();
  63. }
  64. TEST(EnvPosixTest, StartThread) {
  65. State state;
  66. state.val = 0;
  67. state.num_running = 3;
  68. for (int i = 0; i < 3; i++) {
  69. env_->StartThread(&ThreadBody, &state);
  70. }
  71. while (true) {
  72. state.mu.Lock();
  73. int num = state.num_running;
  74. state.mu.Unlock();
  75. if (num == 0) {
  76. break;
  77. }
  78. Env::Default()->SleepForMicroseconds(kDelayMicros);
  79. }
  80. ASSERT_EQ(state.val, 3);
  81. }
  82. } // namespace leveldb
  83. int main(int argc, char** argv) {
  84. return leveldb::test::RunAllTests();
  85. }