def test_arena_layout(self): arena = lib.qcgc_arena_create() lib.arena_cells(arena)[0][0] = 15 self.assertEqual(lib.arena_block_bitmap(arena)[0], 15) lib.arena_cells(arena)[lib.qcgc_arena_bitmap_size // 16][lib.qcgc_arena_bitmap_size % 16] = 3 self.assertEqual(lib.arena_mark_bitmap(arena)[0], 3) lib.arena_cells(arena)[lib.qcgc_arena_cells_count - 1][15] = 12
def test_arena_create(self): p = lib.qcgc_arena_create() self.assertEqual(p, lib.qcgc_arena_addr(lib.arena_cells(p))) self.assertEqual(p, lib.qcgc_arena_addr(ffi.addressof(lib.arena_cells(p)[lib.qcgc_arena_cells_count - 1]))) self.assertEqual(0, lib.qcgc_arena_cell_index(lib.arena_cells(p))) self.assertEqual(int(ffi.cast("uint64_t", p)), int(ffi.cast("uint64_t", p)) << lib.QCGC_ARENA_SIZE_EXP >> lib.QCGC_ARENA_SIZE_EXP) self.assertEqual(lib.BLOCK_FREE, self.get_blocktype(ffi.addressof(lib.arena_cells(p)[lib.qcgc_arena_first_cell_index])))
def test_arena_sweep_no_double_add(self): arena = lib.qcgc_arena_create() i = lib.qcgc_arena_first_cell_index layout = [ (0, lib.BLOCK_BLACK) , (1, lib.BLOCK_WHITE) , (2, lib.BLOCK_BLACK) ] for b in layout: p = ffi.addressof(lib.arena_cells(arena)[i + b[0]]) self.set_blocktype(p, b[1]) lib.qcgc_arena_sweep(arena) have_elems = [0] for i in range(lib.qcgc_small_free_lists): if (i in have_elems): self.assertEqual(1, lib.small_free_list(i).count) else: self.assertEqual(0, lib.small_free_list(i).count) for i in range(lib.qcgc_large_free_lists): self.assertEqual(0, lib.large_free_list(i).count) # Now mark the black blocks black again layout = [ (0, lib.BLOCK_BLACK) , (2, lib.BLOCK_BLACK) ] i = lib.qcgc_arena_first_cell_index for b in layout: p = ffi.addressof(lib.arena_cells(arena)[i + b[0]]) self.set_blocktype(p, b[1]) lib.qcgc_arena_sweep(arena) have_elems = [0] for i in range(lib.qcgc_small_free_lists): if (i in have_elems): self.assertEqual(1, lib.small_free_list(i).count) else: self.assertEqual(0, lib.small_free_list(i).count) for i in range(lib.qcgc_large_free_lists): self.assertEqual(0, lib.large_free_list(i).count)
def test_arena_sweep_mixed_2(self): arena = lib.qcgc_arena_create() i = lib.qcgc_arena_first_cell_index layout = [ (0, lib.BLOCK_WHITE) , (5, lib.BLOCK_FREE) , (20, lib.BLOCK_BLACK) , (32, lib.BLOCK_BLACK) , (33, lib.BLOCK_FREE) , (42, lib.BLOCK_BLACK) , (43, lib.BLOCK_WHITE) , (44, lib.BLOCK_WHITE) , (49, lib.BLOCK_BLACK) ] for b in layout: p = ffi.addressof(lib.arena_cells(arena)[i + b[0]]) self.set_blocktype(p, b[1]) lib.qcgc_arena_sweep(arena) have_elems = [5,8,19] for i in range(lib.qcgc_small_free_lists): if (i in have_elems): self.assertEqual(1, lib.small_free_list(i).count) else: self.assertEqual(0, lib.small_free_list(i).count) for i in range(lib.qcgc_large_free_lists): self.assertEqual(0, lib.large_free_list(i).count)
def test_arena_sweep_mixed(self): arena = lib.qcgc_arena_create() i = lib.qcgc_arena_first_cell_index layout = [ (0, lib.BLOCK_WHITE) , (20, lib.BLOCK_BLACK) , (32, lib.BLOCK_BLACK) , (42, lib.BLOCK_BLACK) , (43, lib.BLOCK_WHITE) , (44, lib.BLOCK_WHITE) ] for b in layout: p = ffi.addressof(lib.arena_cells(arena)[i + b[0]]) self.set_blocktype(p, b[1]) self.assertEqual(lib.qcgc_arena_black_blocks(arena), 3) self.assertEqual(lib.qcgc_arena_white_blocks(arena), 3) self.assertFalse(lib.qcgc_arena_sweep(arena)) self.assertEqual(lib.qcgc_arena_black_blocks(arena), 0) self.assertEqual(lib.qcgc_arena_white_blocks(arena), 3) self.assertEqual(lib.qcgc_arena_free_blocks(arena), 2) self.assertTrue(lib.qcgc_arena_is_coalesced(arena))
def test_bump_allocator_internals(self): arena = lib.qcgc_arena_create() first_cell = lib.arena_cells(arena)[lib.qcgc_arena_first_cell_index] size = lib.qcgc_arena_cells_count - lib.qcgc_arena_first_cell_index lib.bump_allocator_assign(ffi.addressof(first_cell), size) self.assertEqual(ffi.addressof(first_cell), lib._qcgc_bump_allocator.ptr) self.assertEqual(size, self.bump_remaining_cells()) p = self.bump_allocate(16) self.assertEqual(ffi.addressof(first_cell), p) self.assertEqual(size - 1, self.bump_remaining_cells()) q = self.bump_allocate((2**lib.QCGC_LARGE_ALLOC_THRESHOLD_EXP)) self.assertEqual(ffi.addressof(lib.arena_cells(arena)[lib.qcgc_arena_first_cell_index + 1]), q) self.assertEqual(size - 1 - 2**(lib.QCGC_LARGE_ALLOC_THRESHOLD_EXP - 4), self.bump_remaining_cells())
def test_initialization(self): # self.assertEqual( <config_value> ,lib.arenas().size) self.assertEqual(1, lib.arenas().count) self.assertNotEqual(ffi.NULL, lib.arenas().items) # self.assertEqual( <config_value> ,lib.free_arenas().size) self.assertEqual(0, lib.free_arenas().count) self.assertNotEqual(ffi.NULL, lib.free_arenas().items) self.assertEqual( ffi.addressof( lib.arena_cells( lib.arenas().items[0])[lib.qcgc_arena_first_cell_index]), lib._qcgc_bump_allocator.ptr) self.assertEqual( lib.qcgc_arena_cells_count - lib.qcgc_arena_first_cell_index, self.bump_remaining_cells()) for i in range(lib.qcgc_small_free_lists): self.assertEqual(lib.QCGC_SMALL_FREE_LIST_INIT_SIZE, lib.small_free_list(i).size) self.assertEqual(0, lib.small_free_list(i).count) self.assertNotEqual(ffi.NULL, lib.small_free_list(i).items) for i in range(lib.qcgc_large_free_lists): self.assertEqual(lib.QCGC_LARGE_FREE_LIST_INIT_SIZE, lib.large_free_list(i).size) self.assertEqual(0, lib.large_free_list(i).count) self.assertNotEqual(ffi.NULL, lib.large_free_list(i).items)
def test_reuse_old_free_space(self): arena = lib.qcgc_arena_create() first_cell = lib.arena_cells(arena)[lib.qcgc_arena_first_cell_index] size = lib.qcgc_arena_cells_count - lib.qcgc_arena_first_cell_index lib.qcgc_fit_allocator_add(ffi.addressof(first_cell), size) lib.bump_ptr_reset() p = self.bump_allocate(16) self.assertEqual(ffi.addressof(first_cell), p)
def test_block_validity_check(self): arena = lib.qcgc_arena_create() first = ffi.addressof(lib.arena_cells(arena)[lib.qcgc_arena_first_cell_index]) self.assertTrue(lib.valid_block(first, lib.qcgc_arena_cells_count - lib.qcgc_arena_first_cell_index)) lib.qcgc_arena_mark_allocated(first, 10); self.assertFalse(lib.valid_block(first, 10)); self.set_blocktype(first, lib.BLOCK_FREE); self.assertTrue(lib.valid_block(first, 10)); self.assertFalse(lib.valid_block(first, 8)); self.assertFalse(lib.valid_block(first + 1, 9)); self.assertFalse(lib.valid_block(first + 1, 8));
def test_bump_allocator_internals(self): arena = lib.qcgc_arena_create() first_cell = lib.arena_cells(arena)[lib.qcgc_arena_first_cell_index] size = lib.qcgc_arena_cells_count - lib.qcgc_arena_first_cell_index lib.bump_allocator_assign(ffi.addressof(first_cell), size) self.assertEqual(ffi.addressof(first_cell), lib._qcgc_bump_allocator.ptr) self.assertEqual(size, self.bump_remaining_cells()) p = self.bump_allocate(16) self.assertEqual(ffi.addressof(first_cell), p) self.assertEqual(size - 1, self.bump_remaining_cells()) q = self.bump_allocate((2**lib.QCGC_LARGE_ALLOC_THRESHOLD_EXP)) self.assertEqual( ffi.addressof( lib.arena_cells(arena)[lib.qcgc_arena_first_cell_index + 1]), q) self.assertEqual( size - 1 - 2**(lib.QCGC_LARGE_ALLOC_THRESHOLD_EXP - 4), self.bump_remaining_cells())
def test_is_empty(self): arena = lib.qcgc_arena_create() i = lib.qcgc_arena_first_cell_index self.assertTrue(lib.qcgc_arena_is_empty(arena)) p = ffi.addressof(lib.arena_cells(arena)[i]) lib.qcgc_arena_mark_allocated(p, 1) self.assertFalse(lib.qcgc_arena_is_empty(arena)) self.set_blocktype(p, lib.BLOCK_BLACK) self.assertFalse(lib.qcgc_arena_is_empty(arena))
def test_block_validity_check(self): arena = lib.qcgc_arena_create() first = ffi.addressof( lib.arena_cells(arena)[lib.qcgc_arena_first_cell_index]) self.assertTrue( lib.valid_block( first, lib.qcgc_arena_cells_count - lib.qcgc_arena_first_cell_index)) lib.qcgc_arena_mark_allocated(first, 10) self.assertFalse(lib.valid_block(first, 10)) self.set_blocktype(first, lib.BLOCK_FREE) self.assertTrue(lib.valid_block(first, 10)) self.assertFalse(lib.valid_block(first, 8)) self.assertFalse(lib.valid_block(first + 1, 9)) self.assertFalse(lib.valid_block(first + 1, 8))
def test_initialization(self): # self.assertEqual( <config_value> ,lib.arenas().size) self.assertEqual(1, lib.arenas().count) self.assertNotEqual(ffi.NULL, lib.arenas().items) # self.assertEqual( <config_value> ,lib.free_arenas().size) self.assertEqual(0, lib.free_arenas().count) self.assertNotEqual(ffi.NULL, lib.free_arenas().items) self.assertEqual(ffi.addressof(lib.arena_cells(lib.arenas().items[0])[lib.qcgc_arena_first_cell_index]), lib._qcgc_bump_allocator.ptr) self.assertEqual(lib.qcgc_arena_cells_count - lib.qcgc_arena_first_cell_index, self.bump_remaining_cells()) for i in range(lib.qcgc_small_free_lists): self.assertEqual(lib.QCGC_SMALL_FREE_LIST_INIT_SIZE, lib.small_free_list(i).size) self.assertEqual(0, lib.small_free_list(i).count) self.assertNotEqual(ffi.NULL, lib.small_free_list(i).items) for i in range(lib.qcgc_large_free_lists): self.assertEqual(lib.QCGC_LARGE_FREE_LIST_INIT_SIZE, lib.large_free_list(i).size) self.assertEqual(0, lib.large_free_list(i).count) self.assertNotEqual(ffi.NULL, lib.large_free_list(i).items)
def test_block_counting(self): arena = lib.qcgc_arena_create() i = lib.qcgc_arena_first_cell_index layout = [ (0, lib.BLOCK_WHITE) , (2, lib.BLOCK_FREE) , (20, lib.BLOCK_BLACK) , (32, lib.BLOCK_BLACK) , (42, lib.BLOCK_BLACK) , (43, lib.BLOCK_WHITE) , (44, lib.BLOCK_WHITE) , (45, lib.BLOCK_FREE) ] for b in layout: p = ffi.addressof(lib.arena_cells(arena)[i + b[0]]) self.set_blocktype(p, b[1]) self.assertEqual(lib.qcgc_arena_black_blocks(arena), 3) self.assertEqual(lib.qcgc_arena_white_blocks(arena), 3) self.assertEqual(lib.qcgc_arena_free_blocks(arena), 2)
def test_arena_sweep_white(self): arena = lib.qcgc_arena_create() i = lib.qcgc_arena_first_cell_index for j in range(10): lib.qcgc_arena_mark_allocated( ffi.addressof(lib.arena_cells(arena)[i + j]), 1) self.assertEqual(lib.qcgc_arena_white_blocks(arena), 10) self.assertTrue(lib.qcgc_arena_sweep(arena)) self.assertEqual(lib.qcgc_arena_black_blocks(arena), 0) self.assertEqual(lib.qcgc_arena_white_blocks(arena), 0) self.assertEqual(lib.qcgc_arena_free_blocks(arena), 1) self.assertTrue(lib.qcgc_arena_is_empty(arena)) self.assertTrue(lib.qcgc_arena_is_coalesced(arena)) for i in range(lib.qcgc_small_free_lists): self.assertEqual(0, lib.small_free_list(i).count) for i in range(lib.qcgc_large_free_lists): self.assertEqual(0, lib.large_free_list(i).count)
def test_arena_sweep_black(self): arena = lib.qcgc_arena_create() i = lib.qcgc_arena_first_cell_index for j in range(10): p = ffi.addressof(lib.arena_cells(arena)[i + j]) lib.qcgc_arena_mark_allocated(p, 1) self.set_blocktype(p, lib.BLOCK_BLACK) self.assertEqual(lib.qcgc_arena_black_blocks(arena), 10) self.assertFalse(lib.qcgc_arena_sweep(arena)) self.assertEqual(lib.qcgc_arena_black_blocks(arena), 0) self.assertEqual(lib.qcgc_arena_white_blocks(arena), 10) self.assertEqual(lib.qcgc_arena_free_blocks(arena), 1) self.assertTrue(lib.qcgc_arena_is_coalesced(arena)) for i in range(lib.qcgc_small_free_lists): self.assertEqual(0, lib.small_free_list(i).count) for i in range(lib.qcgc_large_free_lists - 1): self.assertEqual(0, lib.large_free_list(i).count) self.assertEqual(1, lib.large_free_list(lib.qcgc_large_free_lists - 1).count)
def test_custom_layout_full_sweep(self): arena = lib.qcgc_arena_create() i = lib.qcgc_arena_first_cell_index layout = [ (0, lib.BLOCK_WHITE) , (19, lib.BLOCK_FREE) , (20, lib.BLOCK_BLACK) , (21, lib.BLOCK_FREE) , (22, lib.BLOCK_WHITE) , (32, lib.BLOCK_BLACK) , (33, lib.BLOCK_FREE) , (42, lib.BLOCK_BLACK) , (43, lib.BLOCK_WHITE) ] for b in layout: p = ffi.addressof(lib.arena_cells(arena)[i + b[0]]) self.set_blocktype(p, b[1]) lib.qcgc_state.free_cells = 0 lib.qcgc_state.largest_free_block = 0 lib.qcgc_arena_sweep(arena) self.assertEqual(lib.qcgc_state.free_cells, self.arena_blocks - 3) self.assertEqual(lib.qcgc_state.largest_free_block, self.arena_blocks - 43)
def test_blocktype_manipulation(self): p = lib.qcgc_arena_create() block = ffi.addressof(lib.arena_cells(p)[lib.qcgc_arena_first_cell_index]) for t in [lib.BLOCK_EXTENT, lib.BLOCK_FREE, lib.BLOCK_WHITE, lib.BLOCK_BLACK]: self.set_blocktype(block, t) self.assertEqual(t, self.get_blocktype(block))
def test_index_calculation(self): p = lib.qcgc_arena_create() self.assertEqual(lib.qcgc_arena_first_cell_index, lib.qcgc_arena_cell_index(ffi.addressof(lib.arena_cells(p)[lib.qcgc_arena_first_cell_index])))