Home | History | Annotate | Download | only in client
      1 // Copyright (c) 2012 The Chromium 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.
      4 
      5 // This file contains the tests for the FencedAllocator class.
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/memory/aligned_memory.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "gpu/command_buffer/client/cmd_buffer_helper.h"
     12 #include "gpu/command_buffer/client/fenced_allocator.h"
     13 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
     14 #include "gpu/command_buffer/service/command_buffer_service.h"
     15 #include "gpu/command_buffer/service/gpu_scheduler.h"
     16 #include "gpu/command_buffer/service/mocks.h"
     17 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 #if defined(OS_MACOSX)
     21 #include "base/mac/scoped_nsautorelease_pool.h"
     22 #endif
     23 
     24 namespace gpu {
     25 
     26 using testing::Return;
     27 using testing::Mock;
     28 using testing::Truly;
     29 using testing::Sequence;
     30 using testing::DoAll;
     31 using testing::Invoke;
     32 using testing::_;
     33 
     34 class BaseFencedAllocatorTest : public testing::Test {
     35  protected:
     36   static const unsigned int kBufferSize = 1024;
     37   static const int kAllocAlignment = 16;
     38 
     39   virtual void SetUp() {
     40     api_mock_.reset(new AsyncAPIMock);
     41     // ignore noops in the mock - we don't want to inspect the internals of the
     42     // helper.
     43     EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, 0, _))
     44         .WillRepeatedly(Return(error::kNoError));
     45     // Forward the SetToken calls to the engine
     46     EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _))
     47         .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken),
     48                               Return(error::kNoError)));
     49 
     50     {
     51       TransferBufferManager* manager = new TransferBufferManager();
     52       transfer_buffer_manager_.reset(manager);
     53       EXPECT_TRUE(manager->Initialize());
     54     }
     55     command_buffer_.reset(
     56         new CommandBufferService(transfer_buffer_manager_.get()));
     57     EXPECT_TRUE(command_buffer_->Initialize());
     58 
     59     gpu_scheduler_.reset(new GpuScheduler(
     60         command_buffer_.get(), api_mock_.get(), NULL));
     61     command_buffer_->SetPutOffsetChangeCallback(base::Bind(
     62         &GpuScheduler::PutChanged, base::Unretained(gpu_scheduler_.get())));
     63     command_buffer_->SetGetBufferChangeCallback(base::Bind(
     64         &GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler_.get())));
     65 
     66     api_mock_->set_engine(gpu_scheduler_.get());
     67 
     68     helper_.reset(new CommandBufferHelper(command_buffer_.get()));
     69     helper_->Initialize(kBufferSize);
     70   }
     71 
     72   int32 GetToken() {
     73     return command_buffer_->GetState().token;
     74   }
     75 
     76 #if defined(OS_MACOSX)
     77   base::mac::ScopedNSAutoreleasePool autorelease_pool_;
     78 #endif
     79   base::MessageLoop message_loop_;
     80   scoped_ptr<AsyncAPIMock> api_mock_;
     81   scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
     82   scoped_ptr<CommandBufferService> command_buffer_;
     83   scoped_ptr<GpuScheduler> gpu_scheduler_;
     84   scoped_ptr<CommandBufferHelper> helper_;
     85 };
     86 
     87 #ifndef _MSC_VER
     88 const unsigned int BaseFencedAllocatorTest::kBufferSize;
     89 #endif
     90 
     91 // Test fixture for FencedAllocator test - Creates a FencedAllocator, using a
     92 // CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling
     93 // it directly, not through the RPC mechanism), making sure Noops are ignored
     94 // and SetToken are properly forwarded to the engine.
     95 class FencedAllocatorTest : public BaseFencedAllocatorTest {
     96  protected:
     97   virtual void SetUp() {
     98     BaseFencedAllocatorTest::SetUp();
     99     allocator_.reset(new FencedAllocator(kBufferSize, helper_.get()));
    100   }
    101 
    102   virtual void TearDown() {
    103     // If the GpuScheduler posts any tasks, this forces them to run.
    104     base::MessageLoop::current()->RunUntilIdle();
    105 
    106     EXPECT_TRUE(allocator_->CheckConsistency());
    107 
    108     BaseFencedAllocatorTest::TearDown();
    109   }
    110 
    111   scoped_ptr<FencedAllocator> allocator_;
    112 };
    113 
    114 // Checks basic alloc and free.
    115 TEST_F(FencedAllocatorTest, TestBasic) {
    116   allocator_->CheckConsistency();
    117   EXPECT_FALSE(allocator_->InUse());
    118 
    119   const unsigned int kSize = 16;
    120   FencedAllocator::Offset offset = allocator_->Alloc(kSize);
    121   EXPECT_TRUE(allocator_->InUse());
    122   EXPECT_NE(FencedAllocator::kInvalidOffset, offset);
    123   EXPECT_GE(kBufferSize, offset+kSize);
    124   EXPECT_TRUE(allocator_->CheckConsistency());
    125 
    126   allocator_->Free(offset);
    127   EXPECT_FALSE(allocator_->InUse());
    128   EXPECT_TRUE(allocator_->CheckConsistency());
    129 }
    130 
    131 // Test alloc 0 fails.
    132 TEST_F(FencedAllocatorTest, TestAllocZero) {
    133   FencedAllocator::Offset offset = allocator_->Alloc(0);
    134   EXPECT_EQ(FencedAllocator::kInvalidOffset, offset);
    135   EXPECT_FALSE(allocator_->InUse());
    136   EXPECT_TRUE(allocator_->CheckConsistency());
    137 }
    138 
    139 // Checks out-of-memory condition.
    140 TEST_F(FencedAllocatorTest, TestOutOfMemory) {
    141   EXPECT_TRUE(allocator_->CheckConsistency());
    142 
    143   const unsigned int kSize = 16;
    144   const unsigned int kAllocCount = kBufferSize / kSize;
    145   CHECK(kAllocCount * kSize == kBufferSize);
    146 
    147   // Allocate several buffers to fill in the memory.
    148   FencedAllocator::Offset offsets[kAllocCount];
    149   for (unsigned int i = 0; i < kAllocCount; ++i) {
    150     offsets[i] = allocator_->Alloc(kSize);
    151     EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]);
    152     EXPECT_GE(kBufferSize, offsets[i]+kSize);
    153     EXPECT_TRUE(allocator_->CheckConsistency());
    154   }
    155 
    156   // This allocation should fail.
    157   FencedAllocator::Offset offset_failed = allocator_->Alloc(kSize);
    158   EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed);
    159   EXPECT_TRUE(allocator_->CheckConsistency());
    160 
    161   // Free one successful allocation, reallocate with half the size
    162   allocator_->Free(offsets[0]);
    163   EXPECT_TRUE(allocator_->CheckConsistency());
    164   offsets[0] = allocator_->Alloc(kSize/2);
    165   EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[0]);
    166   EXPECT_GE(kBufferSize, offsets[0]+kSize);
    167   EXPECT_TRUE(allocator_->CheckConsistency());
    168 
    169   // This allocation should fail as well.
    170   offset_failed = allocator_->Alloc(kSize);
    171   EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed);
    172   EXPECT_TRUE(allocator_->CheckConsistency());
    173 
    174   // Free up everything.
    175   for (unsigned int i = 0; i < kAllocCount; ++i) {
    176     allocator_->Free(offsets[i]);
    177     EXPECT_TRUE(allocator_->CheckConsistency());
    178   }
    179 }
    180 
    181 // Checks the free-pending-token mechanism.
    182 TEST_F(FencedAllocatorTest, TestFreePendingToken) {
    183   EXPECT_TRUE(allocator_->CheckConsistency());
    184 
    185   const unsigned int kSize = 16;
    186   const unsigned int kAllocCount = kBufferSize / kSize;
    187   CHECK(kAllocCount * kSize == kBufferSize);
    188 
    189   // Allocate several buffers to fill in the memory.
    190   FencedAllocator::Offset offsets[kAllocCount];
    191   for (unsigned int i = 0; i < kAllocCount; ++i) {
    192     offsets[i] = allocator_->Alloc(kSize);
    193     EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]);
    194     EXPECT_GE(kBufferSize, offsets[i]+kSize);
    195     EXPECT_TRUE(allocator_->CheckConsistency());
    196   }
    197 
    198   // This allocation should fail.
    199   FencedAllocator::Offset offset_failed = allocator_->Alloc(kSize);
    200   EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed);
    201   EXPECT_TRUE(allocator_->CheckConsistency());
    202 
    203   // Free one successful allocation, pending fence.
    204   int32 token = helper_.get()->InsertToken();
    205   allocator_->FreePendingToken(offsets[0], token);
    206   EXPECT_TRUE(allocator_->CheckConsistency());
    207 
    208   // The way we hooked up the helper and engine, it won't process commands
    209   // until it has to wait for something. Which means the token shouldn't have
    210   // passed yet at this point.
    211   EXPECT_GT(token, GetToken());
    212 
    213   // This allocation will need to reclaim the space freed above, so that should
    214   // process the commands until the token is passed.
    215   offsets[0] = allocator_->Alloc(kSize);
    216   EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[0]);
    217   EXPECT_GE(kBufferSize, offsets[0]+kSize);
    218   EXPECT_TRUE(allocator_->CheckConsistency());
    219   // Check that the token has indeed passed.
    220   EXPECT_LE(token, GetToken());
    221 
    222   // Free up everything.
    223   for (unsigned int i = 0; i < kAllocCount; ++i) {
    224     allocator_->Free(offsets[i]);
    225     EXPECT_TRUE(allocator_->CheckConsistency());
    226   }
    227 }
    228 
    229 // Checks the free-pending-token mechanism using FreeUnused
    230 TEST_F(FencedAllocatorTest, FreeUnused) {
    231   EXPECT_TRUE(allocator_->CheckConsistency());
    232 
    233   const unsigned int kSize = 16;
    234   const unsigned int kAllocCount = kBufferSize / kSize;
    235   CHECK(kAllocCount * kSize == kBufferSize);
    236 
    237   // Allocate several buffers to fill in the memory.
    238   FencedAllocator::Offset offsets[kAllocCount];
    239   for (unsigned int i = 0; i < kAllocCount; ++i) {
    240     offsets[i] = allocator_->Alloc(kSize);
    241     EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]);
    242     EXPECT_GE(kBufferSize, offsets[i]+kSize);
    243     EXPECT_TRUE(allocator_->CheckConsistency());
    244   }
    245   EXPECT_TRUE(allocator_->InUse());
    246 
    247   // No memory should be available.
    248   EXPECT_EQ(0u, allocator_->GetLargestFreeSize());
    249 
    250   // Free one successful allocation, pending fence.
    251   int32 token = helper_.get()->InsertToken();
    252   allocator_->FreePendingToken(offsets[0], token);
    253   EXPECT_TRUE(allocator_->CheckConsistency());
    254 
    255   // Force the command buffer to process the token.
    256   helper_->Finish();
    257 
    258   // Tell the allocator to update what's available based on the current token.
    259   allocator_->FreeUnused();
    260 
    261   // Check that the new largest free size takes into account the unused block.
    262   EXPECT_EQ(kSize, allocator_->GetLargestFreeSize());
    263 
    264   // Free two more.
    265   token = helper_.get()->InsertToken();
    266   allocator_->FreePendingToken(offsets[1], token);
    267   token = helper_.get()->InsertToken();
    268   allocator_->FreePendingToken(offsets[2], token);
    269   EXPECT_TRUE(allocator_->CheckConsistency());
    270 
    271   // Check that nothing has changed.
    272   EXPECT_EQ(kSize, allocator_->GetLargestFreeSize());
    273 
    274   // Force the command buffer to process the token.
    275   helper_->Finish();
    276 
    277   // Tell the allocator to update what's available based on the current token.
    278   allocator_->FreeUnused();
    279 
    280   // Check that the new largest free size takes into account the unused blocks.
    281   EXPECT_EQ(kSize * 3, allocator_->GetLargestFreeSize());
    282   EXPECT_TRUE(allocator_->InUse());
    283 
    284   // Free up everything.
    285   for (unsigned int i = 3; i < kAllocCount; ++i) {
    286     allocator_->Free(offsets[i]);
    287     EXPECT_TRUE(allocator_->CheckConsistency());
    288   }
    289   EXPECT_FALSE(allocator_->InUse());
    290 }
    291 
    292 // Tests GetLargestFreeSize
    293 TEST_F(FencedAllocatorTest, TestGetLargestFreeSize) {
    294   EXPECT_TRUE(allocator_->CheckConsistency());
    295   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize());
    296 
    297   FencedAllocator::Offset offset = allocator_->Alloc(kBufferSize);
    298   ASSERT_NE(FencedAllocator::kInvalidOffset, offset);
    299   EXPECT_EQ(0u, allocator_->GetLargestFreeSize());
    300   allocator_->Free(offset);
    301   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize());
    302 
    303   const unsigned int kSize = 16;
    304   offset = allocator_->Alloc(kSize);
    305   ASSERT_NE(FencedAllocator::kInvalidOffset, offset);
    306   // The following checks that the buffer is allocated "smartly" - which is
    307   // dependent on the implementation. But both first-fit or best-fit would
    308   // ensure that.
    309   EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeSize());
    310 
    311   // Allocate 2 more buffers (now 3), and then free the first two. This is to
    312   // ensure a hole. Note that this is dependent on the first-fit current
    313   // implementation.
    314   FencedAllocator::Offset offset1 = allocator_->Alloc(kSize);
    315   ASSERT_NE(FencedAllocator::kInvalidOffset, offset1);
    316   FencedAllocator::Offset offset2 = allocator_->Alloc(kSize);
    317   ASSERT_NE(FencedAllocator::kInvalidOffset, offset2);
    318   allocator_->Free(offset);
    319   allocator_->Free(offset1);
    320   EXPECT_EQ(kBufferSize - 3 * kSize, allocator_->GetLargestFreeSize());
    321 
    322   offset = allocator_->Alloc(kBufferSize - 3 * kSize);
    323   ASSERT_NE(FencedAllocator::kInvalidOffset, offset);
    324   EXPECT_EQ(2 * kSize, allocator_->GetLargestFreeSize());
    325 
    326   offset1 = allocator_->Alloc(2 * kSize);
    327   ASSERT_NE(FencedAllocator::kInvalidOffset, offset1);
    328   EXPECT_EQ(0u, allocator_->GetLargestFreeSize());
    329 
    330   allocator_->Free(offset);
    331   allocator_->Free(offset1);
    332   allocator_->Free(offset2);
    333 }
    334 
    335 // Tests GetLargestFreeOrPendingSize
    336 TEST_F(FencedAllocatorTest, TestGetLargestFreeOrPendingSize) {
    337   EXPECT_TRUE(allocator_->CheckConsistency());
    338   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
    339 
    340   FencedAllocator::Offset offset = allocator_->Alloc(kBufferSize);
    341   ASSERT_NE(FencedAllocator::kInvalidOffset, offset);
    342   EXPECT_EQ(0u, allocator_->GetLargestFreeOrPendingSize());
    343   allocator_->Free(offset);
    344   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
    345 
    346   const unsigned int kSize = 16;
    347   offset = allocator_->Alloc(kSize);
    348   ASSERT_NE(FencedAllocator::kInvalidOffset, offset);
    349   // The following checks that the buffer is allocates "smartly" - which is
    350   // dependent on the implementation. But both first-fit or best-fit would
    351   // ensure that.
    352   EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeOrPendingSize());
    353 
    354   // Allocate 2 more buffers (now 3), and then free the first two. This is to
    355   // ensure a hole. Note that this is dependent on the first-fit current
    356   // implementation.
    357   FencedAllocator::Offset offset1 = allocator_->Alloc(kSize);
    358   ASSERT_NE(FencedAllocator::kInvalidOffset, offset1);
    359   FencedAllocator::Offset offset2 = allocator_->Alloc(kSize);
    360   ASSERT_NE(FencedAllocator::kInvalidOffset, offset2);
    361   allocator_->Free(offset);
    362   allocator_->Free(offset1);
    363   EXPECT_EQ(kBufferSize - 3 * kSize,
    364             allocator_->GetLargestFreeOrPendingSize());
    365 
    366   // Free the last one, pending a token.
    367   int32 token = helper_.get()->InsertToken();
    368   allocator_->FreePendingToken(offset2, token);
    369 
    370   // Now all the buffers have been freed...
    371   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
    372   // .. but one is still waiting for the token.
    373   EXPECT_EQ(kBufferSize - 3 * kSize,
    374             allocator_->GetLargestFreeSize());
    375 
    376   // The way we hooked up the helper and engine, it won't process commands
    377   // until it has to wait for something. Which means the token shouldn't have
    378   // passed yet at this point.
    379   EXPECT_GT(token, GetToken());
    380   // This allocation will need to reclaim the space freed above, so that should
    381   // process the commands until the token is passed, but it will succeed.
    382   offset = allocator_->Alloc(kBufferSize);
    383   ASSERT_NE(FencedAllocator::kInvalidOffset, offset);
    384   // Check that the token has indeed passed.
    385   EXPECT_LE(token, GetToken());
    386   allocator_->Free(offset);
    387 
    388   // Everything now has been freed...
    389   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize());
    390   // ... for real.
    391   EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize());
    392 }
    393 
    394 // Test fixture for FencedAllocatorWrapper test - Creates a
    395 // FencedAllocatorWrapper, using a CommandBufferHelper with a mock
    396 // AsyncAPIInterface for its interface (calling it directly, not through the
    397 // RPC mechanism), making sure Noops are ignored and SetToken are properly
    398 // forwarded to the engine.
    399 class FencedAllocatorWrapperTest : public BaseFencedAllocatorTest {
    400  protected:
    401   virtual void SetUp() {
    402     BaseFencedAllocatorTest::SetUp();
    403 
    404     // Though allocating this buffer isn't strictly necessary, it makes
    405     // allocations point to valid addresses, so they could be used for
    406     // something.
    407     buffer_.reset(static_cast<char*>(base::AlignedAlloc(
    408         kBufferSize, kAllocAlignment)));
    409     allocator_.reset(new FencedAllocatorWrapper(kBufferSize, helper_.get(),
    410                                                 buffer_.get()));
    411   }
    412 
    413   virtual void TearDown() {
    414     // If the GpuScheduler posts any tasks, this forces them to run.
    415     base::MessageLoop::current()->RunUntilIdle();
    416 
    417     EXPECT_TRUE(allocator_->CheckConsistency());
    418 
    419     BaseFencedAllocatorTest::TearDown();
    420   }
    421 
    422   scoped_ptr<FencedAllocatorWrapper> allocator_;
    423   scoped_ptr_malloc<char, base::ScopedPtrAlignedFree> buffer_;
    424 };
    425 
    426 // Checks basic alloc and free.
    427 TEST_F(FencedAllocatorWrapperTest, TestBasic) {
    428   allocator_->CheckConsistency();
    429 
    430   const unsigned int kSize = 16;
    431   void *pointer = allocator_->Alloc(kSize);
    432   ASSERT_TRUE(pointer);
    433   EXPECT_LE(buffer_.get(), static_cast<char *>(pointer));
    434   EXPECT_GE(kBufferSize, static_cast<char *>(pointer) - buffer_.get() + kSize);
    435   EXPECT_TRUE(allocator_->CheckConsistency());
    436 
    437   allocator_->Free(pointer);
    438   EXPECT_TRUE(allocator_->CheckConsistency());
    439 
    440   char *pointer_char = allocator_->AllocTyped<char>(kSize);
    441   ASSERT_TRUE(pointer_char);
    442   EXPECT_LE(buffer_.get(), pointer_char);
    443   EXPECT_GE(buffer_.get() + kBufferSize, pointer_char + kSize);
    444   allocator_->Free(pointer_char);
    445   EXPECT_TRUE(allocator_->CheckConsistency());
    446 
    447   unsigned int *pointer_uint = allocator_->AllocTyped<unsigned int>(kSize);
    448   ASSERT_TRUE(pointer_uint);
    449   EXPECT_LE(buffer_.get(), reinterpret_cast<char *>(pointer_uint));
    450   EXPECT_GE(buffer_.get() + kBufferSize,
    451             reinterpret_cast<char *>(pointer_uint + kSize));
    452 
    453   // Check that it did allocate kSize * sizeof(unsigned int). We can't tell
    454   // directly, except from the remaining size.
    455   EXPECT_EQ(kBufferSize - kSize * sizeof(*pointer_uint),
    456             allocator_->GetLargestFreeSize());
    457   allocator_->Free(pointer_uint);
    458 }
    459 
    460 // Test alloc 0 fails.
    461 TEST_F(FencedAllocatorWrapperTest, TestAllocZero) {
    462   allocator_->CheckConsistency();
    463 
    464   void *pointer = allocator_->Alloc(0);
    465   ASSERT_FALSE(pointer);
    466   EXPECT_TRUE(allocator_->CheckConsistency());
    467 }
    468 
    469 // Checks that allocation offsets are aligned to multiples of 16 bytes.
    470 TEST_F(FencedAllocatorWrapperTest, TestAlignment) {
    471   allocator_->CheckConsistency();
    472 
    473   const unsigned int kSize1 = 75;
    474   void *pointer1 = allocator_->Alloc(kSize1);
    475   ASSERT_TRUE(pointer1);
    476   EXPECT_EQ(reinterpret_cast<intptr_t>(pointer1) & (kAllocAlignment - 1), 0);
    477   EXPECT_TRUE(allocator_->CheckConsistency());
    478 
    479   const unsigned int kSize2 = 43;
    480   void *pointer2 = allocator_->Alloc(kSize2);
    481   ASSERT_TRUE(pointer2);
    482   EXPECT_EQ(reinterpret_cast<intptr_t>(pointer2) & (kAllocAlignment - 1), 0);
    483   EXPECT_TRUE(allocator_->CheckConsistency());
    484 
    485   allocator_->Free(pointer2);
    486   EXPECT_TRUE(allocator_->CheckConsistency());
    487 
    488   allocator_->Free(pointer1);
    489   EXPECT_TRUE(allocator_->CheckConsistency());
    490 }
    491 
    492 // Checks out-of-memory condition.
    493 TEST_F(FencedAllocatorWrapperTest, TestOutOfMemory) {
    494   allocator_->CheckConsistency();
    495 
    496   const unsigned int kSize = 16;
    497   const unsigned int kAllocCount = kBufferSize / kSize;
    498   CHECK(kAllocCount * kSize == kBufferSize);
    499 
    500   // Allocate several buffers to fill in the memory.
    501   void *pointers[kAllocCount];
    502   for (unsigned int i = 0; i < kAllocCount; ++i) {
    503     pointers[i] = allocator_->Alloc(kSize);
    504     EXPECT_TRUE(pointers[i]);
    505     EXPECT_TRUE(allocator_->CheckConsistency());
    506   }
    507 
    508   // This allocation should fail.
    509   void *pointer_failed = allocator_->Alloc(kSize);
    510   EXPECT_FALSE(pointer_failed);
    511   EXPECT_TRUE(allocator_->CheckConsistency());
    512 
    513   // Free one successful allocation, reallocate with half the size
    514   allocator_->Free(pointers[0]);
    515   EXPECT_TRUE(allocator_->CheckConsistency());
    516   pointers[0] = allocator_->Alloc(kSize/2);
    517   EXPECT_TRUE(pointers[0]);
    518   EXPECT_TRUE(allocator_->CheckConsistency());
    519 
    520   // This allocation should fail as well.
    521   pointer_failed = allocator_->Alloc(kSize);
    522   EXPECT_FALSE(pointer_failed);
    523   EXPECT_TRUE(allocator_->CheckConsistency());
    524 
    525   // Free up everything.
    526   for (unsigned int i = 0; i < kAllocCount; ++i) {
    527     allocator_->Free(pointers[i]);
    528     EXPECT_TRUE(allocator_->CheckConsistency());
    529   }
    530 }
    531 
    532 // Checks the free-pending-token mechanism.
    533 TEST_F(FencedAllocatorWrapperTest, TestFreePendingToken) {
    534   allocator_->CheckConsistency();
    535 
    536   const unsigned int kSize = 16;
    537   const unsigned int kAllocCount = kBufferSize / kSize;
    538   CHECK(kAllocCount * kSize == kBufferSize);
    539 
    540   // Allocate several buffers to fill in the memory.
    541   void *pointers[kAllocCount];
    542   for (unsigned int i = 0; i < kAllocCount; ++i) {
    543     pointers[i] = allocator_->Alloc(kSize);
    544     EXPECT_TRUE(pointers[i]);
    545     EXPECT_TRUE(allocator_->CheckConsistency());
    546   }
    547 
    548   // This allocation should fail.
    549   void *pointer_failed = allocator_->Alloc(kSize);
    550   EXPECT_FALSE(pointer_failed);
    551   EXPECT_TRUE(allocator_->CheckConsistency());
    552 
    553   // Free one successful allocation, pending fence.
    554   int32 token = helper_.get()->InsertToken();
    555   allocator_->FreePendingToken(pointers[0], token);
    556   EXPECT_TRUE(allocator_->CheckConsistency());
    557 
    558   // The way we hooked up the helper and engine, it won't process commands
    559   // until it has to wait for something. Which means the token shouldn't have
    560   // passed yet at this point.
    561   EXPECT_GT(token, GetToken());
    562 
    563   // This allocation will need to reclaim the space freed above, so that should
    564   // process the commands until the token is passed.
    565   pointers[0] = allocator_->Alloc(kSize);
    566   EXPECT_TRUE(pointers[0]);
    567   EXPECT_TRUE(allocator_->CheckConsistency());
    568   // Check that the token has indeed passed.
    569   EXPECT_LE(token, GetToken());
    570 
    571   // Free up everything.
    572   for (unsigned int i = 0; i < kAllocCount; ++i) {
    573     allocator_->Free(pointers[i]);
    574     EXPECT_TRUE(allocator_->CheckConsistency());
    575   }
    576 }
    577 
    578 }  // namespace gpu
    579