return true;
}
-/*
- * Allocate N continuous bits in a zone starting from
- * marker provided in iter.
- */
-int64_t BitMapZone::alloc_cont_bits(int64_t num_blocks,
- BitMapEntityIter<BmapEntry> *iter,
- int64_t *scanned)
-{
- BmapEntry *bmap = NULL;
- int64_t required = num_blocks;
- alloc_assert(check_locked());
- while ((bmap = (BmapEntry *) iter->next())) {
- int64_t found = 0;
- int64_t max_expected = MIN(required, BmapEntry::size());
- found = bmap->find_n_cont_bits(0, max_expected);
-
- required -= found;
-
- if (found < max_expected) {
- break;
- }
- }
-
- /*
- * scanned == allocated
- */
- *scanned = num_blocks - required;
- return (num_blocks - required);
-}
-
void BitMapZone::set_blocks_used(int64_t start_block, int64_t num_blocks)
{
BmapEntry *bmap = NULL;
return !lock_excl_try();
}
-/*
- * Try find N contiguous blocks in a Zone.
- * Nothing less than N is good and considered failure.
- *
- * Caller must take exclusive lock on Zone.
- */
-int64_t BitMapZone::alloc_blocks(int64_t num_blocks, int64_t hint, int64_t *start_block)
-{
- int64_t bmap_idx = hint / BmapEntry::size();
- int bit_idx = hint % BmapEntry::size();
- BmapEntry *bmap = NULL;
- int64_t allocated = 0;
-
- alloc_assert(check_locked());
-
- BitMapEntityIter <BmapEntry> iter = BitMapEntityIter<BmapEntry>(
- m_bmap_list, bmap_idx);
-
- while ((bmap = (BmapEntry *) iter.next())) {
- int64_t scanned = 0;
- int start_offset = -1;
-
- allocated = bmap->find_first_set_bits(num_blocks,
- bit_idx, &start_offset, &scanned);
-
- bit_idx = 0;
-
- if (allocated > 0) {
- (*start_block) = start_offset +
- (iter.index() - 1) * bmap->size();
-
- allocated += alloc_cont_bits(num_blocks - allocated,
- &iter, &scanned);
- /*
- * Iter need to go one step back for case when allocation
- * is not enough and start from last bitmap again.
- */
- iter.decr_idx();
- bit_idx = scanned % BmapEntry::size();
- }
-
- if (allocated < num_blocks) {
- free_blocks_int(*start_block, allocated);
- allocated = 0;
- *start_block = 0;
- } else {
- /*
- * Got required.
- */
- break;
- }
- }
-
- add_used_blocks(allocated);
- return allocated;
-}
-
void BitMapZone::free_blocks(int64_t start_block, int64_t num_blocks)
{
free_blocks_int(start_block, num_blocks);
alloc_assert(get_used_blocks() >= 0);
}
-/*
- * Allocate N blocks, dis-contiguous are fine
- */
-#if 0
-int64_t BitMapZone::alloc_blocks_dis(int64_t num_blocks,
- int64_t hint,
- int64_t zone_blk_off,
- ExtentList *alloc_blocks)
-{
- int64_t bmap_idx = hint / BmapEntry::size();
- int bit = hint % BmapEntry::size();
- BmapEntry *bmap = NULL;
- int64_t allocated = 0;
- int64_t blk_off = 0;
-
- alloc_assert(check_locked());
-
- BitMapEntityIter <BmapEntry> iter = BitMapEntityIter<BmapEntry>(
- m_bmap_list, bmap_idx);
- while ((bmap = (BmapEntry *) iter.next())) {
- int64_t scanned = 0;
- blk_off = (iter.index() - 1) * BmapEntry::size() + zone_blk_off;
- allocated += bmap->find_any_free_bits(bit, num_blocks - allocated,
- alloc_blocks, blk_off, &scanned);
-
- if (allocated == num_blocks) {
- break;
- }
- bit = 0;
- }
-
- add_used_blocks(allocated);
-
- return allocated;
-}
-#endif
-
int64_t BitMapZone::alloc_blocks_dis(int64_t num_blocks,
int64_t min_alloc,
int64_t hint,
return true;
}
-int64_t BitMapAreaIN::alloc_blocks_int_work(bool wait, bool wrap, int64_t num_blocks,
- int64_t hint, int64_t *start_block)
-{
- BitMapArea *child = NULL;
- int64_t allocated = 0;
-
- *start_block = 0;
- BmapEntityListIter iter = BmapEntityListIter(
- m_child_list, hint / m_child_size_blocks, wrap);
-
- while ((child = (BitMapArea *) iter.next())) {
- if (!child_check_n_lock(child, num_blocks - allocated)) {
- hint = 0;
- continue;
- }
-
- allocated = child->alloc_blocks(wait, num_blocks, hint % m_child_size_blocks, start_block);
- child_unlock(child);
- if (allocated == num_blocks) {
- (*start_block) += child->get_index() * m_child_size_blocks;
- break;
- }
-
- child->free_blocks(*start_block, allocated);
- hint = 0;
- *start_block = 0;
- allocated = 0;
- }
- return allocated;
-}
-
-int64_t BitMapAreaIN::alloc_blocks_int(bool wait, int64_t num_blocks,
- int64_t hint, int64_t *start_block)
-{
- return alloc_blocks_int_work(wait, false, num_blocks, hint, start_block);
-}
-
-int64_t BitMapAreaIN::alloc_blocks(bool wait, int64_t num_blocks, int64_t hint,
- int64_t *start_block)
-{
- int64_t allocated = 0;
-
- lock_shared();
-
- if (!reserve_blocks(num_blocks)) {
- goto exit;
- }
-
- allocated = alloc_blocks_int(wait, num_blocks, hint, start_block);
-
- unreserve(num_blocks, allocated);
- alloc_assert((get_used_blocks() <= m_total_blocks));
- alloc_dbg_assert(is_allocated(*start_block, allocated));
-
-exit:
- unlock();
- return allocated;
-}
-
int64_t BitMapAreaIN::alloc_blocks_dis_int_work(bool wait, bool wrap, int64_t num_blocks, int64_t min_alloc,
int64_t hint, int64_t area_blk_off, ExtentList *block_list)
{
child->unlock();
}
-int64_t BitMapAreaLeaf::alloc_blocks_int(bool wait, int64_t num_blocks,
- int64_t hint, int64_t *start_block)
-{
- BitMapArea *child = NULL;
- int64_t allocated = 0;
-
- *start_block = 0;
-
- BmapEntityListIter iter = BmapEntityListIter(
- m_child_list, hint / m_child_size_blocks, false);
-
- while ((child = iter.next())) {
- if (!child_check_n_lock(child, num_blocks - allocated, false)) {
- hint = 0;
- continue;
- }
- alloc_assert(child->get_type() == ZONE);
-
- allocated = child->alloc_blocks(num_blocks, hint % m_child_size_blocks, start_block);
- child_unlock(child);
- if (allocated == num_blocks) {
- (*start_block) += child->get_index() * m_child_size_blocks;
- break;
- }
-
- child->free_blocks(*start_block, allocated);
- hint = 0;
- *start_block = 0;
- allocated = 0;
- }
- return allocated;
-}
-
int64_t BitMapAreaLeaf::alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t min_alloc,
int64_t hint, int64_t area_blk_off, ExtentList *block_list)
{
return true;
}
-int64_t BitAllocator::alloc_blocks_int(bool wait, int64_t num_blocks,
- int64_t hint, int64_t *start_block)
-{
- return alloc_blocks_int_work(wait, true, num_blocks, hint, start_block);
-}
-
-/*
- * Interface to allocate blocks after reserve.
- */
-int64_t BitAllocator::alloc_blocks_res(int64_t num_blocks, int64_t hint, int64_t *start_block)
-{
- int scans = 1;
- int64_t allocated = 0;
-
- *start_block = 0;
- if (!check_input(num_blocks)) {
- return 0;
- }
-
- lock_shared();
- serial_lock();
-
- if (is_stats_on()) {
- m_stats->add_concurrent_scans(scans);
- }
-
- while (scans && !allocated) {
- allocated = alloc_blocks_int(false, num_blocks, hint, start_block);
- scans--;
- }
-
- if (!allocated) {
- /*
- * Could not find anything in concurrent scan.
- * Go in serial manner.
- */
- serial_unlock();
- unlock();
- lock_excl();
- serial_lock();
- allocated = alloc_blocks_int(false, num_blocks, hint, start_block);
- if (is_stats_on()) {
- m_stats->add_serial_scans(1);
- }
- }
-
- alloc_dbg_assert(is_allocated(*start_block, allocated));
- unreserve(num_blocks, allocated);
-
- serial_unlock();
- unlock();
-
- return allocated;
-}
-
-int64_t BitAllocator::alloc_blocks(int64_t num_blocks, int64_t hint, int64_t *start_block)
-{
- int scans = 1;
- int64_t allocated = 0;
-
- *start_block = 0;
- if (!check_input(num_blocks)) {
- ceph_abort();
- return 0;
- }
-
- lock_shared();
- serial_lock();
-
- if (!reserve_blocks(num_blocks)) {
- goto exit;
- }
-
- if (is_stats_on()) {
- m_stats->add_alloc_calls(1);
- m_stats->add_allocated(num_blocks);
- }
-
- if (is_stats_on()) {
- m_stats->add_concurrent_scans(scans);
- }
-
- while (scans && !allocated) {
- allocated = alloc_blocks_int(false, num_blocks, hint, start_block);
- scans--;
- }
-
- if (!allocated) {
- /*
- * Could not find anything in concurrent scan.
- * Go in serial manner.
- */
- serial_unlock();
- unlock();
- lock_excl();
- serial_lock();
- allocated = alloc_blocks_int(false, num_blocks, hint, start_block);
- if (!allocated) {
- allocated = alloc_blocks_int(false, num_blocks, hint, start_block);
- alloc_assert(allocated);
- }
- if (is_stats_on()) {
- m_stats->add_serial_scans(1);
- }
- }
-
- unreserve(num_blocks, allocated);
- alloc_assert((get_used_blocks() <= m_total_blocks));
- alloc_dbg_assert(is_allocated(*start_block, allocated));
-
-exit:
- serial_unlock();
- unlock();
-
- return allocated;
-}
-
void BitAllocator::free_blocks(int64_t start_block, int64_t num_blocks)
{
if (num_blocks == 0) {
area_blk_off, block_list);
}
-int64_t BitAllocator::alloc_blocks_dis(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list)
-{
- return alloc_blocks_dis_work(num_blocks, min_alloc, hint, block_list, false);
-}
-
int64_t BitAllocator::alloc_blocks_dis_res(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list)
{
return alloc_blocks_dis_work(num_blocks, min_alloc, hint, block_list, true);
virtual int64_t get_used_blocks() = 0;
virtual void shutdown() = 0;
- virtual int64_t alloc_blocks(bool wait, int64_t num_blocks,
- int64_t hint, int64_t *start_block) {
- ceph_abort();
- return 0;
- }
- virtual int64_t alloc_blocks(int64_t num_blocks, int64_t hint, int64_t *start_block) {
- ceph_abort();
- return 0;
- }
virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks, int64_t min_alloc,
int64_t hint, int64_t blk_off, ExtentList *block_list) {
void unlock();
bool check_locked();
- int64_t alloc_cont_bits(int64_t num_blocks,
- BitMapEntityIter<BmapEntry> *iter, int64_t *bmap_out_idx);
void free_blocks_int(int64_t start_block, int64_t num_blocks);
void init(int64_t zone_num, int64_t total_blocks, bool def);
~BitMapZone();
void shutdown();
- virtual int64_t alloc_blocks(bool wait, int64_t num_blocks,
- int64_t hint, int64_t *start_block) {
- ceph_abort();
- return 0;
- }
-
virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks, int64_t min_alloc,
int64_t hint, int64_t blk_off, int64_t *block_list) {
ceph_abort();
return 0;
}
-
- int64_t alloc_blocks(int64_t num_blocks, int64_t hint, int64_t *start_block);
- using BitMapArea::alloc_blocks_dis;
int64_t alloc_blocks_dis(int64_t num_blocks, int64_t min_alloc, int64_t hint,
int64_t blk_off, ExtentList *block_list);
void set_blocks_used(int64_t start_block, int64_t num_blocks);
void init(int64_t total_blocks, int64_t zone_size_block, bool def);
void init_common(int64_t total_blocks, int64_t zone_size_block, bool def);
-
- int64_t alloc_blocks_int_work(bool wait, bool wrap,
- int64_t num_blocks, int64_t hint, int64_t *start_block);
int64_t alloc_blocks_dis_int_work(bool wait, bool wrap, int64_t num_blocks, int64_t min_alloc, int64_t hint,
int64_t blk_off, ExtentList *block_list);
virtual int64_t size() {
return m_total_blocks;
}
-
- virtual int64_t alloc_blocks_int(bool wait, int64_t num_blocks,
- int64_t hint, int64_t *start_block);
- using BitMapArea::alloc_blocks; //non-wait version
using BitMapArea::alloc_blocks_dis; //non-wait version
- virtual int64_t alloc_blocks(bool wait, int64_t num_blocks, int64_t hint, int64_t *start_block);
+
virtual int64_t alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t min_alloc, int64_t hint,
int64_t blk_off, ExtentList *block_list);
virtual int64_t alloc_blocks_dis(bool wait, int64_t num_blocks, int64_t min_alloc, int64_t hint,
void init_check(int64_t total_blocks, int64_t zone_size_block,
bmap_alloc_mode_t mode, bool def, bool stats_on);
int64_t alloc_blocks_dis_work(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list, bool reserved);
- int64_t alloc_blocks_int(bool wait, int64_t num_blocks, int64_t hint, int64_t *start_block);
int64_t alloc_blocks_dis_int(bool wait, int64_t num_blocks, int64_t min_alloc,
int64_t hint, int64_t area_blk_off, ExtentList *block_list);
bmap_alloc_mode_t mode, bool def, bool stats_on);
~BitAllocator();
void shutdown();
- using BitMapAreaIN::alloc_blocks; //Wait version
using BitMapAreaIN::alloc_blocks_dis; //Wait version
- int64_t alloc_blocks(int64_t num_blocks, int64_t hint, int64_t *start_block);
- int64_t alloc_blocks_res(int64_t num_blocks, int64_t hint, int64_t *start_block);
void free_blocks(int64_t start_block, int64_t num_blocks);
void set_blocks_used(int64_t start_block, int64_t num_blocks);
void unreserve_blocks(int64_t blocks);
- int64_t alloc_blocks_dis(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list);
int64_t alloc_blocks_dis_res(int64_t num_blocks, int64_t min_alloc, int64_t hint, ExtentList *block_list);
void free_blocks_dis(int64_t num_blocks, ExtentList *block_list);
{
int64_t block_size = 1024;
int64_t blocks = BitMapZone::get_total_blocks() * 2 * block_size;
- uint64_t offset = 0;
- uint32_t length = 0;
int count = 0;
+ uint64_t alloc_len = 0;
- init_alloc(blocks, block_size);
- alloc->init_add_free(block_size, block_size);
- EXPECT_EQ(alloc->reserve(block_size), 0);
- EXPECT_EQ(alloc->allocate(block_size, block_size, 0, &offset, &length), 0);
+ {
+ init_alloc(blocks, block_size);
+ alloc->init_add_free(block_size, block_size);
+ EXPECT_EQ(alloc->reserve(block_size), 0);
+ AllocExtentVector extents = AllocExtentVector
+ (1, AllocExtent(0, 0));
+ EXPECT_EQ(alloc->alloc_extents(block_size, block_size,
+ 0, (int64_t) 0, &extents, &count, &alloc_len), 0);
+ EXPECT_EQ(alloc_len, (uint64_t) block_size);
+ }
/*
* Allocate extent and make sure all comes in single extent.
(4, AllocExtent(0, 0));
EXPECT_EQ(alloc->alloc_extents(4 * (uint64_t)block_size, (uint64_t) block_size,
- 0, (int64_t) 0, &extents, &count), 0);
+ 0, (int64_t) 0, &extents, &count, &alloc_len), 0);
+ EXPECT_EQ(alloc_len, 4 * (uint64_t) block_size);
EXPECT_EQ(extents[0].length, 4 * block_size);
EXPECT_EQ(0U, extents[1].length);
EXPECT_EQ(count, 1);
(4, AllocExtent(0, 0));
EXPECT_EQ(alloc->alloc_extents(4 * (uint64_t)block_size, (uint64_t) block_size,
- 0, (int64_t) 0, &extents, &count), 0);
+ 0, (int64_t) 0, &extents, &count, &alloc_len), 0);
+ EXPECT_EQ(alloc_len, 4 * (uint64_t) block_size);
EXPECT_EQ(extents[0].length, 2 * block_size);
EXPECT_EQ(extents[1].length, 2 * block_size);
EXPECT_EQ(0U, extents[2].length);
int64_t block_size = 1024;
int64_t blocks = BitMapZone::get_total_blocks() * 2 * block_size;
int count = 0;
+ uint64_t alloc_len = 0;
init_alloc(blocks, block_size);
(4, AllocExtent(0, 0));
EXPECT_EQ(alloc->alloc_extents(4 * (uint64_t)block_size, (uint64_t) block_size,
- block_size, (int64_t) 0, &extents, &count), 0);
+ block_size, (int64_t) 0, &extents, &count, &alloc_len), 0);
+ EXPECT_EQ(alloc_len, 4 * (uint64_t) block_size);
for (int i = 0; i < 4; i++) {
EXPECT_EQ(extents[i].length, block_size);
}
(2, AllocExtent(0, 0));
EXPECT_EQ(alloc->alloc_extents(4 * (uint64_t)block_size, (uint64_t) block_size,
- 2 * block_size, (int64_t) 0, &extents, &count), 0);
+ 2 * block_size, (int64_t) 0, &extents, &count, &alloc_len), 0);
+ EXPECT_EQ(alloc_len, 4 * (uint64_t) block_size);
for (int i = 0; i < 2; i++) {
EXPECT_EQ(extents[i].length, block_size * 2);
}
(1024, AllocExtent(0, 0));
EXPECT_EQ(alloc->alloc_extents(1024 * (uint64_t)block_size, (uint64_t) block_size * 4,
- block_size * 4, (int64_t) 0, &extents, &count), 0);
+ block_size * 4, (int64_t) 0, &extents, &count, &alloc_len), 0);
+ EXPECT_EQ(alloc_len, 1024 * (uint64_t) block_size);
for (int i = 0; i < count; i++) {
EXPECT_EQ(extents[i].length, block_size * 4);
}
(8, AllocExtent(0, 0));
EXPECT_EQ(alloc->alloc_extents(16 * (uint64_t)block_size, (uint64_t) block_size,
- 2 * block_size, (int64_t) 0, &extents, &count), 0);
+ 2 * block_size, (int64_t) 0, &extents, &count, &alloc_len), 0);
EXPECT_EQ(count, 8);
+ EXPECT_EQ(alloc_len, 16 * (uint64_t) block_size);
for (int i = 0; i < 8; i++) {
EXPECT_EQ(extents[i].length, 2 * block_size);
}
int64_t block_size = 1024;
int64_t blocks = BitMapZone::get_total_blocks() * block_size;
int count = 0;
+ uint64_t alloc_len = 0;
init_alloc(blocks, block_size);
{
(4, AllocExtent(0, 0));
EXPECT_EQ(alloc->alloc_extents(512 * (uint64_t)block_size, (uint64_t) block_size * 256,
- block_size * 256, (int64_t) 0, &extents, &count), 0);
+ block_size * 256, (int64_t) 0, &extents, &count, &alloc_len), 0);
+ EXPECT_EQ(512 * (uint64_t)block_size, alloc_len);
alloc->init_add_free(0, block_size * 256);
alloc->init_add_free(block_size * 512, block_size * 256);
EXPECT_EQ(alloc->reserve(block_size * 512), 0);
EXPECT_EQ(alloc->alloc_extents(512 * (uint64_t)block_size, (uint64_t) block_size * 512,
- block_size * 512, (int64_t) 0, &extents, &count), -ENOSPC);
+ block_size * 512, (int64_t) 0, &extents, &count, &alloc_len), -ENOSPC);
+ EXPECT_EQ(alloc_len, (uint64_t) 0);
}
}
int count = 0;
int64_t allocated = 0;
int64_t zone_size = 1024;
+ uint64_t alloc_len = 0;
g_conf->set_val("bluestore_bitmapallocator_blocks_per_zone", std::to_string(zone_size));
init_alloc(blocks, 1);
(zone_size * 4, AllocExtent(-1, -1));
alloc->reserve(blocks);
- allocated = alloc->alloc_extents(1, 1, 1, zone_size, &extents, &count);
+ allocated = alloc->alloc_extents(1, 1, 1, zone_size, &extents, &count, &alloc_len);
ASSERT_EQ(0, allocated);
+ ASSERT_EQ((uint64_t) 1, alloc_len);
ASSERT_EQ(1, count);
ASSERT_EQ(extents[0].offset, (uint64_t) zone_size);
- allocated = alloc->alloc_extents(1, 1, 1, zone_size * 2 - 1, &extents, &count);
+ allocated = alloc->alloc_extents(1, 1, 1, zone_size * 2 - 1, &extents, &count, &alloc_len);
+ ASSERT_EQ((uint64_t) 1, alloc_len);
EXPECT_EQ(0, allocated);
ASSERT_EQ(1, count);
EXPECT_EQ((int64_t) extents[0].offset, zone_size * 2 - 1);
/*
* Wrap around with hint
*/
- allocated = alloc->alloc_extents(zone_size * 2, 1, 1, blocks - zone_size * 2, &extents, &count);
+ allocated = alloc->alloc_extents(zone_size * 2, 1, 1, blocks - zone_size * 2, &extents, &count, &alloc_len);
EXPECT_EQ(0, allocated);
+ ASSERT_EQ((uint64_t) zone_size * 2, alloc_len);
EXPECT_EQ(zone_size * 2, count);
EXPECT_EQ((int64_t)extents[0].offset, blocks - zone_size * 2);
- allocated = alloc->alloc_extents(zone_size, 1, 1, blocks - zone_size, &extents, &count);
+ allocated = alloc->alloc_extents(zone_size, 1, 1, blocks - zone_size, &extents, &count, &alloc_len);
EXPECT_EQ(0, allocated);
+ ASSERT_EQ((uint64_t) zone_size, alloc_len);
EXPECT_EQ(zone_size, count);
EXPECT_EQ(extents[0].offset, (uint64_t) 0);
}
TEST(BitAllocator, test_zone_alloc)
{
int total_blocks = 1024;
- int64_t blks = 1;
- int64_t last_blk = -1;
- int64_t start_blk = 0;
int64_t allocated = 0;
BitMapZone *zone = new BitMapZone(total_blocks, 0);
bool lock = zone->lock_excl_try();
bmap_test_assert(lock);
- for (int i = 0; i < total_blocks; i++) {
- allocated = zone->alloc_blocks(blks, 0, &start_blk);
- bmap_test_assert(last_blk + 1 == start_blk);
- bmap_test_assert(allocated == blks);
- last_blk = start_blk;
- }
- bmap_test_assert(zone->get_used_blocks() == total_blocks);
-
- for (int i = 0; i < total_blocks; i++) {
- bmap_test_assert(zone->get_used_blocks() == total_blocks - i);
- zone->free_blocks(i, blks);
- }
-
- blks = 2;
- last_blk = -2;
- for (int i = 0; i < total_blocks/2; i++) {
- allocated = zone->alloc_blocks(blks, 0, &start_blk);
- bmap_test_assert(last_blk + 2 == start_blk);
- last_blk = start_blk;
- }
-
- // Free different boundaries and allocate those
- blks = 3;
- bmap_test_assert(zone->is_exhausted());
- zone->free_blocks(BmapEntry::size() - blks, blks);
- zone->free_blocks(BmapEntry::size(), blks);
-
- allocated = zone->alloc_blocks(blks * 2, 0, &start_blk);
- bmap_test_assert(BmapEntry::size() - blks == start_blk);
- bmap_test_assert(allocated == blks * 2);
-
- blks = 4;
- zone->free_blocks(BmapEntry::size() * 2 - blks, 2 * blks);
- allocated = zone->alloc_blocks(2 * blks, 0, &start_blk);
- bmap_test_assert(BmapEntry::size() * 2 - blks == start_blk);
- bmap_test_assert(allocated == blks * 2);
-
- blks = BmapEntry::size() * 2;
- zone->free_blocks(BmapEntry::size() * 6 - blks, blks);
- allocated = zone->alloc_blocks(blks, 0, &start_blk);
- bmap_test_assert(BmapEntry::size() * 6 - blks == start_blk);
-
- // free blocks at distance 1, 2 up to 63 and allocate all of them
- // together using disc alloc.
- blks = BmapEntry::size() * 2;
- int num_bits = 1;
- for (int i = 0; i < zone->size() / BmapEntry::size() -1; i++) {
- zone->free_blocks(i * BmapEntry::size(), num_bits);
- num_bits++;
- }
-
- num_bits = 1;
- int64_t start_block = 0;
- for (int i = 0; i < zone->size() / BmapEntry::size() -1; i++) {
- allocated = zone->alloc_blocks(num_bits, 0, &start_block);
- bmap_test_assert(num_bits == allocated);
- bmap_test_assert(start_block == i * BmapEntry::size());
- num_bits++;
- }
-
- start_block = 0;
- num_bits = 1;
- for (int i = 0; i < zone->size() / BmapEntry::size() -1; i++) {
- zone->free_blocks(i * BmapEntry::size(), num_bits);
- num_bits++;
- }
-
- delete zone;
- // non-conti allocations test
- zone = new BitMapZone(total_blocks, 0);
- lock = zone->lock_excl_try();
- bmap_test_assert(lock);
- for (int i = 0; i < zone->size(); i++) {
- allocated = zone->alloc_blocks(1, 0, &start_block);
- bmap_test_assert(allocated == 1);
- }
- for (int i = 0; i < zone->size(); i += 2) {
- zone->free_blocks(i, 1);
- }
-
int64_t blk_size = 1024;
AllocExtentVector extents = AllocExtentVector
(zone->size() / 2, AllocExtent(-1, -1));
allocated = zone->alloc_blocks_dis(zone->size() / 2, 1, 0, 0, block_list);
bmap_test_assert(allocated == zone->size() / 2);
- {
- zone = new BitMapZone(total_blocks, 0);
- lock = zone->lock_excl_try();
- bmap_test_assert(lock);
- for (int i = 0; i < zone->size(); i += 4) {
- allocated = zone->alloc_blocks(1, i, &start_block);
- bmap_test_assert(allocated == 1);
- bmap_test_assert(start_block == i);
- }
-
- for (int i = 0; i < zone->size(); i += 4) {
- zone->free_blocks(i, 1);
- }
- }
{
int64_t blk_size = 1024;
TEST(BitAllocator, test_bmap_alloc)
{
- const int max_iter = 2;
+// const int max_iter = 2;
for (int round = 0; round < 3; round++) {
// Test zone of different sizes: 512, 1024, 2048
int64_t total_blocks = zone_size * 4;
int64_t allocated = 0;
- int64_t start_block = 0;
+ //int64_t start_block = 0;
BitAllocator *alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT);
- for (int64_t iter = 0; iter < max_iter; iter++) {
- for (int64_t i = 0; i < total_blocks; i++) {
- alloc_assert(alloc->reserve_blocks(1));
- allocated = alloc->alloc_blocks_res(1, 0, &start_block);
- bmap_test_assert(allocated == 1);
- bmap_test_assert(start_block == i);
- }
-
- for (int64_t i = 0; i < total_blocks; i++) {
- alloc->free_blocks(i, 1);
- }
- }
-
- for (int64_t iter = 0; iter < max_iter; iter++) {
- for (int64_t i = 0; i < total_blocks / zone_size; i++) {
- alloc_assert(alloc->reserve_blocks(zone_size));
- allocated = alloc->alloc_blocks_res(zone_size, 0, &start_block);
- bmap_test_assert(allocated == zone_size);
- bmap_test_assert(start_block == i * zone_size);
- }
-
- for (int64_t i = 0; i < total_blocks / zone_size; i++) {
- alloc->free_blocks(i * zone_size, zone_size);
- }
- }
-
- allocated = alloc->alloc_blocks(1, 0, &start_block);
- bmap_test_assert(allocated == 1);
-
- allocated = alloc->alloc_blocks(zone_size - 1, 0, &start_block);
- bmap_test_assert(allocated == zone_size - 1);
- bmap_test_assert(start_block == 1);
-
- allocated = alloc->alloc_blocks(1, 0, &start_block);
- bmap_test_assert(allocated == 1);
-
- allocated = alloc->alloc_blocks(zone_size, 0, &start_block);
- bmap_test_assert(allocated == zone_size);
- bmap_test_assert(start_block == zone_size * 2);
-
- // Dis contiguous blocks allocations
- delete alloc;
- alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT);
-
- for (int64_t i = 0; i < alloc->size(); i++) {
- allocated = alloc->alloc_blocks(1, 0, &start_block);
- bmap_test_assert(allocated == 1);
- }
- for (int i = 0; i < alloc->size(); i += 2) {
- alloc->free_blocks(i, 1);
- }
-
int64_t blk_size = 1024;
auto extents = AllocExtentVector
(alloc->size(), AllocExtent(-1, -1));
ExtentList *block_list = new ExtentList(&extents, blk_size);
-
- allocated = alloc->alloc_blocks_dis(alloc->size()/2, 1, 0, block_list);
+
+ ASSERT_EQ(alloc->reserve_blocks(alloc->size() / 2), true);
+ allocated = alloc->alloc_blocks_dis_res(alloc->size()/2, 1, 0, block_list);
ASSERT_EQ(alloc->size()/2, allocated);
block_list->reset();
- allocated = alloc->alloc_blocks_dis(1, 1, 0, block_list);
- bmap_test_assert(allocated == 0);
+ ASSERT_EQ(alloc->reserve_blocks(1), true);
+ allocated = alloc->alloc_blocks_dis_res(1, 1, 0, block_list);
+ bmap_test_assert(allocated == 1);
alloc->free_blocks(alloc->size()/2, 1);
block_list->reset();
- allocated = alloc->alloc_blocks_dis(1, 1, 0, block_list);
+ ASSERT_EQ(alloc->reserve_blocks(1), true);
+ allocated = alloc->alloc_blocks_dis_res(1, 1, 0, block_list);
bmap_test_assert(allocated == 1);
bmap_test_assert((int64_t) extents[0].offset == alloc->size()/2 * blk_size);
delete block_list;
delete alloc;
- // unaligned zones
- total_blocks = zone_size * 2 + 11;
- alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT);
-
- for (int64_t iter = 0; iter < max_iter; iter++) {
- for (int64_t i = 0; i < total_blocks; i++) {
- allocated = alloc->alloc_blocks(1, 0, &start_block);
- bmap_test_assert(allocated == 1);
- bmap_test_assert(start_block == i);
- }
-
- for (int64_t i = 0; i < total_blocks; i++) {
- alloc->free_blocks(i, 1);
- }
- }
- delete alloc;
-
- // Make three > 3 levels tree and check allocations and dealloc
- // in a loop
- int64_t alloc_size = 64ull << round;
- total_blocks = BitMapArea::get_level_factor(2) * 4;
- alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT, false);
- for (int64_t iter = 0; iter < max_iter; iter++) {
- for (int64_t i = 0; i < total_blocks / alloc_size; i++) {
- allocated = alloc->alloc_blocks(alloc_size, 0, &start_block);
- bmap_test_assert(allocated == alloc_size);
- bmap_test_assert(start_block == i * alloc_size);
- }
-
- for (int64_t i = 0; i < total_blocks / alloc_size; i++) {
- alloc->free_blocks(i * alloc_size, alloc_size);
- }
- }
-
- delete alloc;
- alloc = new BitAllocator(1024, zone_size, CONCURRENT, true);
-
- alloc->free_blocks(1, 1023);
- allocated = alloc->alloc_blocks(16, 0, &start_block);
- bmap_test_assert(allocated == 16);
- bmap_test_assert(start_block == 1);
- delete alloc;
-
- total_blocks = BitMapArea::get_level_factor(2) * 4;
- alloc_size = 64ull << round;
- alloc = new BitAllocator(total_blocks, zone_size, CONCURRENT, false);
- for (int64_t iter = 0; iter < max_iter; iter++) {
- for (int64_t i = 0; i < total_blocks / alloc_size; i++) {
- bmap_test_assert(alloc->reserve_blocks(alloc_size));
- allocated = alloc->alloc_blocks_res(alloc_size, 0, &start_block);
- bmap_test_assert(allocated == alloc_size);
- bmap_test_assert(start_block == i * alloc_size);
- }
-
- for (int64_t i = 0; i < total_blocks / alloc_size; i++) {
- alloc->free_blocks(i * alloc_size, alloc_size);
- }
- }
-
}
// restore to typical value
ExtentList *block_list = new ExtentList(&extents, blk_size, max_alloc);
- allocated = alloc->alloc_blocks_dis(total_alloc, blk_size, 0, block_list);
+ EXPECT_EQ(alloc->reserve_blocks(total_alloc), true);
+ allocated = alloc->alloc_blocks_dis_res(total_alloc, blk_size, 0, block_list);
EXPECT_EQ(allocated, total_alloc);
max_alloc = total_alloc > max_alloc? max_alloc: total_alloc;
__thread int my_tid;
-void
-do_work(BitAllocator *alloc)
-{
- int num_iters = 3;
- int64_t alloced = 0;
- int64_t start_block = -1;
- int64_t num_blocks = alloc->size() / NUM_THREADS;
- int total_alloced = 0;
- int64_t *allocated_blocks = (int64_t *) new int64_t [MAX_BLOCKS];
-
- while (num_iters--) {
- printf("Allocating in tid %d.\n", my_tid);
- alloc_assert(alloc->reserve_blocks(num_blocks));
- for (int i = 0; i < num_blocks; i++) {
- alloced = alloc->alloc_blocks_res(1, 0, &start_block);
- bmap_test_assert(alloced == 1);
- total_alloced++;
- allocated_blocks[i] = start_block;
- }
-
- printf("Freeing in tid %d %d blocks.\n", my_tid, total_alloced);
- for (int i = 0; i < num_blocks; i++) {
- alloc->free_blocks(allocated_blocks[i], 1);
- }
-
- total_alloced = 0;
- printf("Done tid %d iter %d.\n", my_tid, num_iters);
- }
-}
-
void
do_work_dis(BitAllocator *alloc)
{
my_tid = __sync_fetch_and_add(&tid, 1);
BitAllocator *alloc = (BitAllocator *) args;
printf("Starting thread %d", my_tid);
- if (cont) {
- do_work(alloc);
- } else {
- do_work_dis(alloc);
- }
+ do_work_dis(alloc);
return NULL;
}
pthread_join(pthreads[j], NULL);
}
}
-
}