Skip to content

Commit 50836e7

Browse files
author
David Saada
committed
Improve the efficiency of BufferedBlockDevice
1 parent 1ac4d9b commit 50836e7

File tree

3 files changed

+252
-149
lines changed

3 files changed

+252
-149
lines changed

features/storage/TESTS/blockdevice/buffered_block_device/main.cpp

Lines changed: 138 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -24,105 +24,155 @@
2424
using namespace utest::v1;
2525

2626
static const bd_size_t heap_erase_size = 512;
27-
static const bd_size_t heap_prog_size = heap_erase_size;
28-
static const bd_size_t heap_read_size = 256;
2927
static const bd_size_t num_blocks = 4;
3028

29+
typedef struct {
30+
bd_size_t read_size;
31+
bd_size_t prog_size;
32+
} sizes_t;
33+
34+
static const int num_tests = 4;
35+
36+
sizes_t sizes[num_tests] = {
37+
{1, 1},
38+
{1, 128},
39+
{4, 256},
40+
{256, 512}
41+
};
42+
3143
void functionality_test()
3244
{
33-
uint8_t *dummy = new (std::nothrow) uint8_t[num_blocks * heap_erase_size + heap_prog_size];
34-
TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test");
35-
delete[] dummy;
45+
for (int i = 0; i < num_tests; i++) {
46+
bd_size_t heap_read_size = sizes[i].read_size;
47+
bd_size_t heap_prog_size = sizes[i].prog_size;
3648

37-
HeapBlockDevice heap_bd(num_blocks * heap_erase_size, heap_read_size, heap_prog_size, heap_erase_size);
38-
BufferedBlockDevice bd(&heap_bd);
49+
printf("Testing read size of %lld, prog size of %lld\n", heap_read_size, heap_prog_size);
3950

40-
int err = bd.init();
41-
TEST_ASSERT_EQUAL(0, err);
51+
uint8_t *read_buf, *write_buf;
52+
read_buf = new (std::nothrow) uint8_t[heap_erase_size];
53+
TEST_SKIP_UNLESS_MESSAGE(read_buf, "Not enough memory for test");
54+
write_buf = new (std::nothrow) uint8_t[heap_erase_size];
55+
TEST_SKIP_UNLESS_MESSAGE(write_buf, "Not enough memory for test");
4256

43-
uint8_t *read_buf, *write_buf;
44-
read_buf = new (std::nothrow) uint8_t[heap_prog_size];
45-
TEST_SKIP_UNLESS_MESSAGE(read_buf, "Not enough memory for test");
46-
write_buf = new (std::nothrow) uint8_t[heap_prog_size];
47-
TEST_SKIP_UNLESS_MESSAGE(write_buf, "Not enough memory for test");
57+
uint8_t *dummy = new (std::nothrow) uint8_t[num_blocks * heap_erase_size + heap_prog_size + heap_read_size];
58+
TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test");
59+
delete[] dummy;
4860

49-
TEST_ASSERT_EQUAL(1, bd.get_read_size());
50-
TEST_ASSERT_EQUAL(1, bd.get_program_size());
51-
TEST_ASSERT_EQUAL(heap_erase_size, bd.get_erase_size());
61+
HeapBlockDevice *heap_bd = new HeapBlockDevice(num_blocks * heap_erase_size, heap_read_size, heap_prog_size, heap_erase_size);
62+
BufferedBlockDevice *bd = new BufferedBlockDevice(heap_bd);
5263

53-
for (bd_size_t i = 0; i < num_blocks; i++) {
54-
memset(write_buf, i, heap_prog_size);
55-
err = heap_bd.program(write_buf, i * heap_prog_size, heap_prog_size);
64+
int err = bd->init();
5665
TEST_ASSERT_EQUAL(0, err);
57-
}
5866

59-
err = bd.read(read_buf, heap_prog_size + heap_prog_size / 2, 1);
60-
TEST_ASSERT_EQUAL(0, err);
61-
TEST_ASSERT_EQUAL(1, read_buf[0]);
62-
63-
err = bd.read(read_buf, 2 * heap_prog_size + heap_prog_size / 2, 4);
64-
TEST_ASSERT_EQUAL(0, err);
65-
memset(write_buf, 2, 4);
66-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, 4);
67-
68-
memset(write_buf, 1, heap_prog_size);
69-
memset(write_buf + 64, 0x5A, 8);
70-
memset(write_buf + 72, 0xA5, 8);
71-
err = bd.program(write_buf + 64, heap_prog_size + 64, 8);
72-
TEST_ASSERT_EQUAL(0, err);
73-
err = bd.program(write_buf + 72, heap_prog_size + 72, 8);
74-
TEST_ASSERT_EQUAL(0, err);
75-
err = bd.read(read_buf, heap_prog_size, heap_prog_size);
76-
TEST_ASSERT_EQUAL(0, err);
77-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
78-
memset(write_buf, 1, heap_prog_size);
79-
// Underlying BD should not be updated before sync
80-
err = heap_bd.read(read_buf, heap_prog_size, heap_prog_size);
81-
TEST_ASSERT_EQUAL(0, err);
82-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
83-
err = bd.sync();
84-
TEST_ASSERT_EQUAL(0, err);
85-
memset(write_buf + 64, 0x5A, 8);
86-
memset(write_buf + 72, 0xA5, 8);
87-
// Should be updated now
88-
err = bd.read(read_buf, heap_prog_size, heap_prog_size);
89-
TEST_ASSERT_EQUAL(0, err);
90-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
91-
err = heap_bd.read(read_buf, heap_prog_size, heap_prog_size);
92-
TEST_ASSERT_EQUAL(0, err);
93-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
94-
95-
memset(write_buf, 0xAA, 16);
96-
memset(write_buf + 16, 0xBB, 16);
97-
err = bd.program(write_buf, 3 * heap_prog_size - 16, 32);
98-
TEST_ASSERT_EQUAL(0, err);
99-
// First block should sync, but second still shouldn't
100-
memset(write_buf, 2, heap_prog_size - 16);
101-
memset(write_buf + heap_prog_size - 16, 0xAA, 16);
102-
err = heap_bd.read(read_buf, 2 * heap_prog_size, heap_prog_size);
103-
TEST_ASSERT_EQUAL(0, err);
104-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
105-
memset(write_buf, 3, heap_prog_size);
106-
err = heap_bd.read(read_buf, 3 * heap_prog_size, heap_prog_size);
107-
TEST_ASSERT_EQUAL(0, err);
108-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
109-
memset(write_buf, 0xBB, 16);
110-
err = bd.read(read_buf, 3 * heap_prog_size, heap_prog_size);
111-
TEST_ASSERT_EQUAL(0, err);
112-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
113-
// Moving to another block should automatically sync
114-
err = bd.read(read_buf, 15, 1);
115-
TEST_ASSERT_EQUAL(0, err);
116-
TEST_ASSERT_EQUAL(0, read_buf[0]);
117-
err = heap_bd.read(read_buf, 3 * heap_prog_size, heap_prog_size);
118-
TEST_ASSERT_EQUAL(0, err);
119-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
120-
err = bd.read(read_buf, 3 * heap_prog_size, heap_prog_size);
121-
TEST_ASSERT_EQUAL(0, err);
122-
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_prog_size);
123-
124-
delete[] read_buf;
125-
delete[] write_buf;
67+
TEST_ASSERT_EQUAL(1, bd->get_read_size());
68+
TEST_ASSERT_EQUAL(1, bd->get_program_size());
69+
TEST_ASSERT_EQUAL(heap_erase_size, bd->get_erase_size());
70+
71+
for (bd_size_t i = 0; i < num_blocks; i++) {
72+
memset(write_buf, i, heap_erase_size);
73+
err = heap_bd->program(write_buf, i * heap_erase_size, heap_erase_size);
74+
// Heap BD allocates memory on each program, so failure here indicates
75+
// lack of memory - just skip test.
76+
TEST_SKIP_UNLESS_MESSAGE(!err, "Not enough memory for test");
77+
}
78+
79+
err = bd->read(read_buf, heap_erase_size + heap_erase_size / 2, 1);
80+
TEST_ASSERT_EQUAL(0, err);
81+
TEST_ASSERT_EQUAL(1, read_buf[0]);
82+
83+
err = bd->read(read_buf, 2 * heap_erase_size + heap_erase_size / 2, 4);
84+
TEST_ASSERT_EQUAL(0, err);
85+
memset(write_buf, 2, 4);
86+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, 4);
87+
88+
memset(write_buf, 1, heap_erase_size);
89+
memset(write_buf + 64, 0x5A, 8);
90+
memset(write_buf + 72, 0xA5, 8);
91+
err = bd->program(write_buf + 64, heap_erase_size + 64, 8);
92+
TEST_ASSERT_EQUAL(0, err);
93+
err = bd->program(write_buf + 72, heap_erase_size + 72, 8);
94+
TEST_ASSERT_EQUAL(0, err);
95+
err = bd->read(read_buf, heap_erase_size, heap_erase_size);
96+
TEST_ASSERT_EQUAL(0, err);
97+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
98+
memset(write_buf, 1, heap_erase_size);
99+
// Underlying BD should not be updated before sync
100+
err = heap_bd->read(read_buf, heap_erase_size, heap_erase_size);
101+
TEST_ASSERT_EQUAL(0, err);
102+
if (heap_prog_size > 1) {
103+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
104+
}
105+
err = bd->sync();
106+
TEST_ASSERT_EQUAL(0, err);
107+
memset(write_buf + 64, 0x5A, 8);
108+
memset(write_buf + 72, 0xA5, 8);
109+
// Should be updated now
110+
err = bd->read(read_buf, heap_erase_size, heap_erase_size);
111+
TEST_ASSERT_EQUAL(0, err);
112+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
113+
err = heap_bd->read(read_buf, heap_erase_size, heap_erase_size);
114+
TEST_ASSERT_EQUAL(0, err);
115+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
116+
117+
memset(write_buf, 0xAA, 16);
118+
memset(write_buf + 16, 0xBB, 16);
119+
err = bd->program(write_buf, 3 * heap_erase_size - 16, 32);
120+
TEST_ASSERT_EQUAL(0, err);
121+
// First block should sync, but second still shouldn't
122+
memset(write_buf, 2, heap_erase_size - 16);
123+
memset(write_buf + heap_erase_size - 16, 0xAA, 16);
124+
err = heap_bd->read(read_buf, 2 * heap_erase_size, heap_erase_size);
125+
TEST_ASSERT_EQUAL(0, err);
126+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
127+
memset(write_buf, 3, heap_erase_size);
128+
err = heap_bd->read(read_buf, 3 * heap_erase_size, heap_erase_size);
129+
TEST_ASSERT_EQUAL(0, err);
130+
if (heap_prog_size > 1) {
131+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
132+
}
133+
memset(write_buf, 0xBB, 16);
134+
err = bd->read(read_buf, 3 * heap_erase_size, heap_erase_size);
135+
TEST_ASSERT_EQUAL(0, err);
136+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
137+
// Writing to another block should automatically sync
138+
err = bd->program(write_buf, 15, 1);
139+
TEST_ASSERT_EQUAL(0, err);
140+
err = heap_bd->read(read_buf, 3 * heap_erase_size, heap_erase_size);
141+
TEST_ASSERT_EQUAL(0, err);
142+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
143+
err = bd->read(read_buf, 3 * heap_erase_size, heap_erase_size);
144+
TEST_ASSERT_EQUAL(0, err);
145+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, heap_erase_size);
146+
147+
// Unaligned reads and writes
148+
memset(write_buf, 2, 41);
149+
memset(write_buf + 41, 0x39, 21);
150+
err = bd->program(write_buf + 41, 2 * heap_erase_size + 41, 21);
151+
TEST_ASSERT_EQUAL(0, err);
152+
err = heap_bd->read(read_buf, 2 * heap_erase_size, heap_erase_size);
153+
TEST_ASSERT_EQUAL(0, err);
154+
if (heap_prog_size > 1) {
155+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, 41);
156+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf + 41, 21);
157+
}
158+
err = bd->read(read_buf, 2 * heap_erase_size + 4, 41 + 21 - 4);
159+
TEST_ASSERT_EQUAL(0, err);
160+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf + 4, read_buf, 41 + 21 - 4);
161+
bd->sync();
162+
err = heap_bd->read(read_buf, 2 * heap_erase_size, heap_erase_size);
163+
TEST_ASSERT_EQUAL(0, err);
164+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf, read_buf, 41 + 21);
165+
err = bd->read(read_buf, 2 * heap_erase_size + 10, 41 + 21 - 10);
166+
TEST_ASSERT_EQUAL(0, err);
167+
TEST_ASSERT_EQUAL_UINT8_ARRAY(write_buf + 10, read_buf, 41 + 21 - 10);
168+
169+
bd->deinit();
170+
171+
delete[] read_buf;
172+
delete[] write_buf;
173+
delete bd;
174+
delete heap_bd;
175+
}
126176
}
127177

128178
// Test setup

0 commit comments

Comments
 (0)